2.6、总结
其实就是如下几个关键配置需要注意:
- brokerClusterName:集群名称,所有broker配置的必须一致
- brokerName:broker名称,M-S之间必须一致,比如broker-a/broker-a(M/S),broker-b/broker-b
- brokerId:0 表示 Master,>0 表示 Slave,比如1M2S,那么M是0,Slave1是1,Slave2配置为2
- namesrvAddr:namesrv地址
- store*:持久化数据存储目录
- brokerRole:Broker的角色
- flushDiskType:刷盘方式,2m2s-sync中,master默认为SYNC_FLUSH,slave默认为ASYNC_FLUSH
2.7、启动
2.7.1、启动namesrv
cd /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/bin nohup sh mqnamesrv &
两台机器都要启动。
2.7.2、启动broker
172.17.160.28
cd /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/bin # 启动Master1 nohup sh mqbroker -c /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/conf/2m-2s-sync/broker-a.properties & # 启动Slave2 nohup sh mqbroker -c /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/conf/2m-2s-sync/broker-b-s.properties &
172.17.160.29
cd /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/bin # 启动Master2 nohup sh mqbroker -c /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/conf/2m-2s-sync/broker-b.properties & # 启动Slave1 nohup sh mqbroker -c /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/conf/2m-2s-sync/broker-a-s.properties &
2.8、验证
直接打开我们的管控台进行查看集群(Cluster)
2.9、问题
他致命的问题就是不能自动主备切换,比如我杀死broker-a-master的进程,然后看管控台broker-a-slave是否会自动升级为master,发现并不会。所以我们的Dledger诞生了。
# 找到broker-a-master的进程号是8983 kill -9 8983
3、Dledger搭建
3.1、说明
是基于raft的一种做法,redis的哨兵也是基于raft的,和这个是一样的道理。上面【古老的集群搭建】方式并不作废,Dledger就是基于上面的继续增加额外配置,上面的配置依然保留,继续追加新的配置即可。Dledger要求机器数必须是3台或3台以上才行。这也是raft的基础要求。不懂的可以自行Google下raft。
3.2、搭建
3.2.1、官方搭建手册
https://github.com/apache/rocketmq/blob/master/docs/cn/dledger/deploy_guide.md
3.2.2、准备
我们多开一台虚拟机:172.17.160.30,采取Dledger搭建一组1M2S的集群,机器规划如下:
机器 | 用途 |
172.17.160.28 | namesrv、broker-a-master |
172.17.160.29 | namesrv、broker-a-slave1 |
172.17.160.30 | namesrv、broker-a-slave2 |
3.2.3、配置
上面的【古老的集群搭建】配置不变,在每个properties里新增如下配置:
172.17.160.28
enableDLegerCommitLog=true dLegerGroup=broker-a dLegerPeers=n0-172.17.160.28:40911;n1-172.17.160.29:40911;n2-172.17.160.30:40911 dLegerSelfId=n0 sendMessageThreadPoolNums=4
172.17.160.29
enableDLegerCommitLog=true dLegerGroup=broker-a dLegerPeers=n0-172.17.160.28:40911;n1-172.17.160.29:40911;n2-172.17.160.30:40911 dLegerSelfId=n1 sendMessageThreadPoolNums=4
172.17.160.30
enableDLegerCommitLog=true dLegerGroup=broker-a dLegerPeers=n0-172.17.160.28:40911;n1-172.17.160.29:40911;n2-172.17.160.30:40911 dLegerSelfId=n2 sendMessageThreadPoolNums=4
3.2.4、配置说明
name | 含义 | 举例 |
enableDLegerCommitLog | 是否启动 DLedger | true |
dLegerGroup | DLedger Raft Group的名字,建议和 brokerName 保持一致 | broker-a |
dLegerPeers | DLedger Group 内各节点的端口信息,同一个 Group 内的各个节点配置必须要保证一致 | n0-172.17.160.28:40911;n1-172.17.160.29:40911;n2-172.17.160.30:40911 |
dLegerSelfId | 节点 id, 必须属于 dLegerPeers 中的一个;同 Group 内各个节点要唯一 | n0 |
sendMessageThreadPoolNums=4 | 发送消息的线程数,建议与CPU核数设置成一样的 | 4 |
3.2.5、启动
启动三台的namesrv和三个broker,跟上面姿势一样,不重复贴代码了。
3.2.6、验证
管控台去看的话应该是1个master,两个slave,都叫broker-a,这时候停掉master,会发现其中一个slave自动升级为Master了,这才叫真正的高可用,自动主备切换。
3.3、补充
虽然要求至少三台机器,但是没条件的可以用一台机器去模拟,弄三个不同的端口号就行了。
三、常见问题
1、Lock failed,MQ already started
1.1、错误
[root@iZ2ze84zygpzjw5bfcmh2hZ 2m-2s-sync]# sh ../../bin/mqbroker -c broker-b-s.properties java.lang.RuntimeException: Lock failed,MQ already started at org.apache.rocketmq.store.DefaultMessageStore.start(DefaultMessageStore.java:223) at org.apache.rocketmq.broker.BrokerController.start(BrokerController.java:853) at org.apache.rocketmq.broker.BrokerStartup.start(BrokerStartup.java:64) at org.apache.rocketmq.broker.BrokerStartup.main(BrokerStartup.java:58)
1.2、解决
这个是由于没配置store*导致的,比如如下:
#存储路径 storePathRootDir=/home/chentongwei/data/rocketmq/broker-a/store #commitLog 存储路径 storePathCommitLog=/home/chentongwei/data/rocketmq/broker-a/store/commitlog #消费队列存储路径存储路径 storePathConsumeQueue=/home/chentongwei/data/rocketmq/broker-a/store/consumequeue #消息索引存储路径 storePathIndex=/home/chentongwei/data/rocketmq/broker-a/store/index #checkpoint 文件存储路径 storeCheckpoint=/home/chentongwei/data/rocketmq/broker-a/store/checkpoint #abort 文件存储路径 abortFile=/home/chentongwei/data/rocketmq/broker-a/store/abort
没配置这个,我一台机器上部署两个broker,一个broker-a-master,一个broker-b-slave,都采取默认的store*配置,冲突了,所以报错。所以手动配上不同目录即可,我这里目录区分是broker-a/broker-b。
2、AllocateMappedFileService started:false lastThread:null
这个是由于store*配置的都一样导致的,比如如下:
#存储路径 storePathRootDir=/home/chentongwei/data/rocketmq/broker-a/store #commitLog 存储路径 storePathCommitLog=/home/chentongwei/data/rocketmq/broker-a/store #消费队列存储路径存储路径 storePathConsumeQueue=/home/chentongwei/data/rocketmq/broker-a/store #消息索引存储路径 storePathIndex=/home/chentongwei/data/rocketmq/broker-a/store #checkpoint 文件存储路径 storeCheckpoint=/home/chentongwei/data/rocketmq/broker-a/store #abort 文件存储路径 abortFile=/home/chentongwei/data/rocketmq/broker-a/store
发现了没?我都用的/home/chentongwei/data/rocketmq/broker-a/store
,这肯定不行的,所以我们需要采用不同目录,比如store/commitlog
、store/consumequeue
等。
3、Address already in use
这个更神奇了,见名知意,地址被占用了。也就是端口被占用了。我为什么说他更神奇,不是因为我没配置listenPort,而是我在单台机器上配置了broker-a-master的端口为默认端口10911,broker-b-slave的端口为10912,就是+1操作了。他为啥说我被占用?
经过查源码发现,他大爷的,他给我默认启动了一个进程,端口号就是配置的端口+1,所以启动一个broker后他其实是给我们启动了两个端口,一个原端口,一个原端口+1。所以我配置的时候一个是10911,一个是11911,而不能 是10912!!!
#Broker 对外服务的监听端口 listenPort=11911
源码如下:
// {@link org.apache.rocketmq.broker.BrokerStartup#createBrokerController(String[])} messageStoreConfig.setHaListenPort(nettyServerConfig.getListenPort() + 1);
4、管控台配置namesrv
如果namesrv和broker都启动正常后,管控台上还是没有集群的话,可以检查下管控台是否配置了namesrv
这个namesrv配置需要手动敲完后+回车+点击UPDATE才能生效。
END