broker与zk失去连接,leader切换,这期间的几秒内会发生部分数据丢失,我的replica配置是2,ack是all,从kafka的机制上来说会有这种数据丢失的问题么?怎么可以解决?
[2016-12-19 16:02:50,086] INFO re-registering broker info in ZK for broker 0 (kafka.server.KafkaHealthcheck$SessionExpireListener)
[2016-12-19 16:02:50,088] INFO Creating /brokers/ids/0 (is it secure? false) (kafka.utils.ZKCheckedEphemeral)
[2016-12-19 16:02:50,089] INFO Result of znode creation is: OK (kafka.utils.ZKCheckedEphemeral)
[2016-12-19 16:02:50,090] INFO Registered broker 0 at path /brokers/ids/0 with addresses: PLAINTEXT -> EndPoint(100.77.2.66,9092,PLAINTEXT) (kafka.utils.ZkUtils)
[2016-12-19 16:02:50,090] INFO done re-registering broker (kafka.server.KafkaHealthcheck$SessionExpireListener)
[2016-12-19 16:02:50,090] INFO Subscribing to /brokers/topics path to watch for new topics (kafka.server.KafkaHealthcheck$SessionExpireListener)
[2016-12-19 16:02:50,091] INFO New leader is 7 (kafka.server.ZookeeperLeaderElector$LeaderChangeListener)
数据丢失也跟producer和consumer有关,并不一定是主备切换导致的。
你设置是all,是producer发送数据后,副本也会响应,所以正常副本也是有数据的。
你在看看是那块导致数据丢失的。
另起一个consumer消费数据也是少了的,所以可以排除consumer的问题。另外每次数据丢失时间段都正好是leader切换时,所以判断是切换引起的,因为producer也没有报错,所以怀疑是broker的问题,不知道这里还有没有更好的定位方法。
丢失消息我发过一篇文章,你对比下https://www.orchome.com/429。你可能关闭的早了,消息还在缓存里没来得及发出进程已经结束了。
我的producer是常驻进程,一直都在跑,应该不会是进程结束导致的消息丢失。现在我不太好判断到底是broker还是producer的问题,感觉没有很好的定位手段
开一个broker试试。这样就没有主备切换了。
是否是kafka压力过大?leader下线?
如果是这种情况,肯定丢数据
负载并不大。另外,这种情况为什么肯定会丢呢?我配置的relica是2啊,ack也是all,producer没有错误的话理论上也不会丢失吧
zk和broker断链,这时候是查不到leader节点的,生产消费都会出现错误,如果没有gc的话可以考虑把zk超时时间放大
问题是生产和消费并没有报错,除了有zk断了的错误日志,其他都没有错误信息。
没报错有可能是中断时间比较短,zk一旦断了元数据就查不到了
仔细想了下,不一定丢数据,中间态会查不到leader,但是生产和消费都应有响应的同步元数据和类似重试的机制,leader选举后会恢复
生产者方面:当生产发送给kafka的消息超时了,这个时候其实是不知道消息kafka是不是已经接收到了。如果应用重发,则消息会重复,如果不发,那消息会丢失。
消费者方面:拿消费者获取一批数据之后,一批里面可能包含2000条或者更多,这时候有2种情况,直接提交offset。这时候如果应用宕机了,offset已经提交了,那这2000条就丢失了。如果应用程序处理完成这2000条,在提交,那么可能造成重复消费。
是的,kafka的ack是业务级的,理论上上kafka没接收到生产者应该是发送失败的,这样消息丢失是说得通的,但是我的生产者问题发生时没有错误上报,这个一直想不明白。
我目前还没遇到丢消息的情况。建议你改为同步发送。先排除掉生产丢消息的情况。
生产很难丢包,基本上是消费,消费逻辑如果不合理也会导致丢失。
检查下,ISR是否都同步,如果有副本不在isr中,切换状态,kafka重启后丢数据的可能性很大,如果原来的leader变成f,而原来的不在isr中的replica变成了l,这时候会有日志截断,这个部分的消息就丢了
你生产者send的时候要自己去捕获异常(send方法的第二个参数可以指定。如果直接使用try catch是无法知道是否生产者有问题。)。另外建议提高生产者重试次数。我有遇到这种情况。生产者显示丢一条记录。同样也是在broker Controller 切换的时候
你的答案