使用Kafka进行Spark流式传输 - createDirectStream vs createStream

时间:2016-07-19 21:34:10

标签: apache-spark apache-kafka spark-streaming

我们一直使用kafka的spark spark,直到现在我们使用createStream中的KafkaUtils方法。

我们刚开始探索createDirectStream并喜欢它有两个原因:

1)更好/更容易“完全一次”语义

2)更好地将kafka主题分区与rdd分区相关联

我注意到createDirectStream被标记为实验性的。我的问题是(抱歉,如果这不是非常具体):

我们应该探索createDirectStream方法,如果一次对我们非常重要吗?如果你们可以分享你的经验,那将是非常棒的。我们是否有可能不得不处理可靠性等其他问题?

1 个答案:

答案 0 :(得分:9)

直接方法的创建者(Cody)here有一篇非常广泛的博客文章。

一般来说,阅读Kafka交付语义部分,最后一部分说:

  

因此,Kafka保证默认情况下至少一次交付   允许用户通过禁用最多实施一次交付   生产者重试并在处理之前提交其偏移量   一批消息。完全一次交付需要与合作   目标存储系统但Kafka提供了偏移量   实现这一点是直截了当的。

这基本上意味着“我们至少提供一次开箱即用,如果您只需要一次,那就在您身上”。此外,博客文章讨论了使用两种方法从Spark获得的“一次性”语义的保证(直接和基于接收器,强调我的):

  

其次,要明白 Spark并不能完全保证一次   输出操作的语义。当Spark流媒体指南进行讨论时   关于完全一次,它只是指RDD中的给定项目   被包含在计算值中一次,纯粹是功能性的   感。任何副作用输出操作(即你做的任何事情   foreachRDD保存结果)可能会重复,因为任何阶段   该过程可能会失败并重试。

此外,这是Spark文档中关于基于接收器的处理的说法:

  

第一种方法(基于Receiver)使用Kafka的高级API来存储消费   Zookeeper中的偏移量。传统上这是消费数据的方式   来自卡夫卡。 虽然这种方法(与提前写入日志相结合)   可以确保零数据丢失(即至少一次语义),有一个   在某些失败情况下,某些记录可能会被消耗两次。

这基本上意味着如果您使用基于Receiver的流与Spark,您可能仍然有重复数据,以防输出转换失败,它至少一次

在我的项目中,我使用直接流方法,其中传递语义依赖于如何处理它们。这意味着如果您想确保一次语义,您可以将偏移量与数据一起存储在事务中,如果一个失败,另一个失败也是如此。

我建议您阅读博文(上面的链接)和Delivery Semantics in the Kafka documentation page。总而言之,我绝对建议您研究直接流方法。