文章参考:腾讯技术工程《关于消息队列的知识总结》
主流消息队列你了解哪些?
消息队列的发展历程
2003 年至今有很多优秀的消息队列诞生,如 kafka、阿里自研的 rocketmq 以及后起之秀 pulsar
消息队列在刚出现所需要解决的问题就是:
解决系统间的强耦合
,这也是 activemq 和 rabbitmq 所致力于做的功能
而在 2010 年到 2012 年期间,互联网进入快速发展时期,数据量急速上升,此时对系统的性能有了新的挑战,该阶段消息队列发展的方向逐渐转向了
吞吐量、高并发
, 因此 Kafka 诞生了
随着电商业务的兴起,kafka 在许多业务方面的支持无法满足电商系统的场景,因此 RocketMQ 诞生了,在功能性上比 Kafka 要更加全面,虽然性能不如 Kafka
再之后,容器化、云计算、k8s 技术兴起,如何把基本底层技术能力平台化成为了众多公司的攻坚方向,在此背景下,Pulasr 诞生了
主流消息队列存储分析
Kafka
架构图如下:
对于 Kafka 来说,Kafka 的服务节点没有主从的概念,它主从的概念是针对于 topic 下的某个 partition 来说的
Kafka 消息存储在分区中,每个分区对应
一组连续的物理空间
,新消息被追加到磁盘文件的末尾
Kafka 的读写是
顺序的
,因此可以高效地利用 PageCache(即读取一个数据,会将该数据附近的数据也进行读取,减少磁盘 IO 次数),大幅度提升磁盘读写的性能
RocketMQ
RocketMQ 主从架构图如下:
RocketMQ 相比于 Kafka 选择了轻量级的独立服务器 namesrv,namesrv 特点如下:
-
使用简单的 k/v 结构保存信息
-
支持集群,每个 namesrv 相互独立,不互相通信
-
数据保存在内存,broker 的注册过程通过遍历所有的 namesrv 进行注册
RocketMQ 的设计理念是追求
极致的消息写
,将所有的 topic 消息存储在同一个文件中,确保所有消息发送时,按照顺序写文件,最大可能地保证消息发送地高可用和高吞吐量,但是这种 topic 共用文件地设计使 RocketMQ 不支持删除指定 topic 功能,因为对于某个 topic 的信息,在磁盘上的表现是一段非连续的区域,而不像 kafka,一个 topic 就是一段连续的区域
Pulsa
Pulsa 的特点是使用了分层和分片的架构:
在 Kafka 和 RocketMQ 中,一个服务节点既是计算节点也是服务节点,节点是有状态的,因此容器化、数据迁移、数据扩容缩容等工作都变得非常复杂,因为还需要考虑节点上的数据,如果节点无状态,直接通过添加或者去除节点就可以实现扩容/缩容工作
服务层设计
Broker 集群在 Pulsar 中形成无状态服务层,服务层是
无状态的
,所有数据存储在了 BookKeeper 上,元消息存储在了 zookeeper 上,Broker 中不存储数据
存储层设计
Pulsar 使用了类似于 raft 的存储方案,数据并发写入多个存储节点上
broker2 节点当前需要写入 segment1 到 segment4 数据,流程为:segment1并发写入 b1、b2、b3 数据节点、segment2 并发写入 b2、b3、b4 数据节点、segment3 并发写入 b3、b4、b1 数据节点、segment4 并发写入 b1、b2、b4 数据节点
这种写入方式成为条带化的写入方式,这种方式潜在的决定了数据的分布方式,通过路由算法,可以很快地找到对应数据的位置信息,在数据迁移和恢复中起到重要的作用