跳转至

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-cluster0 为 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)外,生产环境建议开启异步刷盘以提高吞吐。

flushDiskType=ASYNC_FLUSH
2. 开启 Slave 读权限

accessMessageInMemoryMaxRatio 默认值为 40%。当消息不在内存中且开启 slaveReadEnable 时,消费者可以从 Slave 节点读取,从而降低 Master 的读取压力。

slaveReadEnable=true
3. 调整单次拉取消息数量

单次拉取数量由 Broker 和 Consumer 共同决定,默认 32 条。Broker 端由 maxTransferCountOnMessageInMemory 控制,Consumer 端由 pullBatchSize 控制。Broker 端可适当调大(例如 1000),为 Consumer 留出调整空间。

maxTransferCountOnMessageInMemory=1000
4. 调整发送队列等待时间

消息在 Broker 发送队列中的等待时间由 waitTimeMillsInSendQueue 控制,默认 200 ms。建议根据业务设置为 1000~5000 ms;设置过短可能导致客户端超时。

waitTimeMillsInSendQueue=1000
5. 使用主从异步复制

为提高集群性能,生产环境通常设置为主从异步复制。请根据数据可靠性要求评估同步复制带来的性能开销。

brokerRole=ASYNC_MASTER

提高集群稳定性

为了提高集群稳定性,下面对三个参数做特别说明,后续踩坑案例还会继续分析。

关闭堆外内存
transientStorePoolEnable=false
关闭文件预热
warmMapedFileEnable=false
开启堆内传输
transferMsgByHeap=true