RocketMQ从2022年9月份开始推出了新的5.x大版本。相比于之前的4.x版本,5.x版本向云原生前进了一大步。在增强原因功能的基础上,更是支持多语言客户端,周边生态也进行了补强和完善,明显可以看到离Kafka老大哥又近了很大一步。
在服务部署方面,5.x新版本进一步靠近云原生。将各种复杂功能进一步化整为零,通过更灵活的服务组合,提升整体性能。
Proxy组件主要是为了兼容多语言客户端(c/c++, golang, csharp,rust,python, nodejs)。如果还是使用的Java客户端,则不需要启动Proxy。
Proxy组件部署分为两种模式,Local模式以及Cluster模式。其中,Local模式就是随Broker一起部署。 部署方式是在执行bin/mqbroker脚本启动Broker时,增加–enable-proxy参数。Cluster模式则是与Broker分开部署。部署方式是在启动Broker时不要添加–enable-proxy参数,而通过执行bin/mqproxy脚本单独启动Proxy服务。通过-n参数执行NameServer即可。如果需要定制配置项,可以通过添加-pc或者–proxyConfigPath参数指定一个单独的JSON配置文件。目前5.1.0版本中,这个配置文件还没有什么配置项,只有一个rocketMQClusterName属性指定对应的Broker集群的名字。
在之前的4.x版本中,如果需要搭建具备自动主从切换的高可用集群,是需要搭建Dledger集群的,对应发布版本的conf/dledger下的配置文件。这种模式在5.x版本中依然可以使用,不过,5.x版本增加了一种更轻量级进行主从切换的方式,那就是Controller组件。
4.x版本中Dledger集群对RocketMQ的影响包含两个方面,一方面是通过集群选主,支持主从切换,另一方面就是接管RocketMQ的CommitLog日志文件读写。而Controller的作用就是将集群选主功能单独提取出来,提供主从切换的高可用功能。使用Controller组件后,RocketMQ就可以使用自己原有的日志读写机制搭建高可用集群,这样可以更好的用上RocketMQ原生的文件读写功能。未来应该会是RocketMQ集群搭建的主流方式。
Controller也有两种部署方式,可以嵌入到NameServer中运行,也可以单独部署运行。
示例配置:
enableControllerInNamesrv = true controllerDLegerGroup = group1 controllerDLegerPeers = n0-127.0.0.1:9877;n1-127.0.0.1:9878;n2-127.0.0.1:9879 controllerDLegerSelfId = n0 controllerStorePath = /home/admin/DledgerController enableElectUncleanMaster = false notifyBrokerRoleChanged = true
Controller相关配置参数如下:
- enableControllerInNamesrv:Nameserver 中是否开启 controller,默认 false。
- controllerDLegerGroup:DLedger Raft Group 的名字,同一个 DLedger Raft Group 保持一致即可。
- controllerDLegerPeers:DLedger Group 内各节点的端口信息,同一个 Group 内的各个节点配置必须要保证一致。
- controllerDLegerSelfId:节点 id,必须属于 controllerDLegerPeers 中的一个;同 Group 内各个节点要唯一。
- controllerStorePath:controller 日志存储位置。controller 是有状态的,controller 重启或宕机需要依靠日志来恢复数据,该目录非常重要,不可以轻易删除。
- enableElectUncleanMaster:是否可以从 SyncStateSet 以外选举 Master,若为 true,可能会选取数据落后的副本作为 Master 而丢失消息,默认为 false。
- notifyBrokerRoleChanged:当 Broker 副本组上角色发生变化时是否主动通知,默认为 true。
接下来,在启动Broker服务时,如果想要使用Controller,则需要在Broker配置文件中加入:enableControllerMode=true以及controllerAddr 两个核心配置。这样Broker集群就可以具备自动选主的功能。
但是要注意:如果部署了Controller服务,Broker端不开启Controller,这是可以正常运行的,只不过Broker集群不具备自动选主的功能。但是如果反过来,Broker端开启Controller,但是没有部署Controller服务,这样Broker服务就无法正常启动。
Broker中与Controller相关的配置参数如下:
- enableControllerMode:Broker controller 模式的总开关,只有该值为 true,自动主从切换模式才会打开。默认为 false。
- controllerAddr:controller 的地址,多个 controller 中间用分号隔开。例如
controllerAddr = 127.0.0.1:9877;127.0.0.1:9878;127.0.0.1:9879
- syncBrokerMetadataPeriod:向 controller 同步 Broker 副本信息的时间间隔。默认 5000(5s)。
- checkSyncStateSetPeriod:检查 SyncStateSet 的时间间隔,检查 SyncStateSet 可能会 shrink SyncState。默认5000(5s)。
- syncControllerMetadataPeriod:同步 controller 元数据的时间间隔,主要是获取 active controller 的地址。默认10000(10s)。
- haMaxTimeSlaveNotCatchup:表示 Slave 没有跟上 Master 的最大时间间隔,若在 SyncStateSet 中的 slave 超过该时间间隔会将其从 SyncStateSet 移除。默认为 15000(15s)。
- storePathEpochFile:存储 epoch 文件的位置。epoch 文件非常重要,不可以随意删除。默认在 store 目录下。
- allAckInSyncStateSet:若该值为 true,则一条消息需要复制到 SyncStateSet 中的每一个副本才会向客户端返回成功,可以保证消息不丢失。默认为 false。
- syncFromLastFile:若 slave 是空盘启动,是否从最后一个文件进行复制。默认为 false。
- asyncLearner:若该值为 true,则该副本不会进入 SyncStateSet,也就是不会被选举成 Master,而是一直作为一个 learner 副本进行异步复制。默认为false。
- inSyncReplicas:需保持同步的副本组数量,默认为1,allAckInSyncStateSet=true 时该参数无效。
- minInSyncReplicas:最小需保持同步的副本组数量,若 SyncStateSet 中副本个数小于 minInSyncReplicas 则 putMessage 直接返回 PutMessageStatus.IN_SYNC_REPLICAS_NOT_ENOUGH,默认为1。
最后,官方也列了个表格,展示了新版本的Controller功能与4.x旧版本的NameServer和Broker组合会是什么情况。就做做参考好了。
旧版 Nameserver | 旧版 Nameserver+独立部署 Controller | 新版 Nameserver 开启 controller功能 | 新版 Nameserver 关闭 controller 功能 | |
---|---|---|---|---|
旧版 Broker | 正常运行,无法切换 | 正常运行,无法切换 | 正常运行,无法切换 | 正常运行,无法切换 |
新版 Broker 开启 Controller 模式 | 无法正常上线 | 正常运行,可以切换 | 正常运行,可以切换 | 无法正常上线 |
新版 Broker 不开启 Controller 模式 | 正常运行,无法切换 | 正常运行,无法切换 | 正常运行,无法切换 | 正常运行,无法切换 |
在RocketMQ 4.x 版本中,一个进程只有一个broker,通常会以主备或者DLedger(Raft)的形式部署,但是一个进程中只有一个broker,而slave一般只承担冷备或热备的作用,节点之间角色的不对等导致slave节点资源没有充分被利用。
因此在RocketMQ 5.x 版本中,提供一种新的模式BrokerContainer,在一个BrokerContainer进程中可以加入多个Broker(Master Broker、Slave Broker、DLedger Broker),来提高单个节点的资源利用率,并且可以通过各种形式的交叉部署来实现节点之间的对等部署。
部署方式是调用bin/mqbrokercontainer脚本,并通过-c参数指定配置文件即可。
sh bin/mqbrokercontainer -c broker-container.conf
在配置文件中可以指定多个Broker的配置文件,作为一个整体一起执行。例如
#配置端口,用于接收mqadmin命令
listenPort=10811
#指定namesrv
namesrvAddr=127.0.0.1:9876
#或指定自动获取namesrv
fetchNamesrvAddrByAddressServer=true
#指定要向BrokerContainer内添加的brokerConfig路径,多个config间用“:”分隔;
#不指定则只启动BrokerConainer,具体broker可通过mqadmin工具添加
brokerConfigPaths=/home/admin/broker-a.conf:/home/admin/broker-b.conf
整体来看,5.x新版本的功能组件拆分更加分散,而部署的组合也更加灵活,随时可以优化资源配置,设计更合适的部署方案。但是我觉得另一方面也加大了服务部署的门槛。结合Docker或者虚拟化技术会更加好用。
你对Docker不熟?也不用担心,RocketMQ也推出了一个仓库,专门介绍如何结合Docker以及K8s使用RocketMQ。Git仓库地址: https://github.com/apache/rocketmq-docker 有兴趣的可以去看看。