17 RocketMQ 集群性能调优¶
前言¶
本篇从系统参数和集群参数两个维度优化 RocketMQ 集群。相比单纯提高 TPS,优先保证运行稳定性更重要。文中的建议来自生产环境实践,后续还会介绍因参数设置不当导致集群不稳定的案例。
系统参数调优¶
解压 RocketMQ 安装包后,bin/os.sh 中包含官方推荐的系统参数配置。通常这些参数可以满足需求,也可以根据实际情况调整。不建议使用 Linux 2.6 及以下内核,建议使用 3.10 及以上版本;如果使用 CentOS,建议选择 CentOS 7 及以上版本。Linux 2.6 内核可能引发的问题会在后续案例中说明。
最大文件数¶
设置用户允许打开的最大文件数:
vim /etc/security/limits.conf
# End of file
baseuser soft nofile 655360
baseuser hard nofile 655360
* soft nofile 655360
* hard nofile 655360
系统参数设置¶
系统参数以官方推荐值为基础,下面说明各参数的作用。可以执行 sh bin/os.sh(或在对应目录执行 sh os.sh),也可以编辑 /etc/sysctl.conf 手动添加以下内容,随后执行 sysctl -p 使配置生效:
vm.overcommit_memory=1
vm.drop_caches=1
vm.zone_reclaim_mode=0
vm.max_map_count=655360
vm.dirty_background_ratio=50
vm.dirty_ratio=50
vm.dirty_writeback_centisecs=360000
vm.page-cluster=3
vm.swappiness=1
参数说明:
| 参数 | 含义 |
|---|---|
overcommit_memory |
内存过量分配策略:0 由内核检查可用空间;1 始终允许分配;2 禁止过量分配。 |
drop_caches |
手动释放缓存:1 清空页缓存;2 清空 inode 和目录项缓存;3 全部清空。该参数不建议作为常规持久化配置。 |
zone_reclaim_mode |
0 允许从其他 NUMA 节点分配内存;1 优先回收本地节点缓存。 |
max_map_count |
定义了一个进程能拥有的最多的内存区域,默认为 65536 |
dirty_background_ratio/dirty_ratio |
脏页占比达到阈值后触发回写;如果设置了 dirty_background_bytes/dirty_bytes,比例参数会由内核换算。 |
dirty_writeback_centisecs |
内核回写线程的运行间隔,单位为百分之一秒。 |
page-cluster |
一次 swap in/out 操作的页数为 2^page-cluster:0 为 1 页,1 为 2 页,2 为 4 页,3 为 8 页。 |
swappiness |
控制交换倾向:0 最低,1 尽量少交换,60 为默认值,100 最积极使用交换空间。 |
集群参数调优¶
生产环境配置¶
下面列出一份在生产环境使用的配置文件,并说明其参数所表示的含义,稍作修改集群名称和地址后即可用于生产环境。
配置示例:
brokerClusterName=testClusterA
brokerName=broker-a
brokerId=0
listenPort=10911
namesrvAddr=x.x.x.x:9876;x.x.x.x:9876
defaultTopicQueueNums=16
autoCreateTopicEnable=false
autoCreateSubscriptionGroup=false
deleteWhen=04
fileReservedTime=48
mapedFileSizeCommitLog=1073741824
mapedFileSizeConsumeQueue=50000000
destroyMapedFileIntervalForcibly=120000
redeleteHangedFileInterval=120000
diskMaxUsedSpaceRatio=88
storePathRootDir=/data/rocketmq/store
storePathCommitLog=/data/rocketmq/store/commitlog
storePathConsumeQueue=/data/rocketmq/store/consumequeue
storePathIndex=/data/rocketmq/store/index
storeCheckpoint=/data/rocketmq/store/checkpoint
abortFile=/data/rocketmq/store/abort
maxMessageSize=65536
flushCommitLogLeastPages=4
flushConsumeQueueLeastPages=2
flushCommitLogThoroughInterval=10000
flushConsumeQueueThoroughInterval=60000
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
maxTransferCountOnMessageInMemory=1000
transientStorePoolEnable=false
warmMapedFileEnable=false
pullMessageThreadPoolNums=128
slaveReadEnable=true
transferMsgByHeap=true
waitTimeMillsInSendQueue=1000
参数说明:
| 参数 | 含义 |
|---|---|
brokerClusterName |
集群名称 |
brokerName |
broker 名称 |
brokerId |
0 表示 Master,非 0 表示 Slave。 |
listenPort |
broker 监听端口 |
namesrvAddr |
namesrvAddr 地址 |
defaultTopicQueueNums |
创建 Topic 时默认的队列数量 |
autoCreateTopicEnable |
是否允许自动创建主题,生产环境建议关闭,非生产环境可以开启 |
autoCreateSubscriptionGroup |
是否允许自动创建消费组,生产环境建议关闭,非生产环境可以开启 |
deleteWhen |
清理过期日志时间,04 表示凌晨 4 点开始清理 |
fileReservedTime |
日志保留的时间单位小时,48 即 48 小时,保留 2 天 |
mapedFileSizeCommitLog |
日志文件大小 |
mapedFileSizeConsumeQueue |
ConsumeQueue 文件大小 |
destroyMapedFileIntervalForcibly |
强制删除文件前等待的时间,单位为毫秒。 |
redeleteHangedFileInterval |
重试删除卡住文件的时间间隔,单位为毫秒。 |
diskMaxUsedSpaceRatio |
磁盘最大使用率,超过使用率会发起日志清理操作 |
storePathRootDir |
RocketMQ 日志等数据存储的根目录 |
storePathCommitLog |
CommitLog 存储目录 |
storePathConsumeQueue |
ConsumeQueue 存储目录 |
storePathIndex |
索引文件存储目录 |
storeCheckpoint |
checkpoint 文件存储目录 |
abortFile |
abort 文件存储目录 |
maxMessageSize |
单条消息允许的最大字节数。 |
flushCommitLogLeastPages |
未 flush 的消息大小超过设置页时,才执行 flush 操作;一页大小为 4K |
flushConsumeQueueLeastPages |
未 flush 的消费队列大小超过设置页时,才执行 flush 操作;一页大小为 4K |
flushCommitLogThoroughInterval |
两次执行消息 flush 操作的间隔时间,默认为 10 秒 |
flushConsumeQueueThoroughInterval |
两次执行消息队列 flush 操作的间隔时间,默认为 60 秒 |
brokerRole |
Broker 角色:ASYNC_MASTER 异步复制主节点,SYNC_MASTER 同步复制主节点,SLAVE 从节点。 |
flushDiskType |
刷盘类型:ASYNC_FLUSH 异步刷盘,SYNC_FLUSH 同步刷盘。 |
maxTransferCountOnMessageInMemory |
消费时允许一次拉取的最大消息数 |
transientStorePoolEnable |
是否开启堆外内存传输 |
warmMapedFileEnable |
是否开启文件预热 |
pullMessageThreadPoolNums |
拉取消息线程池大小 |
slaveReadEnable |
是否允许从 Slave 节点读取消息;当消息不在内存中时,可降低 Master 的读取压力。 |
transferMsgByHeap |
消息消费时是否从堆内存读取 |
waitTimeMillsInSendQueue |
发送消息时在队列中的等待时间,超过后可能抛出超时错误 |
调优建议¶
以下几个 Broker 属性会影响集群性能和稳定性,单独说明如下。
1. 开启异步刷盘¶
除支付等对持久化延迟要求极高的场景,以及 TPS 较低的场景(例如低于 2000)外,生产环境建议开启异步刷盘以提高吞吐。
2. 开启 Slave 读权限¶
accessMessageInMemoryMaxRatio 默认值为 40%。当消息不在内存中且开启 slaveReadEnable 时,消费者可以从 Slave 节点读取,从而降低 Master 的读取压力。
3. 调整单次拉取消息数量¶
单次拉取数量由 Broker 和 Consumer 共同决定,默认 32 条。Broker 端由 maxTransferCountOnMessageInMemory 控制,Consumer 端由 pullBatchSize 控制。Broker 端可适当调大(例如 1000),为 Consumer 留出调整空间。
4. 调整发送队列等待时间¶
消息在 Broker 发送队列中的等待时间由 waitTimeMillsInSendQueue 控制,默认 200 ms。建议根据业务设置为 1000~5000 ms;设置过短可能导致客户端超时。
5. 使用主从异步复制¶
为提高集群性能,生产环境通常设置为主从异步复制。请根据数据可靠性要求评估同步复制带来的性能开销。
提高集群稳定性¶
为了提高集群稳定性,下面对三个参数做特别说明,后续踩坑案例还会继续分析。