我在Kafka网站上阅读了文档,但在尝试实现一个完整的最小例子(生产者 - > kafka - >消费者)之后,我不太清楚“消费者状态”,偏移需要如何被处理。
一些信息
现在,文档说HighLevel API使用者使用zookeeper存储其状态,所以我希望偏移量因此消费者的状态将保持在
之间。但不幸的是它没有:每次重新启动代理或消费者时,都会重新传递所有消息。 现在,可能这些都是愚蠢的问题,但
在Kafka重启的情况下:我明白这取决于消费者保持其状态所以可能是当经纪人(重新)启动重新发送所有(!)消息和消费者时决定吃什么......是吗?如果是这样,如果我有10.0000.0000的消息会怎么样?
如果JVM使用者重新启动:如果状态保留在Zookeeper上,为什么要重新传递消息?是否有可能新的JVM具有不同的消费者“身份”?在这种情况下,我如何绑定以前的身份?
答案 0 :(得分:4)
是的,消费者负责保持其状态,Java高级消费者将其状态保存在zookeeper中。
您很可能没有指定groupId
配置属性。在那种情况下,kafka会随机生成groupId
。
您也可能关闭了autocommit.enable
配置属性。
可在此页面上找到Kafka配置的完整参考:“高级消费者的重要配置属性”标题下的http://kafka.apache.org/configuration.html。
答案 1 :(得分:4)
回答原来的问题:使用groupId有助于避免“从一开始就重新消耗所有消息”的情况
如果更改groupId,您将从创建队列的那一刻起(或自上次基于kafka日志保留策略的数据清除以来)获取所有消息
不要将此与kafka-console-consumer“ - from-beginning”标志(设置auto.offset.reset选项)混淆,后者可在下面的选项1和2之间进行选择:
1)从消耗最后一条消息的那一刻起消耗新消息(而不是从最初创建kafka队列时开始):
props.put(“auto.offset.reset”,“最小”);
2)从订阅者JVM启动的那一刻开始消耗新消息(在这种情况下,当用户关闭并且没有收听队列时,您可能会丢失丢失的消息):
props.put( “auto.offset.reset”, “最大”);
旁注:以下内容仅与原始问题
相切对于更高级的用例 - 如果您尝试以编程方式设置使用者偏移量以从特定时间开始重放消息 - 则需要使用https://cwiki.apache.org/confluence/display/KAFKA/0.8.0+SimpleConsumer+Example中所示的SimpleConsumer API以找到最小的偏移量从正确的经纪人/分区重播。这本质上是用我们自己的FindLeader逻辑替换zookeeper。非常棘手
对于这个用例(从某个用户指定的时间开始的消息的临时重放),我们决定存储消息的本地缓存并在本地管理偏移,而不是使用kafka偏移管理api(这需要重新实现一个好的块)使用SimpleConsumer的zookeeper功能)。
即。将kafka视为“邮递员”,一旦邮件被传递,它就会转到本地邮箱,以防万一我们需要回到过去的某个偏移量,比如重放消息(已经消耗过的),例如如果消费者应用程序出错,我们不会回到“邮局”(kafka经纪人)来确定正确的交付订单,但要管理本地。
旁注的结尾
答案 2 :(得分:2)
我似乎是一个糟糕的读者...这一切都在配置页面中。具体来说,我的两个问题都是通过设置一个默认为“最小”的标志“autooffset.reset”来解决的,因此会产生所描述的效果。
现在,以“最大”作为值,在消费者和经纪人重启的情况下,事情正如预期的那样工作,因为偏移总是最大的。