我们一直使用kafka的spark spark,直到现在我们使用createStream
中的KafkaUtils
方法。
我们刚开始探索createDirectStream
并喜欢它有两个原因:
1)更好/更容易“完全一次”语义
2)更好地将kafka主题分区与rdd分区相关联
我注意到createDirectStream
被标记为实验性的。我的问题是(抱歉,如果这不是非常具体):
我们应该探索createDirectStream
方法,如果一次对我们非常重要吗?如果你们可以分享你的经验,那将是非常棒的。我们是否有可能不得不处理可靠性等其他问题?
答案 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。总而言之,我绝对建议您研究直接流方法。