消息队列-Metaq(RocketMQ)原理

1.      应用场景

适用于大存储量,顺序消息,广播和日志数据传输的场景。设计理念类似kafka,场景类似。和kafak的一些差异如下,可以考虑差异使用:

  • 文本协议设计,透明。纯java实现,kafka是scala实现。
  • 提供事务支持,包括本地事务和XA分布式事务。Kakfa不支持分布式事务
  • 支持HA复制,包括异步复制和同步复制,保证消息的可靠性。Kafka也都支持。支持同步和异步刷盘,kakfa只支持异步
  • 多种offset存储支持,Kafka是zookeeper。
  • 需要大量的topic,kafka对多topic的性能影响比较大,而metaq相对较好。
  • 实时性要求比较高。
  • 消息局部有序,基于partition顺序消费。但如果consumer有多线程会出现乱序。

 

2.      产品特性

因为metaq主要实现和kafka原理相似,产品特性可以参考kafak,这里主要列出两个产品的差异点:

功能

特性

Kafka

Metaq

备注

数据可靠性

刷盘和复制

异步刷盘

同步异步复制

同同步异步复制步异步刷屏

 

性能对比

写入速度

100w/s

7w/s

Kafka合并小数据批量发送

单机队列数

队列或分区数

5w/分区或队列

64/分区或队列

 

实时性

消息投递

Kafka使用短轮询方式,实时性取决于轮询间隔时间。0.8版本以上已经支持长轮询

使用长轮询,同Push方式实时性一致

 

消费失败重试

 

支持固定时间重试,需要配置

支持定时重试,每次重试间隔时间顺延

 

定时/延时消息

 

不支持

支持

 

分布式事务

 

不支持

支持

 

消息查询

 

不支持

支持根据Message Id查询消息,也支持根据消息内容查询消息(发送消息时指定一个Message Key,任意字符串,例如指定为订单Id

 

消息回溯

 

Offset回溯

支持按照时间来回溯消息,精度毫秒

 

消费并行度

 

依赖与分区数

顺序模式:依赖分区数

乱序模式:取决与conusmer的线程数

 

消息轨迹

 

不支持

支持

 

Broker端消息过滤

 

不支持

基于tags过滤

支持上传代码过滤

 

消息堆积能力

 

更强

理论上都够用

 

3.      逻辑架构
消息队列-Metaq(RocketMQ)原理_第1张图片

  • 支持发布订阅模式
  • 消息类型是message

4.      存储架构
消息队列-Metaq(RocketMQ)原理_第2张图片
消息队列-Metaq(RocketMQ)原理_第3张图片

 

  • 消息持久存储
  • metaq 将消息存储在本地文件中,每个文件最大大小为 1G,如果写入新的消息时,超过当前文件大 小,则会自动新建一个文件。文件名称为起始字节大小 。
  • 即使一个 broker 为多个 topic 服务,这些 topic 的消息都存储同一个文件组中,消息顺序写入,永远 都是当前文件在写,其他文件只读
  • broker 将消息存储到文件后,会将该消息在文件的物理位置,消息大小,消息类型封装成一个固定大 小的数据结构,暂且称这个数据结构为索引单元吧,大小固定为 16k,消息在物理文件的位置称为 offset。
  • 多个索引单元组成了一个索引文件,索引文件默认固定大小为 20M,和消息文件一样,文件名是 起始字节位置,写满后,产生一个新的文件。
  • 由于meta把kafka中一个partion一个文件夹的思路,转变成了多个partition共享一个文件,实现真正的顺序写。所以可以支持更多的topic和partition。

 

5.      处理流程
消息队列-Metaq(RocketMQ)原理_第4张图片
消息队列-Metaq(RocketMQ)原理_第5张图片

  • 处理数据流程:
    • 根据 topic 和 partition 找到逻辑队列:A 

    • 根据 offset 从 A 定位指定的索引文件:B 

    • 从 B 中读取所有的索引数据:C 

    • 遍历 C,根据索引单元的消息物理地址和消息长度,找到物理消息 D,将 D 放入集合,并计 
算消息的累加长度,若大于请求里消息最大长度 maxSize,则终止遍历,返回结果。 

  • 生产者的数据直接写入磁盘。(有可能在os的缓存中)。通过同步策略刷新进磁盘。

6.      分布架构

  • 由于异步复制导致slave数据的可能缺失。写入必须通过master,读取可以slave。
  • 也可以把slave升级为maste。当maste重启后变为salve。默认实现。

7.      zookeeper架构

  • ids
    • /meta/brokers/ids/m1/master
    • /meta/brokers/ids/m1/slaves1
    • /meta/brokers/ids/m1/slaves2

  • topics
    • meta/brokers/topics/hello/m1-m
    • /meta/brokers/topics/hello/m2-m
    • /meta/brokers/topics/hello/s1-s
    • /meta/brokers/topics/hello/s2-s
  • partion数据存储在节点的数据中
  • 分组信息存储
    • /meta/consumers/hellogroup/ids/hellogroup_c1 节点数据为“hello1,hello2”
    • /meta/consumers/hellogroup/ids/hellogroup_c2 节点数据为"hello2,hello3"
  • 分组消费的位置存储
    • /meta/consumers/hellogroup/offsets/t1/b1-1数据为 1 。
    • /meta/consumers/hellogroup/offsets/t1/b1-2数据为 2 。
    • /meta/consumers/hellogroup/offsets/t1/b2-1数据为 3 。
    • /meta/consumers/hellogroup/offsets/t1/b2-2数据为 4 。

group 和 topic 是变量,以实际值为准。t,b分别为topic,broker,数字为位置。

8.      性能评估

Kafka单机写入TPS约在百万条/秒,消息大小10个字节。RocketMQ单机写入TPS单实例约7万条/秒,单机部署3个Broker,可以跑到最高12万条/秒,消息大小10个字节。Kafka的TPS跑到单机百万,主要是由于Producer端将多个小消息合并,批量发向Broker。

Metaq为什么没有进行合并发送:

  • Producer通常使用Java语言,缓存过多消息,GC是个很严重的问题
  • Producer调用发送消息接口,消息未发送到Broker,向业务返回成功,此时Producer宕机,会导致消息丢失,业务出错
  • Producer通常为分布式系统,且每台机器都是多线程发送,我们认为线上的系统单个Producer每秒产生的数据量有限,不可能上万。
  • 缓存的功能完全可以由上层业务完成。

    Topic数的增加对RocketMQ无影响,长时间运行服务非常稳定。Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长。RocketMQ单机支持最高5万个队列,Load不会发生明显变化。

 

阿里云招聘,欢迎技术大牛加入:[email protected]

你可能感兴趣的:(消息队列-Metaq(RocketMQ)原理)