前言
本文介绍如何使用DLedger搭建RocketMQ集群,并实现数据的高可用和负载均衡。主要包括搭建DLedger集群、配置RocketMQ Broker以使用DLedger作为存储、创建Topic等步骤。
什么是RocketMQ-DLedger集群
- 引用官方说法如下:
RocketMQ-on-DLedger Group 是指一组相同名称的 Broker,至少需要 3 个节点,通过 Raft 自动选举出一个 Leader,其余节点 作为 Follower,并在 Leader 和 Follower 之间复制数据以保证高可用。
RocketMQ-on-DLedger Group 能自动容灾切换,并保证数据一致。
RocketMQ-on-DLedger Group 是可以水平扩展的,也即可以部署任意多个 RocketMQ-on-DLedger Group 同时对外提供服务。
- 根据网上搜索的资料,之前官方的集群方案(主从方案)一旦主节点挂掉,那么需要手动将Slave节点改为Master节点并重新启动,才能恢复。而DLedger集群可以通过自动选举的方式选举出Master节点,当任意一个Master挂掉之后,程序会自动选举新的Master替换为主节点。
PS:同一组RocketMQ-Dledger集群至少需要3个节点,如果只有2个节点,当Master节点挂掉后,由于得不到过半选票,Slave节点不会切换为Master节点。
同一个集群可部署多个 Broker,同时提供服务。
宿主机搭建
参考官方文档,写的很详细,包括如何将旧机群转换为新集群。此处不再描述。
Docker容器搭建
-
使用Docker环境搭建,有个坑,如果采用默认的Bridge网络模式,搭建完成后可能会出现集群异常,报
org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to <172.17.0.11:10911> failed
异常,控制台无法连接RocketMQ节点问题。此处猜测为采用bridge网络后,broker内会使用容器内部IP,导致使用到内部IP无法正常连接。具体如下图
因此,我采用了host模式进行搭建,直接共享宿主机网卡。如有其他搭建方式欢迎分享出来一起学习~
方式一
准备工作
-
到 官方Release下载二进制文件,如
rocketmq-all-4.9.1.zip
-
解压文件,在
conf/dledger/
文件夹下找到三个配置文件,分别为broker-n0.conf
、broker-n1.conf
、broker-n2.conf
-
修改配置文件
- namesrvAddr:修改成nameserver地址,如
172.16.0.4:9876;172.16.0.17:9876;172.16.0.14:9876
- storePathRootDir:根据实际需要修改为存储路径地址
- storePathCommitLog:根据实际需要改成commitlog存储路径地址
- enableDLegerCommitLog:是否启动 DLedger,填
true
- dLegerPeers:各节点端口信息,如
n0-127.0.0.1:40911;n1-127.0.0.1:40912;n2-127.0.0.1:40913
- sendMessageThreadPoolNums:发送线程个数,建议配置成 CPI 核数,4核填4,8核填8,以此类推
- dLegerSelfId:节点 id,同一个Group中必须唯一
brokerClusterName = RaftCluster brokerName=RaftNode00 #listenPort=30911 namesrvAddr=127.0.0.1:9876 storePathRootDir=/tmp/rmqstore/node00 storePathCommitLog=/tmp/rmqstore/node00/commitlog enableDLegerCommitLog=true dLegerGroup=RaftNode00 dLegerPeers=n0-127.0.0.1:40911;n1-127.0.0.1:40912;n2-127.0.0.1:40913 ## must be unique dLegerSelfId=n0 sendMessageThreadPoolNums=16
- namesrvAddr:修改成nameserver地址,如
-
假设我现在有三台机器,内网IP分别为:
172.16.0.4,172.16.0.17,172.16.0.14
则对应的配置文件为:
brokerClusterName = RaftCluster brokerName=RaftNode00 #listenPort=30911 namesrvAddr=172.16.0.4:9876;172.16.0.17:9876;172.16.0.14:9876 storePathRootDir=/opt/data/ storePathCommitLog=/opt/data/commitlog enableDLegerCommitLog=true dLegerGroup=RaftNode00 dLegerPeers=n0-172.16.0.4:40911;n1-172.16.0.17:40911;n2-172.16.0.14:40911 ## must be unique dLegerSelfId=n0 sendMessageThreadPoolNums=4
PS:除了
dLegerSelfId
需要调整,其他节点配置都一样。
启动容器
-
启动带有JDK环境的容器镜像,通过解压安装包后手动执行启动脚本的方式启动
需提前将解压并修改配置文件后的
rocketmq-4.9.1
文件夹分别传到3台服务器上。cname="rocketmq-node1" logs="/opt/data/"${cname} docker run -d --privileged=true --restart=always -v /opt/script/setup/rocketmq-node1/rocketmq-4.9.1/:/usr/local/rocketmq-4.9.1/ --net=host --name ${cname} -v ${logs}:/opt/data 10.252.0.29:5000/base/jdk:v19.01.01
启动NameServer
进入docker容器,进入RocketMQ文件夹的bin
目录下,执行以下命令
nohup ./mqnamesrv > /opt/data/namesrv.log 2>&1 &
/opt/data/namesrv.log
为后台运行的日志路径
根据实际情况,可以启动多个NameServer做高可用
启动Broker
进入docker容器,进入RocketMQ文件夹的bin
目录下,执行以下命令
节点1:
nohup sh mqbroker -c /usr/local/rocketmq-4.9.1/conf/dledger/broker-n0.conf > /opt/data/broker.log 2>&1 &
节点2:
nohup sh mqbroker -c /usr/local/rocketmq-4.9.1/conf/dledger/broker-n1.conf > /opt/data/broker.log 2>&1 &
节点3:
nohup sh mqbroker -c /usr/local/rocketmq-4.9.1/conf/dledger/broker-n2.conf > /opt/data/broker.log 2>&1 &
/opt/data/broker.log
为后台运行的日志路径
- 可通过修改
bin
目录下的runbroker.sh
文件,调整启动占用的内存大小!
方式二
准备工作
-
打包rocketmq镜像
-
到rocketmq-docker的GitHub地址克隆docker脚本
-
执行以下命令开始制作docker镜像
cd image-build sh build-image.sh RMQ-VERSION BASE-IMAGE
RMQ-VERSION可以在官方查看
BASE-IMAGE可以为centos或alpine
例子:sh build-image.sh 4.9.2 centos
-
制作成功后会获得如下镜像:apacherocketmq/rocketmq:4.9.2
-
-
打包rockermq-dashboard镜像
前提:依赖上面拉取的docker脚本
cd image-build sh build-image-dashboard.sh VERSION centos
VERSION可以在官方查看
例子:sh build-image-dashboard.sh 1.0.0 centos
成功后获得如下镜像:apache/rocketmq-dashboard:1.0.0-centos
-
准备broker配置文件
-
在三台机器分别创建以下目录
-
创建Broker持久化目录
mkdir -p /opt/data/rocketmq-{n}/broker/conf mkdir -p /opt/data/rocketmq-{n}/broker/logs mkdir -p /opt/data/rocketmq-{n}/broker/store
-
创建NameServer持久化目录
mkdir -p /opt/data/rocketmq-{n}/nameserver/logs
{n}填写第n个节点的数字,如:mkdir -p /opt/data/rocketmq-01/broker/conf
也可以不需要,根据自己需求决定
-
-
创建配置文件
-
节点1
vim /opt/data/rocketmq-01/broker/conf
写入以下内容
brokerIP1=172.16.32.73 listenPort=30911 brokerClusterName=RaftCluster brokerName=RaftNode00 namesrvAddr=172.16.32.73:9876;172.16.32.54:9876;172.16.32.86:9876 ## DLeger dLegerSelfId=n0 dLegerGroup=RaftNode00 enableDLegerCommitLog=true ## must be unique dLegerPeers=n0-172.16.32.73:40911;n1-172.16.32.54:40911;n2-172.16.32.86:40911 sendMessageThreadPoolNums=4
-
节点2
vim /opt/data/rocketmq-02/broker/conf
写入以下内容
brokerIP1=172.16.32.54 listenPort=30911 brokerClusterName=RaftCluster brokerName=RaftNode00 namesrvAddr=172.16.32.73:9876;172.16.32.54:9876;172.16.32.86:9876 ## DLeger dLegerSelfId=n1 dLegerGroup=RaftNode00 enableDLegerCommitLog=true ## must be unique dLegerPeers=n0-172.16.32.73:40911;n1-172.16.32.54:40911;n2-172.16.32.86:40911
-
节点3
vim /opt/data/rocketmq-03/broker/conf
写入以下内容
brokerIP1=172.16.32.86 listenPort=30911 brokerClusterName=RaftCluster brokerName=RaftNode00 namesrvAddr=172.16.32.73:9876;172.16.32.54:9876;172.16.32.86:9876 ## DLeger dLegerSelfId=n2 dLegerGroup=RaftNode00 enableDLegerCommitLog=true ## must be unique dLegerPeers=n0-172.16.32.73:40911;n1-172.16.32.54:40911;n2-172.16.32.86:40911 sendMessageThreadPoolNums=4
主要是brokerIP1和dLegerSelfId的配置区别
-
-
-
更改目录归属组与用户容器的配置一致
在3台机器上执行下面的命令创建组和用户
## 创建组 groupadd rocketmq ## 增加用户并加入组 useradd -g rocketmq rocketmq ## 设置用户密码 passwd rocketmq ## 更改组的 gid groupmod -g 3000 rocketmq ## 更改用户的 uid usermod -u 3000 rocketmq ## 查看是否更改成功 id rocketmq
在3台机器上分别更改上面创建的目录权限为rocketmq
## 节点1 chown -R rocketmq:rocketmq /opt/data/rocketmq-01 ## 节点2 chown -R rocketmq:rocketmq /opt/data/rocketmq-02 ## 节点3 chown -R rocketmq:rocketmq /opt/data/rocketmq-03
启动NameServer
-
节点1
docker run -itd --name rocketmq-nameserver-01 --net host \ -v /opt/data/rocketmq-01/nameserver/logs:/home/rocketmq/logs \ -e "JAVA_OPT_EXT=-Xms512M -Xmx512M -Xmn128m" \ -e TZ=AsiaShanghai \ --restart=always \ apacherocketmq/rocketmq:4.9.2 \ sh mqnamesrv
-
节点2
docker run -itd --name rocketmq-nameserver-02 --net host \ -v /opt/data/rocketmq-02/nameserver/logs:/home/rocketmq/logs \ -e "JAVA_OPT_EXT=-Xms512M -Xmx512M -Xmn128m" \ -e TZ=AsiaShanghai \ --restart=always \ apacherocketmq/rocketmq:4.9.2 \ sh mqnamesrv
-
节点3
docker run -itd --name rocketmq-nameserver-03 --net host \ -v /opt/data/rocketmq-03/nameserver/logs:/home/rocketmq/logs \ -e "JAVA_OPT_EXT=-Xms512M -Xmx512M -Xmn128m" \ -e TZ=AsiaShanghai \ --restart=always \ apacherocketmq/rocketmq:4.9.2 \ sh mqnamesrv
启动Broker
-
节点1
docker run -itd --name rocketmq-broker-01 --net host \ -e "JAVA_OPT_EXT=-Xmx4096m -Xms4096m -Xmn2048m" \ -e TZ=AsiaShanghai \ -v /opt/data/rocketmq-01/broker/logs:/home/rocketmq/logs \ -v /opt/data/rocketmq-01/broker/store:/home/rocketmq/store \ -v /opt/data/rocketmq-01/broker/conf:/home/rocketmq/conf \ --restart=always \ apacherocketmq/rocketmq:4.9.2 \ sh mqbroker -c /home/rocketmq/conf/broker.conf
-
节点2
docker run -itd --name rocketmq-broker-02 --net host \ -e "JAVA_OPT_EXT=-Xmx4096m -Xms4096m -Xmn2048m" \ -e TZ=AsiaShanghai \ -v /opt/data/rocketmq-02/broker/logs:/home/rocketmq/logs \ -v /opt/data/rocketmq-02/broker/store:/home/rocketmq/store \ -v /opt/data/rocketmq-02/broker/conf:/home/rocketmq/conf \ --restart=always \ apacherocketmq/rocketmq:4.9.2 \ sh mqbroker -c /home/rocketmq/conf/broker.conf
-
节点3
docker run -itd --name rocketmq-broker-03 --net host \ -e "JAVA_OPT_EXT=-Xmx4096m -Xms4096m -Xmn2048m" \ -e TZ=AsiaShanghai \ -v /opt/data/rocketmq-03/broker/logs:/home/rocketmq/logs \ -v /opt/data/rocketmq-03/broker/store:/home/rocketmq/store \ -v /opt/data/rocketmq-03/broker/conf:/home/rocketmq/conf \ --restart=always \ apacherocketmq/rocketmq:4.9.2 \ sh mqbroker -c /home/rocketmq/conf/broker.conf
RocketMQ控制台
docker run --restart=always -e TZ=Asia/Shanghai -itd -p 8789:8080 -e "NAMESRV_ADDR=172.16.0.4:9876;172.16.0.17:9876;172.16.0.14:9876" --name rocketmq-console apache/rocketmq-dashboard:1.0.0-centos
JAVA_OPTS=-Drocketmq.namesrv.addr=
后接上自己NameServer的地址,多个用;
隔开
启动成功后,通过IP加端口即可访问控制台.进入Cluster
菜单查看集群,这里可以看到DLedger集群已成功搭建,并选举出了一个Master,其余两个都是Slave节点.
测试发送消息
进入Topic
菜单,选择一个Topic,我这里是新建的TEST
,点SEND MASSAGE
输入消息后点击COMMIT
发送消息
sendStatus
显示SEND_OK
回到Cluster
菜单,看到三个节点均已正常复制数据.
验证DLedger自动选举Master
将Master节点进程kill之后,验证是否会自动选举新的Master节点
将Borker进程结束掉
等待10s后,回到控制台,发现已经重新选举了一个新的Master节点
重新启动节点后,会自动作为Slave节点加入集群