由于在具体开发中某些环节考虑使用kafka却担忧有消息丢失的风险,本周结合项目对kafka的消息可靠性作了一下调研和总结:网络
首先明确一下丢消息的定义。kafka集群中的部分或所有broker挂了,致使consumer没有及时收到消息,这不属于丢消息。broker挂了,只要消息所有持久化到了硬盘上,重启broker集群以后,使消费者继续拉取消息,消息就没有丢失,仍然全量消费了。运维
以个人理解,所谓丢消息,意味着:开发人员未感知到哪些消息没有被消费。性能
我把消息的丢失概括了如下几种状况:.net
1)、 producer把消息发送给broker,由于网络抖动,消息没有到达broker,且开发人员无感知。blog
解决方案:producer设置acks参数,消息同步到master以后返回ack信号,不然抛异常使应用程序感知到并在业务中进行重试发送。这种方式必定程度保证了消息的可靠性,producer等待broker确认信号的时延也不高。内存
2)、 producer把消息发送给broker-master,master接收到消息,在未将消息同步给follower以前,挂掉了,且开发人员无感知。开发
解决方案:producer设置acks参数,消息同步到master且同步到全部follower以后返回ack信号,不然抛异常使应用程序感知到并在业务中进行重试发送。这样设置,在更大程度上保证了消息的可靠性,缺点是producer等待broker确认信号的时延比较高。kafka
3)、 producer把消息发送给broker-master,master接收到消息,master未成功将消息同步给每一个follower,有消息丢失风险。同步
解决方案:同上。ast
4)、 某个broker消息还没有从内存缓冲区持久化到磁盘,就挂掉了,这种状况没法经过ack机制感知。
解决方案:设置参数,加快消息持久化的频率,能在必定程度上减小这种状况发生的几率。但提升频率天然也会影响性能。
5)、consumer成功拉取到了消息,consumer挂了。
解决方案:设置手动sync,消费成功才提交。
综上所述,集群/项目运转正常的状况下,kafka不会丢消息。一旦集群出现问题,消息的可靠性没法彻底保证。要想尽量保证消息可靠,基本只能在发现消息有可能没有被消费时,重发消息来解决。因此在业务逻辑中,要考虑消息的重复消费问题,对于关键环节,要有幂等机制。
几条建议:
1)、若是一个业务很关键,使用kafka的时候要考虑丢消息的成本和解决方案。
2)、producer端确认消息是否到达集群,如有异常,进行重发。
3)、consumer端保障消费幂等性。
4)、运维保障集群运转正常且高可用,保障网络情况良好。————————————————版权声明:本文为CSDN博主「qrne06」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处连接及本声明。原文连接:https://blog.csdn.net/qrne06/article/details/94225070