消息队列的作用,高可用,顺序消费的那些事(二)

文章目录:

  1. 消息队列如何选型,各自的优缺点?
  2. 如何保证其可用性
  3. 如何保证消息不丢失?
  4. 如何保证消息不重复处理(EOS语义)?
  5. 如何保证消息的消费的顺序性?
  6. 如何解决集群故障后大量数据积压?

继上篇文章【消息队列的作用,高可用,顺序消费的那些事(一)】之后我们讨论了前三个 话题,在这篇文章中我们接着之前遗留下的话题来讨论。

一、如何保证消息不重复处理?

消息队列我们首先以kafka为例,我们可以分为两部分来分析其消息处理的重复性问题。

从生产者->Broker

首先在生产者发送到Broker中,我们要保证消息不被重复发送,那么kafka中是如何保证的呢?在kafka0.11之前并不能保证消息不被重复处理。在0.11版本之后,kafka解决了这一问题,对程序员来说无疑是一件很值得兴奋的事情。

在生产者初始化消息的时候,会生成一个唯一ID。PID和一个序列号会包含在消息中,一起被发送到broker。序列号从0开始单调递增,对于每一个PID/TopicPartition对来说,当且仅当消息的序列号比上一次提交消息的序列号刚好大1,broker才会接收这个消息。如果不是消息重复的话,生产者会重发消息。具体如下图所示:
在这里插入图片描述
(上图来自于网络)

从Broker->消费者

对于消费者的消费,我们也要保证其不能重复消费,从上面的讨论中我们可以看到,每一条消息会保存一个序列号,在消费者成功消息一条消息的时候,会向Broker提交一个offset,代表自己消费到了哪条消息,那么下次不管是消费者重启还是宕机都可以从之前的offset开始消费,避免了重复消费。

但是,这样也不能完全保证其不重复消费。当消费者消费成功一条消息的时候,此时还没来得及给broker提交offset就宕机了。此时broker并不知道它已经消费成功,保证的还是之前的offset,因此消息还是会重复消费,那么如何处理这种情况呢?

  1. 如果是写数据库的业务可以使用唯一键或者主键查询的方式来保证消息不重复消费。
  2. 使用redis生成全局唯一ID,首先去redis中去查询,如果没有就消费。
  3. 使用zookeeper生成全局唯一ID,同上。
如何保证消息消费的顺序性

RabbitMQ如何保证顺序性

在RabbitMQ中,如果一个queue中的消息被多个消费者消费,那么就出现消息消费的不一致性情况。如下图所示:
在这里插入图片描述
那么如何保证呢?最简单的方法就是,每一个消费者消费一个queue,这样这些具有依赖关系,有顺序性的消息就可以发送到一个queue中被一个消费者消费。如下图所示:
在这里插入图片描述
Kafka如何保证顺序性

在kafka中,每个broker中会有topic,每个topic会分为多个partition,每一个partition会被一个消费者消费,但是在消费者内部是多线程处理,因此,会出现顺序性问题,那么如何解决呢?在消费者的内部,我们可以使用单线程进行消费,这样可以保证顺序消费,但是吞吐量太低。我们一般写 N 个内存 queue,具有相同 key 的数据都到同一个内存 queue;然后对于 N 个线程,每个线程分别消费一个内存 queue 即可,这样就能保证顺序性。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值