簡體   English   中英

從 Kafka 讀取並寫入鑲木地板中的 hdfs

[英]Read from Kafka and write to hdfs in parquet

我是 BigData 生態系統的新手,並且剛開始接觸。

我已經閱讀了幾篇關於使用 Spark 流讀取 kafka 主題的文章,但想知道是否可以使用 Spark 作業而不是流從 kafka 讀取? 如果是的話,你們能幫我指出一些可以讓我入門的文章或代碼片段嗎?

我的問題的第二部分是以鑲木地板格式寫入 hdfs。 一旦我從 Kafka 中讀到,我想我會有一個 rdd。 將此 rdd 轉換為數據幀,然后將數據幀寫入鑲木地板文件。 這是正確的方法嗎。

任何幫助表示贊賞。

謝謝

對於從 Kafka 讀取數據並將其寫入 HDFS,在 Parquet 格式中,使用 Spark Ba​​tch 作業而不是流式傳輸,您可以使用Spark Structured Streaming

Structured Streaming 是一種基於 Spark SQL 引擎構建的可擴展且容錯的流處理引擎。 您可以像在靜態數據上表達批處理計算一樣表達流式計算。 Spark SQL 引擎將負責以增量方式連續運行它,並隨着流數據的不斷到達更新最終結果。 您可以使用 Scala、Java、Python 或 R 中的 Dataset/DataFrame API 來表達流聚合、事件時間窗口、流到批處理連接等。計算在同一個優化的 Spark SQL 引擎上執行。 最后,系統通過檢查點和預寫日志確保端到端的一次性容錯保證。 簡而言之,Structured Streaming 提供了快速、可擴展、容錯、端到端的一次性流處理,用戶無需對流進行推理。

它帶有 Kafka 作為內置 Source,即我們可以從 Kafka 輪詢數據。 它與 Kafka 代理版本 0.10.0 或更高版本兼容。

為了以批處理模式從 Kafka 中提取數據,您可以為定義的偏移范圍創建一個 Dataset/DataFrame。

// Subscribe to 1 topic defaults to the earliest and latest offsets
val df = spark
  .read
  .format("kafka")
  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
  .option("subscribe", "topic1")
  .load()
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
  .as[(String, String)]

// Subscribe to multiple topics, specifying explicit Kafka offsets
val df = spark
  .read
  .format("kafka")
  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
  .option("subscribe", "topic1,topic2")
  .option("startingOffsets", """{"topic1":{"0":23,"1":-2},"topic2":{"0":-2}}""")
  .option("endingOffsets", """{"topic1":{"0":50,"1":-1},"topic2":{"0":-1}}""")
  .load()
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
  .as[(String, String)]

// Subscribe to a pattern, at the earliest and latest offsets
val df = spark
  .read
  .format("kafka")
  .option("kafka.bootstrap.servers", "host1:port1,host2:port2")
  .option("subscribePattern", "topic.*")
  .option("startingOffsets", "earliest")
  .option("endingOffsets", "latest")
  .load()
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
  .as[(String, String)]

源中的每一行都具有以下架構:

| Column           | Type          |
|:-----------------|--------------:|
| key              |        binary |
| value            |        binary |
| topic            |        string |
| partition        |           int |
| offset           |          long |
| timestamp        |          long |
| timestampType    |           int |

現在,要將數據以 parquet 格式寫入 HDFS,可以編寫以下代碼:

df.write.parquet("hdfs://data.parquet")

有關 Spark Structured Streaming + Kafka 的更多信息,請參閱以下指南 - Kafka 集成指南

我希望它有幫助!

你已經有幾個關於這個話題的好答案。

只是想強調一下 - 小心直接流入鑲木地板。 當 parquet 行組大小足夠大時,Parquet 的性能會大放異彩(為簡單起見,您可以說文件大小應該在 64-256Mb 之間),以利用字典壓縮、布隆過濾器等(一個 Parquet 文件可以有多個行塊在其中,通常每個文件中有多個行塊;雖然行塊不能跨越多個鑲木地板文件)

如果您直接流式傳輸到鑲木地板,那么您最終很可能會得到一堆小型鑲木地板文件(取決於 Spark Streaming 的小批量大小和數據量)。 查詢此類文件可能非常緩慢。 例如,Parquet 可能需要讀取所有文件的標頭以協調架構,這是一個很大的開銷。 如果是這種情況,您將需要有一個單獨的進程,例如,作為一種解決方法,讀取舊文件並將它們“合並”寫入(這不是簡單的文件級合並,一個進程會實際上需要讀入所有鑲木地板數據並溢出更大的鑲木地板文件)。

此解決方法可能會破壞數據“流式傳輸”的原始目的。 您也可以在這里查看其他技術——比如 Apache Kudu、Apache Kafka、Apache Druid、Kinesis 等,它們可以在這里更好地工作。

更新:自從我發布了這個答案,現在這里有一個強大的新玩家 - Delta Lake https://delta.io/如果你習慣了鑲木地板,你會發現 Delta 非常有吸引力(實際上,Delta 是建立在鑲木地板 + 元數據之上)。 三角洲湖提供:

Spark 上的 ACID 事務:

  • 可序列化的隔離級別確保讀者永遠不會看到不一致的數據。
  • 可擴展的元數據處理:利用 Spark 的分布式處理能力輕松處理 PB 級表的所有元數據,其中包含數十億個文件。
  • 流式和批處理統一:Delta Lake 中的表是批處理表,也是流式源和接收器。 流數據攝取、批量歷史回填、交互式查詢都是開箱即用的。
  • 架構實施:自動處理架構變化以防止在攝取期間插入不良記錄。
  • 時間旅行:數據版本控制支持回滾、完整的歷史審計跟蹤和可重復的機器學習實驗。
  • Upserts 和 deletes:支持合並、更新和刪除操作,以支持復雜的用例,如更改數據捕獲、緩慢變化維度 (SCD) 操作、流式更新插入等。

使用 Kafka 流。 SparkStreaming 用詞不當(它是引擎蓋下的小批量,至少高達 2.2)。

https://eng.verizondigitalmedia.com/2017/04/28/Kafka-to-Hdfs-ParquetSerializer/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM