Kafka在什么情况下会丢数据

Kafka是高吞吐量数据总线,使用得当会使我们处理业务如鱼得水,如虎添翼。处理不当也会使系统残破不堪,维护起来痛苦万分,我们针对数据可靠性这点,来分析下这个消息组件在什么情况下会丢失数据。

一、producer配置acks=0

在acks=0模式下,消息传输到Broker端没收到Broker的反馈即发送下一条,这种纯异步的发送方式,难免会丢数据。

二、producer配置acks=1

在ack=1模式,只要消息传输到partition的leader节点,leader节点返回ack,即认为发送数据成功,无需等待副本全部同步完。这种模式下,在leader节点宕机时,副本还没同步完leader的数据,就会发生数据丢失。

三、NO_ENOUGH_REPLICATE

produer配置acks=all的时候,也是有可能会丢数据的,当某个partition的ISR列表中的副本数,不满足min.inSync.replicate的时候,生产者发送消息就得不到ack确认,这时候生产者会进入重试,重试次数为配置的message.send.max.retries,如果在重试次数内ISR列表副本数仍然达不到最小同步副本数,那么,生产者会抛出NO_ENOUGH_REPLICATE的异常,如果没能正确处理这个异常,很可能这条数据就丢失了

那么什么情况下ISR列表的副本数不足最小副本数呢?

follower副本进程卡住,在一段时间内根本没有向leader副本发起同步请求,比如频繁的Full GC。
follower副本进程同步过慢,在一段时间内都无法追赶上leader副本,比如IO开销过大。
四、NOT_LEADER_FOR_PARTITION

其中一台Broker会出现与zk的sessionTime out 连接超时,接着导致Controller重新选举,导致producer元数据不正确,此时写入该Broker,会抛出NOT_LEADER_FOR_PARTITION的警告,此时可能会发生数据丢失
auto.leader.rebalance.enable=true 也会进行重新选举leader的操作,导致写入原leader,抛出NOT_LEADER_FOR_PARTITION
五、磁盘故障

kafka的数据一开始就是存储在PageCache上的,定期flush到磁盘上的,也就是说,不是每个消息都被存储在磁盘了,如果出现断电或者机器故障等,PageCache上的数据就丢失了。

可以通过log.flush.interval.messages和log.flush.interval.ms来配置flush间隔

六、Producer生产数据过长

单批数据的长度超过限制会丢失数据,报kafka.common.MessageSizeTooLargeException异常
生产者生产的数据,大于消费者配置的能拉取的最大消息大小,这条大数据将会消费失败
七、无重发重试

网络负载很高或者磁盘很忙写入失败的情况下,没有自动重试重发消息。没有做限速处理,超出了网络带宽限速。kafka一定要配置上消息重试的机制,并且重试的时间间隔一定要长一些,默认1秒钟并不符合生产环境(网络中断时间有可能超过1秒)。

八、消费者崩溃

如果auto.commit.enable=true,当consumer fetch了一些数据但还没有完全处理掉的时候,刚好到commit interval出发了提交offset操作,接着consumer crash掉了。这时已经fetch的数据还没有处理完成但已经被commit掉,因此没有机会再次被处理,数据丢失。

九、消费者异常没正确处理

Consumer消费者自动提交位点,在消费者消费数据异常时,没有将异常数据处理妥当,导致业务异常数据丢失
Consumer手动批量提交位点,在批量位点中某个位点数据异常时,没有正确处理异常,而是将批量位点的最后一个位点提交,导致异常数据丢失

你可能感兴趣的:(Kafka,kafka)