写点什么

对线面试官 - MQ 数据丢失问题的解决方案

作者:派大星
  • 2023-08-28
    辽宁
  • 本文字数:1622 字

    阅读完需:约 5 分钟

书接上文。这次继续聊一聊 MQ


面试官:继上次你对 MQ 的回答,我还有一些疑问想要针对 MQ。我们继续聊一聊?


派大星:好的,当然可以。


面试官:OK,那我们继续上次的话题,就是 MQ 如何保证消息的可靠性,或者说如何保证消息不丢失呢?


派大星:这种情况需要就不同情况进行分析。主要是有三张场景会导致消息丢失的问题。


  1. 生产者丢失了消息

  2. MQ 丢失了消息

  3. 消费的时候丢失了消息


面试官:嗯,不错,那你能就每种情况简单聊一聊吗?


派大星:可以,首先我先简单说一下 RabbitMQ 丢失消息如何解决。每种消息丢失的情况的解决方案大致如下图所示:



  • 首先来说一说生产者丢失了消息:


主要场景是:写消息等过程中消息还没有到达 MQ 的时候,在网络传输的过程中就将消息丢失了;或者消息到了 RabbitMQ 但是 MQ 内部错乱没有存储消息导致消息丢失。


解决方案 1:可以使用RabbitMQ事务机制,具体配置如下:


channel.txSelect();try{    // 发送消息}catch{    channel.txRollback();}channel.txCommit();
复制代码


但是该种方案也有弊端:因为是事务机制,所以是同步阻塞的,这样就会导致生产者发送消息的吞吐量大大下降解决方案 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 个参数:


  1. 给 topic 设置replication.replicas参数,这个值必须要大于 1,也就是要求每个 parttion 只要有两个副本。

  2. 在 Kafka 服务端设置min.insync.replicas参数:这个值必须要大于 1,这个是要求一个 leader 只要高指导最少有一个 follwer 还跟自己保持联系,这样才能确保 leader 还有一个 follwer。

  3. 在 producer 段设置ack=all:这个要求是每条数据必须是写入所有的 replica 之后,才能认为是成功了。

  4. 在 producer 端设置retries=MAX:这个要求一旦写入失败,就无线重试,卡在这里。


按照上述配置后至少保证了在 Kafka 段在 leader 所在的 broker 发生故障进行 leader 切换时,数据不会丢失。


  • 最后聊一下生产者丢失数据的情况


如果是按照上述方式配置了ack=all则一定不会丢,要求是:你的 leader 接收到消息,所有的 follwer 都同步到了消息之后,才认为本次消息发送成功,否则生产者会重试无限次。


如有问题,欢迎加微信交流:w714771310,备注- 技术交流 。或关注微信公众号【码上遇见你】。




发布于: 刚刚阅读数: 7
用户头像

派大星

关注

微信搜索【码上遇见你】,获取更多精彩内容 2021-12-13 加入

微信搜索【码上遇见你】,获取更多精彩内容

评论

发布
暂无评论
对线面试官 - MQ数据丢失问题的解决方案_MQ_派大星_InfoQ写作社区