我想输出火花和火花流到卡夫卡一次。但正如医生说的那样
"输出操作(如foreachRDD)至少具有一次语义,也就是说,如果工作者发生故障,转换后的数据可能会被多次写入外部实体。 "
要进行事务更新,spark建议使用批处理时间(在foreachRDD中可用)和RDD的分区索引来创建标识符。该标识符唯一地标识流应用程序中的blob数据。代码如下:
dstream.foreachRDD { (rdd, time) =>
rdd.foreachPartition { partitionIterator =>
val partitionId = TaskContext.get.partitionId()
val **uniqueId** = generateUniqueId(time.milliseconds, partitionId)
// use this uniqueId to transactionally commit the data in partitionIterator
}
}
但是如何使用kafka中的 uniqueId 进行事务提交。
由于
答案 0 :(得分:1)
Kixer的高级软件工程师Cody Koeninger在Spark峰会上讨论了与Kafka完全一致的解决方案。本质上,此解决方案涉及通过同时提交存储偏移量和数据。
在2016年的Confluent聚会上向工程师提及了一次专题,工程师们参考了Cody关于这一主题的讲座。 Cloudera在http://blog.cloudera.com/blog/2015/03/exactly-once-spark-streaming-from-apache-kafka/发表了他的演讲。 Cody的论文在http://koeninger.github.io/kafka-exactly-once/#1,他的github(对于这个主题)是在https://github.com/koeninger/kafka-exactly-once。他的演讲视频也可以在网上找到。
Kafka的后续版本引入Kafka Streams来处理没有Spark的一次性场景,但该主题仅值得注意,因为问题的框架是与Spark一起使用。