我在接受采访时被问过这个问题。
想象一下,由于失败而导致数据包丢失(不确定其消费者失败或经纪人)。应该做什么(代码实现)在此期间使用偏移恢复丢失的消息?
对不起,我的问题可能不太清楚,因为问的方式类似。
感谢
答案 0 :(得分:1)
如果您知道要恢复的邮件的偏移量以及它属于哪个分区,则可以使用KafkaConsumer
方法seek
:
consumer.seek(new TopicPartition("topic-name", partNumber), offsetNumber);
详细here
下一次调用poll()
会在列表中首先显示您错过的消息。
这只适用于您首先自行管理抵消的情况。如果您让Kafka管理偏移量,您可能不知道偏移数量,并且您可能最终会消耗两次消息(对poll()
的调用将从最后提交的偏移开始消耗) )。
答案 1 :(得分:0)
Kafka遵循at-least once
消息传递语义,这意味着您可能在代理失败时获得重复,您不会丢失数据。
但是当你创建Kafka Producer
如果你有这个属性为0,那么它将尝试只发送一次,即使在代理失败的情况下它也不会尝试重新发送。因此,如果代理失败,您可能会丢失数据。
props.put("retries", 0);
因此,您可以将此属性值更改为1,因此它将尝试再次发送,同时{Zoo}会自动在Zookeeper中管理,如果消息仅成功传递,它将更新{{1}中的偏移量}}
此外,由于您提到要使用SPark Streaming,因此SPark Streaming支持两种不同的方法。
<强> 1。基于接收者: 偏移量在Zookeeper中处理。
<强> 2。直接方法: 在存储消息的本地处理偏移量,这种方法也支持Exactly-once消息传递。
有关详细信息,请查看此link
答案 2 :(得分:0)
阅读了很多文章和文档后,我觉得最好的答案可能是:
使用没有接收器的新Spark Kafka Consumer(spark-streaming-kafka-0-10_2.11)。在这种方法中,我们可以从我们想要阅读的地方提供startOffset。
val offsetRanges = Array(// topic,partition,inclusive起始 偏移,独占结束偏移OffsetRange(“test”,0,0,100),
OffsetRange(“test”,1,0,100))val rdd = KafkaUtils.createDirectStream [String,String](sparkContext, kafkaParams,offsetRanges,PreferConsistent)
阅读并处理完您的消息后,获取您阅读的偏移量并将其存储在Kafka或Zk或外部交易数据库中。
offsetRanges = rdd.asInstanceOf [HasOffsetRanges] .offsetRanges
每次我们正在启动Job时,从数据库中获取Offsets并将其传递给createDirectStream以获得exacly once机制。
更多阅读 http://blog.cloudera.com/blog/2015/03/exactly-once-spark-streaming-from-apache-kafka/ https://spark.apache.org/docs/latest/streaming-kafka-0-10-integration.html