如何保证MQ的可靠性传输

所谓可靠性传输是指:不能丢数据。这里丢数据分两种:

  • 生产者生产时丢数据
  • 消息队列本身丢数据
  • 消费者消费时丢数据

RabbitMQ

RabbitMQ 有三种丢数据的情况:

  1. 生产者传入过程中消息丢失
  2. RabbitMQ 收到消息,暂时保存内存,还没来得及消费,进程挂掉了,内存中数据丢失
  3. 消费者消费 MQ 时,正准备处理,系统宕机了,RabbitMQ 认为这条 MQ 已经被消费

RabbitMQ 生产者在发送数据前可以开启 RabbitMQ 事务,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,回滚事务重新发送即可。如果消息被成功接收,提交事务即可。然而使用事务会大幅度降低吞吐量,系统损耗严重

除了上面提到的事务处理,还可以采用 confirm 模式。在生产者设置开启 confirm 模式后,每次写消息会分配唯一 ID,消息写入 RabbitMQ 时会回传 ack 消息,如果没有处理某个消息,RabbitMQ 会回调 nack 接口,告诉某个消息发送失败,生产者可以重发。甚至生产者可以在内存中根据 ID 维护每个 MQ 的状态,如果长时间没有收到 ack 也重发

这里事务是同步的,confrim 是异步的,相比事务,confirm 更加高效

对于 RabbitMQ 自己丢失数据,可以通过持久化解决,消息写入之后会持久化到磁盘,此时哪怕 RabbitMQ 挂掉了,恢复之后也可以自动读取之前存储的数据,不会丢失

如果 RabbitMQ 在正准备持久化时挂掉,就可能丢失一小部分数据。此时我们可以结合 confrim 模式,在消息持久化完成后再返回 ack,丢失的数据生产者会重发。

消费端弄丢数据的主要是因为正准备消费时,系统挂掉了。此时我们关闭 RabbitMQ 自动 ack 机制,不在消费端收到消息时返回 ack,而在消费端处理完消费无误时再 ack,这样即使处理 MQ 时系统异常宕机也不会影响数据。
RabbitMQ的可靠性传输


Kafka

KafKa 同样有三种丢数据的场景:

  • 生产者传送时丢失
  • Kafka 自身丢失
  • 消费者消费时丢失

Kafka 可以通过以下两个参数确保生产者传送时不丢失数据:

  • acks=all:每条数据写入所有 leader 以及 follower 才会返回 ack
  • retries=MAX:确保每次写入失败后,无限重试

Kafka 自身丢数据主要集中在某个 broker 突然挂机,此时该 broker 上的 leader partition 还没有完全同步到 follower,后续重新选主出的 leader 就会丢失一部分数据。对于这种场景通过以下四个参数解决:

  • topic 设置 replication.factor,值大于1,要求每个 partition 至少有两个副本
  • 给 kafka 设置 min.insync.replicas,值大于1,保证一个 leader 至少感知到一个 follower 跟自己保持一致。
  • (配合生产者传送时丢失的两个参数)

对于消费者消费时丢失,原理和 RabbitMQ 是相同的,无非 RabbitMQ 接收 ack,Kafka 返回 offset。处理方式也相同:关闭 Kafka offset 自动提交,在代码中消息正常消费完成后再提交 offset 即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值