万字超详细解析:RocketMQ集群环境搭建

一、RocketMQ集群架构

通过之前安装单台RocketMQ,并演示了消息的收发,已经基本了解了RocketMQ是怎么样工作的,下面就来搭建一个集群

1.1、RocketMQ集群架构解析

一个完整的RocketMQ集群中,有如下几个角色

  • Producer:消息的发送者;举例:发信者
  • Consumer:消息接收者;举例:收信者
  • Broker:暂存和传输消息;举例:邮局
  • NameServer:管理Broker;举例:各个邮局的管理机构
  • Topic:区分消息的种类;一个发送者可以发送消息给一个或者多个Topic;一个消息的接收者可以订阅一个或者多个Topic消息

我们之前的测试案例中,Topic是什么?topic='TopicTest'现在你能看懂我们之前在broker.conf中添加的autoCreateTopicEnable=true这个属性的用处了吗?

  • Message Queue:相当于是Topic的分区;用于并行发送和接收消息

在之前的测试案例中,一个queueId就代表了一个MessageQueue。有哪些queueId? 0,1,2,3四个MessageQueue,你都找到了吗?

1.2、RocketMQ集群搭建与优化

1.2.1 实验环境

​ 准备三台虚拟机,硬盘空间建议大于4G。配置机器名。这样后期在进行相关处理的时候就比较方便了,使用vim /etc/hosts,输入如下内容:

#mq 
192.168.253.131 Jony1
192.168.253.132 Jony2
192.168.253.133 Jony3
复制代码

1.2.2 安装JDK1.8 

给Jony2及Jony3安装JDK1.8,因比较简单,具体安装步骤省略了

1.2.3 安装RocketMQ

将安装的压缩文件分别复制到Jony2和Jony3机器上面

Jony2:

Jony3:

并配置环境变量

#rocketmq 
export ROCKETMQ_HOME=/usr/local/soft/rocketmq
复制代码

使环境变量生效

source /etc/profile
复制代码

1.2.4 配置RocketMQ主从集群

​ 我们为了便于观察,这次搭建一个2主2从异步刷盘的集群,所以我们会使用conf/2m-2s-async下的配置文件。预备设计的集群情况如下:

机器名nemaeServer节点部署broker节点部署
Jony1nameserver
Jony2nameserverbroker-a, broker-b-s
Jony3nameserverbroker-b,broker-a-s

Jony1:进负责起一个nameServer

Jony2:启动broker-a的主节点及borker-b的从节点

Jony3:启动broker-b的主节点及borker-a的从节点

rocketmq在配置文件中默认帮我们预设了一些集群的配置文件,如下:

在rocketmq的config目录下可以看到rocketmq建议的各种配置方式:

2m-2s-async: 2主2从异步刷盘(吞吐量较大,但是消息可能丢失),

2m-2s-sync:2主2从同步刷盘(吞吐量会下降,但是消息更安全),

2m-noslave:2主无从(单点故障),

然后还可以直接配置broker.conf,进行单点环境配置。

而dleger就是用来实现主从切换的。

集群中的节点会基于Raft协议随机选举出一个leader,其他的就都是follower。

通常正式环境都会采用这种方式来搭建集群。

我们采用2m-2s-async的方式搭建集群。

1、配置第一组broker-a

在Jony2上先配置borker-a的master节点。先配置2m-2s-async/broker-a.properties

先进入2m-2s-async目录,可以看到如下配置文件

打开broker-a.properites

vim broker-a.properties
复制代码

将以上内容注释掉,并将以下内容复制到文件中

#所属集群名字,名字一样的节点就在同一个集群内 
brokerClusterName=rocketmq-cluster 
#broker名字,名字一样的节点就是一组主从节点。 
brokerName=broker-a 
#brokerid,0就表示是Master,>0的都是表示 
Slave brokerId=0 
#nameServer地址,分号分割 
namesrvAddr=Jony1:9876;Jony2:9876;Jony3:9876 
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4 
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true 
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true 
#Broker 对外服务的监听端口 
listenPort=10911 
#删除文件时间点,默认凌晨 4点 
deleteWhen=04 
#文件保留时间,默认 48 小时 
fileReservedTime=120 
#commitLog每个文件的大小默认1G 
mapedFileSizeCommitLog=1073741824 
#ConsumeQueue每个文件默认存30W条,根据业务情况调整 
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间 
diskMaxUsedSpaceRatio=88 
#存储路径 
storePathRootDir=/usr/local/soft/rocketmq/store 
#commitLog 存储路径 
storePathCommitLog=/usr/local/soft/rocketmq/store/commitlog 
#消费队列存储路径存储路径 
storePathConsumeQueue=/usr/local/soft/rocketmq/store/consumequeue 
#消息索引存储路径 
storePathIndex=/usr/local/soft/rocketmq/store/index 
#checkpoint 文件存储路径 
storeCheckpoint=/usr/local/soft/rocketmq/store/checkpoint 
#abort 文件存储路径 
abortFile=/usr/local/soft/rocketmq/store/abort 
#限制的消息大小 
maxMessageSize=65536 
#flushCommitLogLeastPages=4 
#flushConsumeQueueLeastPages=2 
#flushCommitLogThoroughInterval=10000 #flushConsumeQueueThoroughInterval=60000 
#Broker 的角色 
#- ASYNC_MASTER 异步复制Master 
#- SYNC_MASTER 同步双写Master 
#- SLAVE brokerRole=ASYNC_MASTER 
#刷盘方式 
#- ASYNC_FLUSH 异步刷盘 
#- SYNC_FLUSH 同步刷盘 
flushDiskType=ASYNC_FLUSH 
#checkTransactionMessageEnable=false
#发消息线程池数量 
#sendMessageThreadPoolNums=128 
#拉消息线程池数量 
#pullMessageThreadPoolNums=128
复制代码

该节点对应的从节点在Jony3上。修改2m-2s-async/broker-a-s.properties

#所属集群名字,名字一样的节点就在同一个集群内 brokerClusterName=rocketmq-cluster #broker名字,名字一样的节点就是一组主从节点。 brokerName=broker-a #brokerid,0就表示是Master,>0的都是表示 Slave brokerId=1 #nameServer地址,分号分割 namesrvAddr=Jony1:9876;Jony2:9876;Jony3:9876 #在发送消息时,自动创建服务器不存在的topic,默认创建的队列数 defaultTopicQueueNums=4 #是否允许 Broker 自动创建Topic,建议线下开启,线上关闭 autoCreateTopicEnable=true #是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭 autoCreateSubscriptionGroup=true #Broker 对外服务的监听端口 listenPort=11011 #删除文件时间点,默认凌晨 4点 deleteWhen=04 #文件保留时间,默认 48 小时 fileReservedTime=120 #commitLog每个文件的大小默认1G mapedFileSizeCommitLog=1073741824 #ConsumeQueue每个文件默认存30W条,根据业务情况调整 mapedFileSizeConsumeQueue=300000 #destroyMapedFileIntervalForcibly=120000 #redeleteHangedFileInterval=120000 #检测物理文件磁盘空间 diskMaxUsedSpaceRatio=88 #存储路径 storePathRootDir=/usr/local/soft/rocketmq/storeSlave #commitLog 存储路径 storePathCommitLog=/usr/local/soft/rocketmq/storeSlave/commitlog #消费队列存储路径存储路径 storePathConsumeQueue=/usr/local/soft/rocketmq/storeSlave/consumequeue #消息索引存储路径 storePathIndex=/usr/local/soft/rocketmq/storeSlave/index #checkpoint 文件存储路径 storeCheckpoint=/usr/local/soft/rocketmq/storeSlave/checkpoint #abort 文件存储路径 abortFile=/usr/local/soft/rocketmq/storeSlave/abort #限制的消息大小 maxMessageSize=65536 #flushCommitLogLeastPages=4 #flushConsumeQueueLeastPages=2 #flushCommitLogThoroughInterval=10000 #flushConsumeQueueThoroughInterval=60000 #Broker 的角色 #- ASYNC_MASTER 异步复制Master #- SYNC_MASTER 同步双写Master #- SLAVE brokerRole=SLAVE #刷盘方式 #- ASYNC_FLUSH 异步刷盘 #- SYNC_FLUSH 同步刷盘 flushDiskType=ASYNC_FLUSH #checkTransactionMessageEnable=false #发消息线程池数量 #sendMessageThreadPoolNums=128 #拉消息线程池数量 #pullMessageThreadPoolNums=128
复制代码

2、配置第二组Broker-b

这一组broker的主节点在Jony3上,所以需要配置Jony3上的config/2m-2s-async/broker-b.properties

#所属集群名字,名字一样的节点就在同一个集群内 brokerClusterName=rocketmq-cluster #broker名字,名字一样的节点就是一组主从节点。 brokerName=broker-b #brokerid,0就表示是Master,>0的都是表示 Slave brokerId=0 #nameServer地址,分号分割 namesrvAddr=Jony1:9876;Jony2:9876;Jony3:9876 #在发送消息时,自动创建服务器不存在的topic,默认创建的队列数 defaultTopicQueueNums=4 #是否允许 Broker 自动创建Topic,建议线下开启,线上关闭 autoCreateTopicEnable=true #是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭 autoCreateSubscriptionGroup=true #Broker 对外服务的监听端口 listenPort=10911 #删除文件时间点,默认凌晨 4点 deleteWhen=04 #文件保留时间,默认 48 小时 fileReservedTime=120 #commitLog每个文件的大小默认1G mapedFileSizeCommitLog=1073741824 #ConsumeQueue每个文件默认存30W条,根据业务情况调整 mapedFileSizeConsumeQueue=300000 #destroyMapedFileIntervalForcibly=120000 #redeleteHangedFileInterval=120000 #检测物理文件磁盘空间 diskMaxUsedSpaceRatio=88 #存储路径 storePathRootDir=/usr/local/soft/rocketmq/store #commitLog 存储路径 storePathCommitLog=/usr/local/soft/rocketmq/store/commitlog #消费队列存储路径存储路径 storePathConsumeQueue=/usr/local/soft/rocketmq/store/consumequeue #消息索引存储路径 storePathIndex=/usr/local/soft/rocketmq/store/index #checkpoint 文件存储路径 storeCheckpoint=/usr/local/soft/rocketmq/store/checkpoint #abort 文件存储路径 abortFile=/usr/local/soft/rocketmq/store/abort #限制的消息大小 maxMessageSize=65536 #flushCommitLogLeastPages=4 #flushConsumeQueueLeastPages=2 #flushCommitLogThoroughInterval=10000 #flushConsumeQueueThoroughInterval=60000 #Broker 的角色 #- ASYNC_MASTER 异步复制Master #- SYNC_MASTER 同步双写Master #- SLAVE brokerRole=ASYNC_MASTER #刷盘方式 #- ASYNC_FLUSH 异步刷盘 #- SYNC_FLUSH 同步刷盘 flushDiskType=ASYNC_FLUSH #checkTransactionMessageEnable=false #发消息线程池数量 #sendMessageThreadPoolNums=128 #拉消息线程池数量 #pullMessageThreadPoolNums=128
复制代码

然后他对应的slave在Jony2上,修改Jony上的 conf/2m-2s-async/broker-b-s.properties

#所属集群名字,名字一样的节点就在同一个集群内 brokerClusterName=rocketmq-cluster #broker名字,名字一样的节点就是一组主从节点。 brokerName=broker-b #brokerid,0就表示是Master,>0的都是表示 Slave brokerId=1 #nameServer地址,分号分割 namesrvAddr=Jony1:9876;Jony2:9876;Jony3:9876 #在发送消息时,自动创建服务器不存在的topic,默认创建的队列数 defaultTopicQueueNums=4 #是否允许 Broker 自动创建Topic,建议线下开启,线上关闭 autoCreateTopicEnable=true #是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭 autoCreateSubscriptionGroup=true #Broker 对外服务的监听端口 listenPort=11011 #删除文件时间点,默认凌晨 4点 deleteWhen=04 #文件保留时间,默认 48 小时 fileReservedTime=120 #commitLog每个文件的大小默认1G mapedFileSizeCommitLog=1073741824 #ConsumeQueue每个文件默认存30W条,根据业务情况调整 mapedFileSizeConsumeQueue=300000 #destroyMapedFileIntervalForcibly=120000 #redeleteHangedFileInterval=120000 #检测物理文件磁盘空间 diskMaxUsedSpaceRatio=88 #存储路径 storePathRootDir=/usr/local/soft/rocketmq/storeSlave #commitLog 存储路径 storePathCommitLog=/usr/local/soft/rocketmq/storeSlave/commitlog #消费队列存储路径存储路径 storePathConsumeQueue=/usr/local/soft/rocketmq/storeSlave/consumequeue #消息索引存储路径 storePathIndex=/usr/local/soft/rocketmq/storeSlave/index #checkpoint 文件存储路径 storeCheckpoint=/usr/local/soft/rocketmq/storeSlave/checkpoint #abort 文件存储路径 abortFile=/usr/local/soft/rocketmq/storeSlave/abort #限制的消息大小 maxMessageSize=65536 #flushCommitLogLeastPages=4 #flushConsumeQueueLeastPages=2 #flushCommitLogThoroughInterval=10000 #flushConsumeQueueThoroughInterval=60000 #Broker 的角色 #- ASYNC_MASTER 异步复制Master #- SYNC_MASTER 同步双写Master #- SLAVE brokerRole=SLAVE #刷盘方式 #- ASYNC_FLUSH 异步刷盘 #- SYNC_FLUSH 同步刷盘 flushDiskType=ASYNC_FLUSH #checkTransactionMessageEnable=false #发消息线程池数量 #sendMessageThreadPoolNums=128 #拉消息线程池数量 #pullMessageThreadPoolNums=128
复制代码

这样2主2从的集群配置基本就完成了。搭建过程中需要注意的配置项:

1、同一机器上两个实例的store目录不能相同,否则会报错 Lock failed,MQ already started

2、同一机器上两个实例的listenPort也不能相同。否则会报端口占用的错

nameserver不需要进行配置,直接启动就行。这也看出nameserver是无状态的。

3、如果是多网卡的机器,比如云服务器,那么需要在broker.conf中增加brokerIP1属性,指定所在机器的外网网卡地址。

1.2.5 启动RocketMQ

启动就比较简单了,直接调用bin目录下的脚本就行。只是启动之前要注意看下他们的JVM内存配置,默认的配置都比较高。

1、先启动nameServer

修改三个节点上的bin/runserver.sh,调整里面的jvm内存配置。找到下面这一行调整下内存

JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
复制代码

直接在三个节点上启动nameServer。

nohup bin/mqnamesrv &
复制代码

启动完成后,在nohup.out里看到这一条关键日志就是启动成功了。

Java HotSpot(TM) 64-Bit Server VM warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release

Java HotSpot(TM) 64-Bit Server VM warning: UseCMSCompactAtFullCollection is deprecated and will likely be removed in a future release.

The Name Server boot success. serializeType=JSON

使用jps指令可以看到一个NamesrvStartup进程。

这里也看到,RocketMQ在runserver.sh中是使用的CMS垃圾回收期,而在runbroker.sh中使用的是G1垃圾回收期。

2、再启动broker

需要注意的是在启动broker之前,同样需要修改bin/runbroker.sh的JVM参数,修改为512m

JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m"
复制代码

启动broker是使用的mqbroker指令,只是注意启动broker时需要通过-c 指定对应的配置文件。

启动顺序最好先启动master节点,然后再启动slave节点

在Jony2上启动broker-a的master节点

nohup ./mqbroker -c ../conf/2m-2s-async/broker-a.properties &
复制代码

在Jony3上启动broker-b的master节点和broker-a的slave节点

nohup ./mqbroker -c ../conf/2m-2s-async/broker-b.properties &
复制代码

在Jony2上启动broker-b的slave节点

nohup ./mqbroker -c ../conf/2m-2s-async/broker-b-s.properties &
复制代码

在Jony3上启动broker-a的slave节点

nohup ./mqbroker -c ../conf/2m-2s-async/broker-a-s.properties &
复制代码

启动slave时,如果遇到报错 Lock failed,MQ already started ,那是因为有多个实例共用了同一个storePath造成的,这时就需要调整store的路径。

3、启动状态检查

使用jps指令,能看到一个NameSrvStartup进程和两个BrokerStartup进程。

Jony2:

Jony3:

nohup.out中也有启动成功的日志。

对应的日志文件:

# 查看nameServer日志 
tail -500f ~/logs/rocketmqlogs/namesrv.log
# 查看broker日志 
tail -500f ~/logs/rocketmqlogs/broker.log
复制代码

通过查看broker日志发现一些未成功创建文件的错误如下:

2023-03-27 23:04:26 ERROR DiskCheckScheduledThread1 - Error when measuring disk space usage, file doesn't exist on this path: /usr/local/soft/rocketmq/storeSlave/commitlog 
2023-03-27 23:04:30 ERROR StoreScheduledThread1 - Error when measuring disk space usage, file doesn't exist on this path: /usr/local/soft/rocketmq/store/commitlog
复制代码

主要为store和storeSlave目录下缺失:commitlog及consumqueue文件

先停止Broker,然后给Jony2和Jony3在对应目录下分别创建,然后重启启Broker

再次查看broker.log

2023-03-27 23:39:25 INFO BrokerControllerScheduledThread1 - Update slave consumer offset from master, 192.168.253.133:10911 2023-03-27 23:39:25 INFO BrokerControllerScheduledThread1 - Update slave delay offset from master, 192.168.253.133:10911 2023-03-27 23:39:35 INFO BrokerControllerScheduledThread1 - Update slave consumer offset from master, 192.168.253.133:10911 2023-03-27 23:39:35 INFO BrokerControllerScheduledThread1 - Update slave delay offset from master, 192.168.253.133:10911 2023-03-27 23:39:45 INFO BrokerControllerScheduledThread1 - Update slave consumer offset from master, 192.168.253.133:10911 2023-03-27 23:39:45 INFO BrokerControllerScheduledThread1 - Update slave delay offset from master, 192.168.253.133:10911 2023-03-27 23:39:51 INFO BrokerControllerScheduledThread1 - dispatch behind commit log 0 bytes 2023-03-27 23:39:52 INFO brokerOutApi_thread_3 - register broker[1]to name server Jony1:9876 OK 2023-03-27 23:39:52 INFO brokerOutApi_thread_1 - register broker[1]to name server Jony3:9876 OK 2023-03-27 23:39:52 INFO brokerOutApi_thread_2 - register broker[1]to name server Jony2:9876 OK

4、测试mqadmin管理工具

​ RocketMQ源码中并没有提供管理控制台,只提供了一个mqadmin指令来管理RocketMQ。指令的位置在bin目录下。直接使用该指令就会列出所有支持的命令。

./mqadmin 
复制代码

使用方式都是 mqadmin {command} {args}。 如果有某个指令不会使用,可以使用 mqadmin help {command} 指令查看帮助。

使用mqadmin查看集群信息:

mqadmin clusterList
复制代码

发生如下异常

1、到jdk目录下/jre/lib/ext/找到sunjce_provider.jar复制到rocketmq/lib/中

2、修改etc/profile 添加环境变量(在执行的时候会从nameServer获取URL地址)

#rocketmq -address 
export NAMESRV_ADDR='Jony1:9876;Jony2:9876;Jony3:9876'
复制代码

5、命令行快速验证

RocketMQ提供了一个tools.sh工具可以用来在命令行快速验证RocketMQ服务。例如,在worker2机器上进入RocketMQ的安装目录:

发送消息:默认会发1000条消息

bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
复制代码

接收消息:

bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
复制代码

注意,这是官方提供的Demo,但是官方的源码中,这两个类都是没有指定nameServer的,所以运行会有点问题。要指定NameServer地址,可以配置一个环境变量NAMESRV_ADDR,这样默认会读取这个NameServer地址。可以配到.bash_profile里或者直接临时指定。export NAMESRV_ADDR='Jony1:9876;Jony2:9876;Jony3:9876'然后就可以正常执行了。

这个tooles.sh实际上是封装了一个简单的运行RocketMQ的环境,上面指令中指定的Java类,都在lib/rocketmq-example-4.9.1.jar包中。未来如果自己有一些客户端示例,也可以打成jar包放到这个lib目录下,通过tools.sh运行。

1.2.6 搭建管理控制台

RocketMQ源代码中并没有提供控制台,但是有一个Rocket的社区扩展项目中提供了一个控制台,地址: github.com/apache/rock…

此项目是一个Maven项目,可以使用mvn package 打包生成jar包,在maven之前需要进入项目修改一些配置文件

在这个项目的application.yml中需要指定nameserver的地址。默认这个属性是指向本地。如果配置为空,会读取环境变量NAMESRV_ADDR。

那我们可以在jar包的当前目录下增加一个application.yml文件,覆盖jar包中默认的一个属性:

rocketmq: 
    config: 
        namesrvAddrs: 
            - Jony1:9876
            - Jony2:9876 
            - Jony3:9876
复制代码

然后进入对应的目录,使用maven进行编译

mvn clean package -Dmaven.test.skip=true
复制代码

编译的时候我这边yarn包无法从github下载,报如下错误:

解决办法就是从github手动下载,然后复制到我们本地仓库中

github.com/yarnpkg/yar…

并将这个zip的文件名改为yarn-1.22.10.tar.gz,然后将zip拷贝到自己的maven仓库

再进行编译,编译完成后,获取target下的jar包,可以本地运行,我这边上传到了虚拟机中。

nohup java -jar rocketmq-dashboard-1.0.1-SNAPSHOT.jar &
复制代码

启动完成后,可以访问 http://192.168.253.131:8080看到管理页面

1.2.7 管理控制台的认识

此控制台为RocketMQ社区提供,为我们使用RocketMQ提供了非常便利的操作

1.2.7.1 切换语言

此控制台支持英文和中文的语言切换,为了方便切换为中文 如下:

1.2.7.2 集群查看

点击集群就可以看到、当前集群的各个borker相关信息,如master/slave 、地址、以及消息生成和消费的相关数据,点击节点后面的状态和配置就可以查对应borker的对应信息

1.2.7.3 主题-topic

点击主题,可以看到当前是没有任何topic的

下面用bin下面的tools发送消息

bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
复制代码

发送成功之后,可以看到返回了消息发送的结果,包括发送状态,使用的Topic和brokerName

再次打开控制台,就可以看到已经自动创建了一个TopicTest的Topic

点击状态就可以查看当前Topic的相关信息,通过如下信息可以看到,发送的1000条消息,被分部到了8个MessageQueue中,分别有broker-a和borker-a,每个broker上面各有4个MessageQueue,最小点位指当前消息消费到了哪里的偏移量,最大点位指当前共有多少消息,MessageQueue是一个消息队列,遵循先进先出规则。

然后再使用如下命令进行消费消息

bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
复制代码

点击Topic的CONSUMER 管理

这样就可以看到消费消息的相关信息

订阅组:在消费的源码中设置的值(后面看源码可以看到)

Broker:消费消息的BrokerName

队列:在Broker中的队列

消费者终端:消费消息的服务相关信息

代理者位点:当前broker有多少个消息

消费者位点:当前消费到了哪个消息

差值:还差多杀消息未消费

使用tool.sh工具再发送1000条消息,再次查看CONSUMER管理,这次可以看到代理者位点就变成了250,消费者位点依然是125,这样就代表当前broker共有250条消息,消费了125个,然后对应的差值125还未消费

再进入Topic配置页

具体信息如下:可以看到当前Topic有哪些borker(截屏未全部截取),以及broker的队列数量,默认是4个,perm只权限,权限分别分为如下几种:

2:不可读写

4:可读不可写

6:可读可写

3.2.8 搭建Dledger高可用集群--了解

上面搭建2m-2s的集群不是高可用的,当其中一个m挂掉,对应的borker就无法提供服务了,官方给了一个Dledger的高可用方案,在conf下有dledger文件夹下有三个conf,其中有对应的配置信息

要搭建高可用的Broker集群,我们只需要配置conf/dleger下的配置文件就行。

这种模式是基于Raft协议的,是一个类似于Zookeeper的paxos协议的选举协议,也是会在集群中随机选举出一个leader,其他的就是follower。只是他选举的过程跟paxos有点不同。Raft协议基于随机休眠机制的,选举过程会比paxos相对慢一点。

​ 首先:我们同样是需要修改runserver.sh和runbroker.sh,对JVM内存进行定制。

​ 然后:我们需要修改conf/dleger下的配置文件。 跟dleger相关的几个配置项如下:

name含义举例
enableDLegerCommitLog是否启动 DLedgertrue
dLegerGroupDLedger Raft Group的名字,建议和 brokerName 保持一致RaftNode00
dLegerPeersDLedger Group 内各节点的端口信息,同一个 Group 内的各个节点配置必须要保证一致n0-127.0.0.1:40911;n1-127.0.0.1:40912;n2-127.0.0.1:40913
dLegerSelfId节点 id, 必须属于 dLegerPeers 中的一个;同 Group 内各个节点要唯一n0
sendMessageThreadPoolNums发送线程个数,建议配置成 Cpu 核数16

配置完后,同样是使用 nohup bin/mqbroker -c $conf_name & 的方式指定实例文件。

在bin/dleger下有个fast-try.sh,这个脚本是在本地启动三个RocketMQ实例,搭建一个高可用的集群,读取的就是conf/dleger下的broker-no.conf,broker-n1.conf和broker-n2.conf。使用这个脚本同样要注意定制下JVM内存,他给每个实例默认定制的是1G内存,虚拟机肯定是不够的。这种单机三实例的集群搭建完成后,可以使用 bin/mqadmin clusterList -n worker1.conf的方式查看集群状态。

如果使用Dledger搭建集群,需要将三个节点放到不同的服务器,如果放到一台如果服务器宕机,RocketMQ对应的单个节点就都无法访问,这样也就不是高可用了,但是如果放到三个不同的服务器,这三个节点之间会进行Raft选举,一定程度会浪费一些资源,因此正式的高可用集群可以使用keeplive来保持master的活性,也就实现了高可用。

3.2.9 系统参数调优 -- 重要

到这里,整个RocketMQ的服务就搭建完成了。但是在实际使用时,我们说RocketMQ的吞吐量、性能都很高,那要发挥RocketMQ的高性能,还需要对RocketMQ以及服务器的性能进行定制

1、配置RocketMQ的JVM内存大小:

之前提到过,在runserver.sh中需要定制nameserver的内存大小,在runbroker.sh中需要定制broker的内存大小。这些默认的配置可以认为都是经过检验的最优化配置,但是在实际情况中都还需要根据服务器的实际情况进行调整。这里以runbroker.sh中对G1GC的配置举例,在runbroker.sh中的关键配置:

JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0" 
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${GC_LOG_DIR}/rmq_broker_gc_%p_%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" 
JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
复制代码

-XX:+UseG1GC: 使用G1垃圾回收器, -XX:G1HeapRegionSize=16m 将G1的region块大小设为16M,-XX:G1ReservePercent:在G1的老年代中预留25%空闲内存,这个默认值是10%,RocketMQ把这个参数调大了。-XX:InitiatingHeapOccupancyPercent=30:当堆内存的使用率达到30%之后就会启动G1垃圾回收器尝试回收垃圾,默认值是45%,RocketMQ把这个参数调小了,也就是提高了GC的频率,但是避免了垃圾对象过多,一次垃圾回收时间太长的问题。

然后,后面定制了GC的日志文件,确定GC日志文件的地址、打印的内容以及控制每个日志文件的大小为30M并且只保留5个文件。这些在进行性能检验时,是相当重要的参考内容。

2、RocketMQ的其他一些核心参数

例如在conf/dleger/broker-n0.conf中有一个参数:sendMessageThreadPoolNums=16。这一个参数是表明RocketMQ内部用来发送消息的线程池的线程数量是16个,其实这个参数可以根据机器的CPU核心数进行适当调整,例如如果你的机器核心数超过16个,就可以把这个参数适当调大。

3、Linux内核参数定制

我们在部署RocketMQ的时候,还需要对Linux内核参数进行一定的定制。例如

  • ulimit,需要进行大量的网络通信和磁盘IO。
  • vm.extra_free_kbytes,告诉VM在后台回收(kswapd)启动的阈值与直接回收(通过分配进程)的阈值之间保留额外的可用内存。RocketMQ使用此参数来避免内存分配中的长延迟。(与具体内核版本相关)
  • vm.min_free_kbytes,如果将其设置为低于1024KB,将会巧妙的将系统破坏,并且系统在高负载下容易出现死锁。
  • vm.max_map_count,限制一个进程可能具有的最大内存映射区域数。RocketMQ将使用mmap加载CommitLog和ConsumeQueue,因此建议将为此参数设置较大的值。
  • vm.swappiness,定义内核交换内存页面的积极程度。较高的值会增加攻击性,较低的值会减少交换量。建议将值设置为10来避免交换延迟。
  • File descriptor limits,RocketMQ需要为文件(CommitLog和ConsumeQueue)和网络连接打开文件描述符。我们建议设置文件描述符的值为655350。

这些参数在CentOS7中的配置文件都在 /proc/sys/vm目录下。另外,RocketMQ的bin目录下有个os.sh里面设置了RocketMQ建议的系统内核参数,可以根据情况进行调整。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值