阅读Kafka并写入镶木地板中的hdfs

时间:2017-08-22 22:01:30

标签: hadoop apache-spark apache-kafka hdfs parquet

我是BigData生态系统的新手,有点开始。

我已经阅读了几篇关于使用spark streaming阅读kafka主题的文章,但是想知道是否可以使用spark作业而不是流式传输来读取kafka? 如果是的话,你们可以帮助我指出一些可以让我开始的文章或代码片段。

我的第二部分问题是以镶木地板格式写入hdfs。 有一次我从卡夫卡读书,我想我会有一个rdd。 将此rdd转换为数据帧,然后将数据帧写为镶木地板文件。 这是正确的做法。

任何帮助表示赞赏。

由于

3 个答案:

答案 0 :(得分:4)

您已经对该主题有几个很好的答案。

只想强调一下-小心地直接流入镶木地板中。 当实木复合地板行组的大小足够大(例如,为简单起见,您可以说文件大小应在64-256Mb的数量级)以利用字典压缩,bloom过滤器等(一个实木复合地板文件可以具有多个)时,实木复合地板的性能会得到提高行块,通常每个文件中都有多个行块;尽管行块不能跨越多个镶木文件)

如果直接流式传输到实木复合地板表,则最终可能会遇到一堆微小的实木复合地板文件(取决于Spark Streaming的最小批量大小和数据量)。查询此类文件可能非常慢。例如,Parquet可能需要读取所有文件的标头才能协调架构,这是很大的开销。如果是这种情况,您将需要有一个单独的进程,例如,作为一种解决方法,它可以读取较旧的文件,然后将它们“合并”(这不是简单的文件级合并,一个过程会实际上需要读取所有镶木地板数据,并散出更大的镶木地板文件文件)。

此替代方法可能会破坏数据“流式传输”的原始目的。您也可以在这里查看其他技术,例如Apache Kudu,Apache Kafka,Apache Druid,Kinesis等,它们可以在此处更好地工作。

答案 1 :(得分:2)

为了从Kafka读取数据并以Parquet格式将其写入HDFS,使用Spark Ba​​tch作业而不是流式传输,您可以使用Spark Structured Streaming

Structured Streaming是一个基于Spark SQL引擎的可扩展且容错的流处理引擎。您可以像表达静态数据的批处理计算一样表达流式计算。 Spark SQL引擎将负责逐步和连续地运行它,并在流数据继续到达时更新最终结果。您可以使用Scala,Java,Python或R中的数据集/数据框架API来表示流聚合,事件时间窗口,流到批处理连接等。计算在同一优化的Spark SQL引擎上执行。最后,系统通过检查点和预读日志确保端到端的一次性容错保证。简而言之,Structured Streaming提供快速,可扩展,容错,端到端的精确一次流处理,而无需用户推理流式传输。

它附带Kafka作为内置源,即我们可以从Kafka轮询数据。它与Kafka经纪人版本0.10.0或更高版本兼容。

要以批处理模式从Kafka中提取数据,您可以为定义的偏移范围创建数据集/数据框。

// 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 |

现在,要以镶木地板格式将数据写入HDFS,可以编写以下代码:

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

有关Spark Structured Streaming + Kafka的更多信息,请参阅以下指南 - Kafka Integration Guide

我希望它有所帮助!

答案 2 :(得分:2)

使用Kafka Streams。 SparkStreaming是一个误称(它是引擎盖下的迷你批次,至少高达2.2)。

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