RocketMQ

来自智得网
跳转至: 导航、​ 搜索

简介

RocketMQ最早是阿里巴巴研发的类Kafka的消息队列,前身是MetaQ,后来开源,目前已经是apache旗下的顶级开源项目,RocketMQ采用Java语言进行开发,具有高性能、高可靠、高实时、分布式特点。

RocketMQ由Producer,Consumer,Broker,NameServer等四个组件构成。

RocketMQ 类比Kafka 作用
Producer Producer 消息的生产方,一般通过SDK和Broker进行交互
Consumer Consumer 消息的消费方,一般通过SDK和Brokder交互
Broker Broker 消息队列的服务提供方,提供消息存储,消息推送等能力
NameServer -- 消息队列的配置服务,Kafka采用zookeeper实现该功能

原理

Broker

存储

Broker的存储可以分为数据文件的存储和索引文件的存储。

数据文件就是消息存储文件,各个Topic的消息根据到达 Broker 的顺序写入各自的 CommitLog 文件,CommitLog文件默认为1G,文件的命名信息中包含了该存储在消息文件中的第一个全局偏移量,从而根据offset可以快速定位到消息所在的物理文件。

RocketMQ的CommitLog 文件使用顺序写,所以性能较高。

除了消息存储文件之外,每个消息队列可能会有多个消费者,每个消费者都需要消费这些事件,而且消费的速度是不同的,所以需要根据消费者记录消息的消费状况。这部分数据就是消息消费队列文件。

消费队列文件的组织方式为 /topic/queue,同一个队列中存在多个文件,ConsumeQueue 设计是每个条目使用固定长度(8字节 CommitLog 物理偏移量、4字节消息长度、8字节 Tag HashCode),这里不是存储 tag 的原始字符串,而是存储 HashCode,目的就是确保每个条目的长度固定,可以使用访问类似数组下标的方式来快速定位条目,极大的提高了 ConsumeQueue文件的读取性能,试想一下,消息消费者根据 Topic、消息消费进度(ConsumeQueue 逻辑偏移量),即第几个 ConsumeQueue 条目,这样根据消费进度去访问消息的方法为使用逻辑偏移量logicOffset* 20即可找到该条目的起始偏移量( ConsumeQueue 文件中的偏移量),然后读取该偏移量后20个字节即得到了一个条目,无需遍历 ConsumeQueue 文件。

除了基于offset的消费之外,Broker还需要提供根据其他索引查询消息的能力。

IndexFile就是基于物理磁盘文件实现 Hash 索引。其文件由40字节的文件头、500W个 Hash 槽,每个 Hash 槽为4个字节,最后由2000万个 Index 条目,每个条目由20个字节构成,分别为4字节的索引key的 HashCode、8字节消息物理偏移量、4字节时间戳、4字节的前一个Index条目( Hash 冲突的链表结构)。

集群

RocketMQ集群主要分为两类节点,NameServer节点以及数据节点。

NameServer的高可用采用的是多副本的方式,消息队列对于CAP来说,更加看重可用性和分区容忍性,对于一致性的要求不高,所以采用多副本的方式部署NameServer。

BrokerServer的读写正常情况下都由Master节点提供,Slave提供容灾功能。

Broker集群可以分为多master,多master多slave同步模式,多master多slave异步模式。

多master方式的实现最为简单,master之间不需要数据同步,master宕机也不会影响其他正常节点的新数据写入,但是master节点宕机之后会导致部分数据不能消费。

多master和slave同步模式中,每个master都会有一个或者多个slave节点,数据写入到master节点之后需要同步到其他所有的slave节点才会正常返回,该模式的数据安全性以及一致性最高,性能最差。

为了兼顾数据安全以及一致性和服务的性能,rocketmq提供了第三种集群模式,即多master多slave异步模式,该模式下master同样由多个slave,但是数据的同步是异步模式,该模式下即使master宕机,也只会影响很少量的数据。