likes
comments
collection
share

RocketMQ源码-从4.x到5.x

作者站长头像
站长
· 阅读数 16

前言

RocketMQ目前主要分为4.x和5.x版本,本文基于时间线分析一下每个小版本新增的feature,主要目的:

1)对于RocketMQ的发展有个整体的认知,方便之后源码学习;

2)选个合适的版本进行源码学习;

3)走读一下各个feature的主要作用,重点在于5.x,因为4.x的特性基本也都了解;

4.x版本

4.2(2017/12/13)

1. 支持ssl通讯[ROCKETMQ-28]

2. PushConsumer流控增强[ROCKETMQ-294]

原来只支持queue纬度消息数量流控,支持topic和queue纬度,包括消息数量和大小。

4.3(2018/07/24)

1. 新增基于机房rebalance策略[ISSUE-203]

AllocateMachineRoomNearby。

2. 支持事务消息[ISSUE-292]

重要功能。

4.4(2019/01/17)

1. 支持ACL访问控制[ISSUE-403]

rocketmq-acl模块。

2. PullConsumer支持SQL92过滤[ISSUE-502]

PushConsumer在4.1已经支持SQL92过滤[ROCKETMQ-121]。

3. 支持消息轨迹[ISSUE-525]

RocketMQ源码-从4.x到5.x图片来自rocketmq-dashboard,早期叫rocketmq-console-ng,和阿里云收费版控制台差不多,根据MessageID或MessageKey查询消息生产消费链路。

4.5(2019/03/29)

1. 支持broker多副本[ISSUE-1046]

broker端基于raft实现CommitLog,即DLedgerCommitlog,建立多副本。

此外,同一个BrokerName组内,通过Raft自动选主,failover。

4.6(2019/11/25)

1. 新增LitePullConsumer[ISSUE-1388]

废弃DefaultMQPullConsumer,建议使用DefaultLitePullConsumer。

支持自动rebalance,支持指定MessageQueue消费,支持通过seek和commit方法操作offset。

2. 支持IPv6[RIP-15]

3. 支持请求响应模式[RIP-16]

生产消费类似rpc调用。

RocketMQ源码-从4.x到5.x

4.7(2020/03/16)

1. SYNC_MASTER同步复制性能优化[ISSUE-1515]

4.8(2020/12/21)

1. DLedger性能优化[ISSUE-1846]

2. DLedger支持批量消息[ISSUE-690]

4.9(2021/06/15)

1. producer和consumer支持opentracing[ISSUE-2860]

2. 事务消息生产者支持消息轨迹[ISSUE-2833]

3. LitePullConsumer支持消息轨迹[ISSUE-2556]

5.x版本

5.0(2022/09/09)

1. 支持POP模式消费[RIP-19]

RocketMQ源码-从4.x到5.x

PULL模式:

Consumer通过平均分配算法rebalance,同一消费组内,每个Queue与一个Consumer实例绑定。

PULL模式缺点:

1)逻辑都在客户端,多语言支持不友好

2)如果Consumer数量大于Queue数量,部分Consumer会分配不到Queue

3)独占队列,某个Consumer机器hang住,导致消息堆积

POP模式:

Broker分配Queue给Consumer,一个Queue支持多个Consumer消费,offset由Broker管理,支持Pop和Push动态切换。

2. 支持StaticTopic和LogicalQueue[RIP-21]

原来队列和BrokerName是绑定关系,这类queue称为physical message queue,对应的topic称为dynamic sharded topic。

比如下面创建topic=aaaa,broker-a和broker-b分别创建了16个物理队列,topic下总共有32个物理队列。RocketMQ源码-从4.x到5.x

StaticTopic可以针对多个Cluster纬度或多个BrokerName纬度设置Queue的总数量。

比如下面通过updateStaticTopic命令,在DefaultCluster集群下创建TopicA,总共固定16个读写队列。

mqadmin updateStaticTopic -c DefaultCluster -t TopicA -qn 16 -n localhost:9876

这类Topic称为StaticTopic,队列称为LogicalQueue,底层LogicalQueue会映射到原来的MessageQueue。

3. 批量消息处理吞吐量优化[RIP-26]

RocketMQ源码-从4.x到5.x

原来broker端收到批消息后,会拆分成一条一条消息,放入消费队列索引ConsumeQueue,每个offset对应一个子消息,即生产批量发送,消费还是一条一条拉取。

现在支持将批消息直接放入批消费队列索引BatchConsumeQueue,一个批消息对应一个offset。

4. 支持BrokerContainer[RIP-31]

一般情况下,一个机器部署一个broker进程,但是由于broker角色不同,比如slave相较于master资源利用率低。

新增rocketmq-container模块,BrokerContainer负责启动多个broker。

支持一个进程中包含多个broker,比如一个进程中包含一个master一个slave。

也支持DLedgerBroker(4.5的那个)。

RocketMQ源码-从4.x到5.x

5. 支持Slave Acting Master[RIP-32]

当Master下线后,同组最小id的Slave顶替Master,承担更多职责。

代理Slave下的Queue被设置为只读,即仅能提供给消费者使用。

消费者能自动重连到代理Slave进行消费。

当Master上线后,先从代理Slave同步数据,然后向NameServer注册。

6. master-slave架构下支持quorum写和自适应降级[RIP-34]

支持quorum写

这个特性和kafka很像,对应kafka的min.insync.replicas配置项。

原来如果master是同步复制,必须要所有slave都写成功,才能响应客户端成功;

如果master是异步复制,只要master写入成功,就响应客户端成功。

同步和异步复制是两个极端,quorum写特性,支持设置一个副本组写入inSyncReplicas个副本成功后,响应客户端成功。

我这里看文档,默认情况下,inSyncReplicas=1,即5.0同步复制quorum写只需要写入一个副本就成功。

所以可能要设置quorum数量为副本组所有副本数量才能和原来的ASYNC_MASTER语义保持一致。

支持自适应降级

默认关闭。

如果副本组中,部分slave无法追上master的进度,支持降级quorum到一个minInSyncReplicas副本数量。

7. 支持gRPC协议[RIP-39]

RocketMQ支持gRPC协议分为两部分。

第一部分是服务端,新增rocketmq-proxy模块,即gRPC Server。

rocketmq-proxy支持两种部署模式。

RocketMQ源码-从4.x到5.x

LOCAL模式,gRPC Server和Broker部署在一个进程里,通过rocketmq-proxy包装rocketmq-broker模块启动。

CLUSTER模式,计算与存储分离,gRPC Server单独部署一套无状态集群,Broker专门负责存储。

第二部分是客户端,客户端不在rocketmq这个主项目中,而是在rocketmq-clients这个项目中,里面包含各种语言的gRPC客户端。

8. 支持任意时间的延迟消息[RIP-43]

5.0以前,延迟消息只能指定延迟级别,默认从1秒到2小时,可以通过修改broker配置支持更多延迟级别。

messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

5.0基于时间轮实现任意时间延迟消息,默认开启,producer在Message的properties中可以设置。

RocketMQ源码-从4.x到5.x

9. master-slave架构下支持DLedger Controller[RIP-44]

4.5提出的DLedger模式,在5.0开始简称DLedgerBorker

DLedgerBorker在存储上无法使用零拷贝能力,底层基于Raft必须部署三副本,至少过半ack才能返回。

总而言之,无法像master-slave一样异步复制,也无法使用零拷贝,还有很多维护上的困难。

5.0将DLedger上移,新增rocketmq-controller模块,提供DLedgerController

DLedgerController支持broker组自动master-slave切换,有两种部署模式。

内嵌NameServer部署

NameServer本身还是无状态的,只是把DLedgerController放到NameServer一个进程里部署。

RocketMQ源码-从4.x到5.x

独立部署:DLedgerController独立进程部署。

5.1(2023/02/16)

1. 可观测性提升[RIP-46]

仅针对metrics,和tracing、logging无关。

早期版本提供了rocketmq-exporter项目负责从broker拉取metrics暴露给prometheus。

rocketmq-exporter需要独立部署,不方便;

rocketmq-exporter通过mqadmin从broker拉取metrics,给broker带来额外压力;

rocketmq-exporter对于metrics的命名有歧义;

rocketmq-exporter仅支持broker,而5.x新增了很多可以独立部署的模块;

新版本提供开箱即用的metrics,在broker/proxy/controller内部。

2. 服务端offset管理增强[RIP-48]

1)广播消费offset管理增强

广播消费者的offset是在本地自己管理的。

原来,如果广播消费者重启后没有offset文件,将从最大offset开始消费,重启过程中的消息将会丢失。

增强后,服务端可以提供消费组中所有消费实例中最小的offset,供广播消费者重启后使用。

2)ConsumeProgress命令返回不精确

原来broker只会记录offset被ack的状态,现在提出两个新状态:

ready状态,message已经准备就绪(进入ConsumeQueue),可以被消费者消费,但是还未被consumer拉取。

inflight状态,message已经被consumer拉取,但是还未收到consumer的ack。

这个和rabbitmq又很像,ready对应ready,inflight对应unacked。

RocketMQ源码-从4.x到5.x

3)server端重置offset

大概意思是现在设置offset的地方太多了,容易并发修改异常,然后做了一些优化?

3. remoting模块优化[RIP-49]

Server反压优化、日志优化、部分特殊网络情况下,Client需要通过proxy连接Server。

4. 事务消息优化[RIP-50]

1)支持批op消息,一个批op消息对应多个半消息;

2)异步刷盘情况下,如果半消息之后马上收到commit/rollback,有可能commit/rollback失败,原因是半消息还未刷盘不可读,这个版本内存中缓存半消息;

5. POP顺序消费优化[RIP-51]

这里说到两个优化点。

一点是pop顺序消费不支持设置invisibleTime,和消费重试相关。

另一点是pop顺序消费没有消息通知机制,客户端长轮询无法及时被唤醒,导致消费延迟。

6. 消费队列索引构建优化[RIP-52]

broker端收到消息后,将消息写入commitLog,然后异步单线程构建消费队列ConsumeQueue。

说是消息多的时候,单线程构建ConsumeQueue存在性能瓶颈。

新版本将构建ConsumeQueue拆分为运算操作和io操作。

前者采用多线程,后者写ConsumeQueue还是单线程顺序写。

7. rocketmq-proxy支持remoting协议[RIP-55]

5.0,为了支持gRPC协议,新增rocketmq-proxy模块。

5.1,rocketmq-proxy支持原来RocketMQ自己的私有协议,即remoting协议。

8. 支持多级存储[RIP-57]

对传统基于CommitLog存储的方式提出几个问题:

1)CommitLog仅支持文件的固定保留时间(fileReservedTime=72小时),想支持Topic级别的保留时间;

2)MessageStore存储层面仅支持同步读消息的api,当消息不在pagecache时,工作线程会阻塞读,然后堵住其他请求,想做冷热数据分离并提供异步api;

3)想在减少集群大小时,不丢失历史数据,将消息卸载到其他存储介质中;

然后提供了新的MessageStore实现TieredMessageStore。

RocketMQ源码-从4.x到5.x

选版本

从使用角度来说,4.x和5.x各选最高的没什么问题,bug少,特性多,性能好。

从读源码角度来说,我选4.6,因为:

1)5.x版本复杂度非常高,虽然有很多新特性,但是很多if-else和class实现默认情况下是不会进的;

2)4.9是可观测性的提升,大概率是一些埋点逻辑,可以暂时忽略;

3)4.7和4.8是性能优化,大概率代码会更复杂,不利于分析主干逻辑;

3)4.6版本已经基本满足了业务诉求,且代码逻辑应该相对更加清晰,容易上手;

4.6看完之后,再分析5.x的部分特性。

总结

本文梳理了一下RocketMQ各个小版本中的新特性。

重点分析了一下5.x的新特性,5.0的很多概念几乎是颠覆性的。

POP消费:rebalance不在consumer端,broker负责consumer负载均衡,队列非独占。

Slave Acting Master:Master下线支持Slave代理Master提供消费能力。

延迟消息:支持任意时间,不仅限于messageDelayLevel延迟级别。

quorum写:不再是完全同步复制或完全异步复制,支持按照inSyncReplicas副本数半同步复制。

DLedgerController:区别于4.5的DLedgerBroker,在master-slave架构下支持自动master-slave切换。

参考文档

  1. RocketMQ Improvement Proposal:github.com/apache/rock…
  2. RocketMQ Release Notes:rocketmq.apache.org/release-not…
转载自:https://juejin.cn/post/7244708523962908709
评论
请登录