各种消息中间件对比与总结

一:优劣对比

消息中间件ActiveMq,RabbitMq,RocketMq,Kafka面试时可以从单机吞吐量,时效性,架构可靠性,消息可靠性,支持的功能等方面去讲

ActiveMqRabbitMqRocketMqKafka
单机吞吐量每秒万级每秒万级10万级10万级
时效性毫秒级微秒级毫秒级毫秒级
可用性基于主从架构基于主从架构天然支持分布式天然支持分布式
消息可靠性较低概率丢失经过配置几乎可以0丢失经过配置几乎可以0丢失经过配置几乎可以0丢失
功能及其完备基于erlang语言开发,并发能力强,延时很低接口简单易用,功能完备,扩展性好,比如支持,普通消息(同步发送,异步发送,单向发送),定时延时消息,顺序消息,事物消息功能较为简单,主要支持简单的mq功能,因为功能简单,在大数据以及日志采集方面用处广
数据存储每个节点存储着所有的数据每个节点存储着所有的数据每个节点存储着一部分数据,并且每个节点都有数据备份,防数据丢失每个节点存储着一部分数据,并且每个节点都有数据备份,防数据丢失
消费方式pull(基于长轮训的拉模式)push(broker 的推模式)pullpull

 

参考一参考二参考三

二:消息存储与消费

  1. RabbitMq

  • 是基于主从做高可用的,有三种模式:单机模式,普通集群模式,镜像集群模式,每台机器上存储着全量的数据。(这里不多做介绍)
  1. RocketMq

  • 架构:Producer (Producer Group)、Consumer (Consumer Group)、 NameServer 、Broker (Topic-->queue)、master/slave结构
    • 是天然支持分布式的,Topic由多个队列组成,队列会平均分散在多个Broker上,而Producer的发送机制保证消息尽量平均分布到所有队列中,最终效果就是所有消息都平均落在每个Broker上,类似elasticsearch存储数据一样
      • kafaka/rocketmq
  • 消息消费:
    •   一个消费者集群(Consumer Group )多台机器共同消费平均消费一个 topic 的多个队列,一个队列只会被一个消费者消费。如果某个消费者挂掉,分组内其它消费者会接替挂掉的消费者继续消费
    • 不同消费者组的消费者全量消费一个 topic 的多个队列所有的消息
    • 而每个消费者组在每个队列中的消费位置都是不同的。如果此时有多个消费者组,那么消息被一个消费者组消费完之后是不会删除的(因为其它消费者组也需要呀),它仅仅是为每个消费者组维护一个 消费位移(offset) ,每次消费者组消费完会返回一个成功的响应,然后队列再把维护的消费位移加一,这样就不会出现刚刚消费过的消息再一次被消费临近期末考试,一篇消息队列和RocketMQ的总结送给你们(二)
    • 为什么一个主题中需要维护多个队列:答案是 提高并发能力
    • 所以总结来说,RocketMQ 通过使用在一个 Topic 中配置多个队列并且每个队列维护每个消费者组的消费位置 实现了 主题模式/发布订阅模式 。
    • rocketmq的消息顺序消费,在全局消息下是无法保证的,如果想要顺序消费那么就把消息单独发送到一个queue里面这样可以顺序消费
  • 重复消费
    • 发生重复消费的原因有3点
    • 发送时消息重复

      当一条消息已被成功发送到服务端并完成持久化,此时出现了网络闪断或者客户端宕机,导致服务端对客户端Producer 应答失败。 如果此时生产者Producer 意识到消息发送失败并尝试再次发送消息,消费者后续会收到两条内容相同并且 Message ID 也相同的消息。

    • 投递时消息重复

      消息消费的场景下,消息已投递到消费者并完成业务处理,当客户端给服务端反馈应答的时候网络闪断。为了保证消息至少被消费一次,消息队列 RocketMQ 版的服务端将在网络恢复后再次尝试投递之前已被处理过的消息,消费者后续会收到两条内容相同并且 Message ID 也相同的消息。

    • 负载均衡时消息重复(包括但不限于网络抖动、Broker 重启以及消费者应用重启)

      当消息队列 RocketMQ 版的 Broker 或客户端重启、扩容或缩容时,会触发 Rebalance,此时消费者可能会收到重复消息

    • 解决办法
      • rocketmq消息重复问题解决起来是很复杂的一件事,所以最好的办法就是不解决,所以需要我们自己根据业务情况来去做幂等
  • 消息类型
    • 普通消息(同步发送,异步发送,单向发送)
    • 定时和延时消息
    • 顺序消息
    • 事物消息
  • 消息可靠性(可点击)
    • 从Producer的视角来看:消息发送失败会丢失
    • 从Broker的视角来看:消息存持久化失败会丢失
    • 从Consumer的视角来看:消息返回消费成功应答码但是突然宕机消费失败会丢失
    • 解决:
      • Producer可以采用同步阻塞式的发送,检查Brocker返回的状态是否持久化成功,状态超时或者失败,则会触发默认的2次重试,RocketMQ 选 择了确保一定投递,保证消息不丢失,但有可能造成消息重复
      • Broker自身支持同步双写和异步刷盘的策略,可以保证接收到的消息一定存储在本地的内存中,并且Broke集群支持 1主N从的策略,支持同步复制和异步复制的方式,同步复制可以保证即使Master 磁盘崩溃,消息仍然不会丢失  2、Broker采取事务消息的投递方式,并不能保证消息100%投递成功到了Broker,但是如果消息发送Ack失败的话,此消息会存储在CommitLog当中
      • Consumer可以关闭自动消费之后的响应码为手动状态,人为的确保消费成功之后再返回ack码,然后再更新消费唯一offset
  1. Kafka

  • 架构:Producer (Producer Group)、Consumer (Consumer Group)、zk(0.9版本之后弃用使用Broker存储元数据)、Broker (Topic-->Partition-->Replica)、Leader/Follower结构
    • 分布式架构的, Topic 可以分布到多个 Broker (即服务器)上,一个 Topic 可以分为多个 Partition,每个 Partition 是一个 有序的队列。Replica:副本,为实现备份的功能,保证集群中的某个节点发生故障时,该节点上的 Partition 数据不丢失,且 Kafka 仍然能够继续工作,Kafka 提供了副本机制,一个 Topic 的每个分区都有若干个副本,一个 Leader 和若干个 Follower。
    • Topic 是逻辑上的概念,而 Partition 是物理上的概念,每个 Partition 对应于一个 log 文件,该 log 文件中存储的就是 Producer 生产的数据。Producer 生产的数据会不断追加到该 log 文件末端,且每条数据都有自己的 Offset。

  • 消息消费
    • 消费者组内每个消费者负责消费不同分区的数据,提高消费能力。一个分区只能由组内一个消费者消费,消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。这点跟RocketMq中的同一Consumer Group消费类似,这样方便扩展
  • 存储机制
    • 由于生产者生产的消息会不断追加到 log 文件末尾,为防止 log 文件过大导致数据定位效率低下,Kafka 采取了分片和索引机制。它将每个 Partition 分为多个 Segment,每个 Segment 对应两个文件:“.index” 索引文件和 “.log” 数据文件。

  • 重复消费
    • Kafka消费数据会在zk里面记录当前消费者消费到的位置offset=第几条数据,每当消费者消费一条数据之后都会通知zk去提交消费者的位置,但是并不是每次消费一条数据都会去提交,而是定时定期提交一次offset,kafka后面的版本消费唯一offset都存在了broker上了,所以当消费者消费完之后还没有提交offset的时候突然宕机了,等启动之后然而位移没发生变化,就可能会出现重复消费。
    • 消息队列不保证消息的幂等性,需要我们自己根据业务去保证消息幂等性。
  • 消息可靠性
    • 从Producer的视角来看:消息发送失败会丢失
    • 从Broker的视角来看:消息存持久化失败会丢失
    • 从Consumer的视角来看:消息返回消费成功应答码但是突然宕机消费失败会丢失
    • 解决:
      • 为保证 Producer 发送的数据,能可靠地发送到指定的 Topic,Topic 的每个 Partition 收到 Producer 发送的数据后,都需要向 Producer 发送 ACK(ACKnowledge 确认收到)。如果 Producer 收到 ACK,就会进行下一轮的发送,否则重新发送数据

      • 何时发送 ACK?确保有 Follower 与 Leader 同步完成,Leader 再发送 ACK,这样才能保证 Leader 挂掉之后,能在 Follower 中选举出新的 Leader 而不丢数据。多少个 Follower 同步完成后发送 ACK?全部 Follower 同步完成,再发送 ACK。

      • ACK 应答机制

        • 对于某些不太重要的数据,对数据的可靠性要求不是很高,能够容忍数据的少量丢失,所以没必要等 ISR 中的 Follower 全部接受成功。所以 Kafka 为用户提供了三种可靠性级别,用户根据可靠性和延迟的要求进行权衡,选择以下的配置。

        • 0:Producer 不等待 Broker 的 ACK,这提供了最低延迟,Broker 一收到数据还没有写入磁盘就已经返回,当 Broker 故障时有可能丢失数据。

        • 1:Producer 等待 Broker 的 ACK,Partition 的 Leader 落盘成功后返回 ACK,如果在 Follower 同步成功之前 Leader 故障,那么将会丢失数据。

        • -1(all):Producer 等待 Broker 的 ACK,Partition 的 Leader 和 Follower 全部落盘成功后才返回 ACK。但是在 Broker 发送 ACK 时,Leader 发生故障,则会造成数据重复。

参考:Kafka1Kafka2

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值