Flume KafkaChannel数据重复问题

近期笔者在生产环境中使用Flume的hdfssink读取kafkachannel中的数据,然后写到hdfs文件中,出现了数据重复采集的状况,为此,开启了一次Flume数据传输流程的探索。

问题现象

最先发现问题是在hdfs中发现很多大小一模一样的文件,原本以为到达了Flume的采集能力上限导致只能写这么多数据,结果把文件拉下来进行MD5校验发现所有的文件是一样的,这意味着我们的文件采集重复了,接着去查了Flume 的运行日志,发下如下异常:org.apache.flume.EventDeliveryException: org.apache.kafka.clients.consumer.CommitFailedException: Commit cannot be completed due to group rebalance

2020-04-21 08:45:55,930 (SinkRunner-PollingRunner-DefaultSinkProcessor) [ERROR - org.apache.flume.sink.hdfs.HDFSEventSink.process(HDFSEventSink.java:447)] process failed
org.apache.kafka.clients.consumer.CommitFailedException: Commit cannot be completed due to group rebalance
        at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator$OffsetCommitResponseHandler.handle(ConsumerCoordinator.java:552)
        at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator$OffsetCommitResponseHandler.handle(ConsumerCoordinator.java:493)
        at org.apache.kafka.clients.consumer.internals.AbstractCoordinator$CoordinatorResponseHandler.onSuccess(AbstractCoordinator.java:665)
        at org.apache.kafka.clients.consumer.internals.AbstractCoordinator$CoordinatorResponseHandler.onSuccess(AbstractCoordinator.java:644)
        at org.apache.kafka.clients.consumer.internals.RequestFuture$1.onSuccess(RequestFuture.java:167)
        at org.apache.kafka.clients.consumer.internals.RequestFuture.fireSuccess(RequestFuture.java:133)
        at org.apache.kafka.clients.consumer.internals.RequestFuture.complete(RequestFuture.java:107)
        at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient$RequestFutureCompletionHandler.onComplete(ConsumerNetworkClient.java:380)
        at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:274)
        at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.clientPoll(ConsumerNetworkClient.java:320)
        at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:213)
        at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:193)
        at org.apache.kafka.clients.consumer.internals.ConsumerNetworkClient.poll(ConsumerNetworkClient.java:163)
        at org.apache.kafka.clients.consumer.internals.ConsumerCoordinator.commitOffsetsSync(ConsumerCoordinator.java:358)
        at org.apache.kafka.clients.consumer.KafkaConsumer.commitSync(KafkaConsumer.java:968)
        at org.apache.flume.channel.kafka.KafkaChannel$ConsumerAndRecords.commitOffsets(KafkaChannel.java:684)
        at org.apache.flume.channel.kafka.KafkaChannel$KafkaTransaction.doCommit(KafkaChannel.java:567)
        at org.apache.flume.channel.BasicTransactionSemantics.commit(BasicTransactionSemantics.java:151)
        at org.apache.flume.sink.hdfs.HDFSEventSink.process(HDFSEventSink.java:433)
        at org.apache.flume.sink.DefaultSinkProcessor.process(DefaultSinkProcessor.java:67)
        at org.apache.flume.SinkRunner$PollingRunner.run(SinkRunner.java:145)
        at java.lang.Thread.run(Thread.java:748)

也就说消费者提交offset不成功,原因是消费者组进行rebalance了

问题分析

根据Flume报出的异常,我们分析一次rebalance应该不至于导致发生这么大的故障的,消费的离开和加入不都会产生重平衡吗,应该不会是重平衡本身造成的这个问题,最后去阅读了Flume源码才找到问题原因的来龙去脉,现将问题出现的原因总结如下
首先,集群有一段时间HDFS读写负载很高,进而导致hdfssink写入hdfs出现了几次10s超时,按理说虽然后续HDFS恢复了且几次写超时应该不至于造成大的影响,可问题的原因就出在这里,Flume的事务机制确保每一个批次的消息都要投递到数据要去的地方,否则会进行回滚,但是Kafka本身也有机制来检测消费者状态,其中有一项是检测消费着两次poll的时间间隔,若超过了设置的时间则认为消费者已经死掉进行重平衡,所以当写HDFS超时后,事务回进行回滚重试,在次期间,不再去kafka poll新的消息,当事务重试的时间超过了两次poll的时间间隔的最大限制后,kafkar认为此消费者已经死掉并进行重平衡,后续虽然事务成功了,但是由于已经进行重平衡,导致offset无法提交成功,紧接着,Flume会再次从上回的offset进行消费,然后写hdfs成功,提交offset不成功…这个过程周而复始进入循环,结局就是采集持续重复现象发生了

问题解决

这里可以理解成Flume的事务机制和Kafka的offset机制两者的配合出现了问题,sink不管是hdfs、hive、avro等各类,只要后面存在写不稳定的情况,原理上都有可能触发此类问题,如果不想大改,可以修改kafka的poll时间间隔,心跳超时等时间设置,但是只能是降低事情发生的触发条件,未根本解决问题,我们是自己开发了读kafka写hdfs的组件,自己控制读取,offset提交的方式规避了这个问题

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值