对线面试官 - MQ 数据丢失问题的解决方案
书接上文。这次继续聊一聊 MQ
面试官:继上次你对 MQ 的回答,我还有一些疑问想要针对 MQ。我们继续聊一聊?
派大星:好的,当然可以。
面试官:OK,那我们继续上次的话题,就是 MQ 如何保证消息的可靠性,或者说如何保证消息不丢失呢?
派大星:这种情况需要就不同情况进行分析。主要是有三张场景会导致消息丢失的问题。
生产者丢失了消息
MQ 丢失了消息
消费的时候丢失了消息
面试官:嗯,不错,那你能就每种情况简单聊一聊吗?
派大星:可以,首先我先简单说一下 RabbitMQ 丢失消息如何解决。每种消息丢失的情况的解决方案大致如下图所示:
首先来说一说生产者丢失了消息:
主要场景是:写消息等过程中消息还没有到达 MQ 的时候,在网络传输的过程中就将消息丢失了;或者消息到了 RabbitMQ 但是 MQ 内部错乱没有存储消息导致消息丢失。
解决方案 1:可以使用RabbitMQ事务机制
,具体配置如下:
但是该种方案也有弊端:因为是事务机制,所以是同步阻塞的,这样就会导致生产者发送消息的吞吐量大大下降
解决方案 2:把 channel 设置成confirm
模式,发送一个消息就不用管了,RabbitMQ 如果接收到了这个消息就会回调生产者本地的一个接口,通知你说这条消息已经发送成功并且接受成功,反之也会通知。这种方式的吞吐量也会高一些。
其次说一些 RabbitMQ 自己弄丢了消息
这种情况的解决方可可以将 RabbitMQ设置为持久化
。除非有及其罕见的情况 RabbitMQ 还没来得及持久化自己就挂了,可能会导致少量的数据丢失,当然这种概率是很小的。
最后便是第三种情况:消费者丢失了消息
只有当你打开了消费者的autoAck
的这样一个机制:你消费到了数据之后消费者会自动通知 RabbitMQ 说我已经消费到了这条数据;这样会出现一种情况:假设你消费到了一条数据但是还没有处理完,此时消费者就自动autoAck
了。此时恰巧消费者系统服务挂了,消息还没来得及处理而且 RabbitMQ 以为该消息已经处理掉了。解决方案便是关掉RabbitMQ的自动ACK机制
面试官:不错,刚刚你有提到 RabbitMQ 设置持久化。你知道它怎么配置持久化吗:
派大星:直到的。具体步骤如下(注意两者缺一不可,需同时设置):
创建 queue 的时候将其设置为持久化的,这样保证 RabbitMQ 持久化 queue 的元数据,但是不会持久化 queue 里的数据
另外发送消息的时候将消息的
deliveryMode
设置为 2,就是将消息设置为持久化。此时 RabbitMQ 就会将消息持久化到磁盘上去。
面试官:不错,但是我们这边实际工作中用的 MQ 是 Kafka 居多,关于 Kafka 消息丢失就以上情况你了解具体的解决方案吗?
派大星:这个也了解一些。
首先说一下。Kafka 中消费者弄丢了消息的场景:
具体过程为消费者自动提交了 offset,其实消息还没有处理完。和 RabbitMQ 情况差不多。解决方案为:就是关闭自动提交offset,手动提交offset
其次说一下 Kafka 弄丢了消息
主要表现形式为:Kafka 的 leader 接受到了消息但是还没来得及同步给 follwer 就挂了,此时 follwer 变成了 leader。导致数据丢失。解决方案为:需要设置 4 个参数:
给 topic 设置
replication.replicas
参数,这个值必须要大于 1,也就是要求每个 parttion 只要有两个副本。在 Kafka 服务端设置
min.insync.replicas
参数:这个值必须要大于 1,这个是要求一个 leader 只要高指导最少有一个 follwer 还跟自己保持联系,这样才能确保 leader 还有一个 follwer。在 producer 段设置
ack=all
:这个要求是每条数据必须是写入所有的 replica 之后,才能认为是成功了。在 producer 端设置
retries=MAX
:这个要求一旦写入失败,就无线重试,卡在这里。
按照上述配置后至少保证了在 Kafka 段在 leader 所在的 broker 发生故障进行 leader 切换时,数据不会丢失。
最后聊一下生产者丢失数据的情况
如果是按照上述方式配置了ack=all
则一定不会丢,要求是:你的 leader 接收到消息,所有的 follwer 都同步到了消息之后,才认为本次消息发送成功,否则生产者会重试无限次。
如有问题,欢迎加微信交流:w714771310,备注- 技术交流 。或关注微信公众号【码上遇见你】。
版权声明: 本文为 InfoQ 作者【派大星】的原创文章。
原文链接:【http://xie.infoq.cn/article/1ca469f716c1d2f379b713ad6】。
本文遵守【CC BY-NC-ND】协议,转载请保留原文出处及本版权声明。
评论