跳到主要内容

性能调优

RocketMQ 作为高性能消息中间件,合理的调优配置可以显著提升系统性能。本章将从 JVM、操作系统、Broker 三个层面介绍性能调优方法。

调优思路

性能调优需要遵循科学的流程:

调优原则

  • 先监控后调优,避免盲目修改
  • 单一变量原则,每次只修改一个参数
  • 记录修改前后数据,对比效果
  • 生产环境修改前先在测试环境验证

JVM 调优

JVM 内存模型

RocketMQ Broker 的 JVM 内存模型如下:

Broker JVM 配置

修改 bin/runbroker.sh 文件:

# 推荐配置(16GB 内存机器)
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"

# 大内存机器(32GB+ 内存)
JAVA_OPT="${JAVA_OPT} -server -Xms16g -Xmx16g -Xmn8g"

# GC 配置
JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m"
JAVA_OPT="${JAVA_OPT} -XX:InitiatingHeapOccupancyPercent=45"
JAVA_OPT="${JAVA_OPT} -XX:MaxGCPauseMillis=200"

# 元空间配置
JAVA_OPT="${JAVA_OPT} -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

# 直接内存配置(重要)
JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=4g"

# GC 日志
JAVA_OPT="${JAVA_OPT} -Xlog:gc*:file=/dev/shm/mq_gc.log:time,tags:filecount=5,filesize=30m"

NameServer JVM 配置

修改 bin/runserver.sh 文件:

# NameServer 内存需求较小
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g"
JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC"

JVM 参数详解

参数说明推荐值
-Xms堆内存初始大小与 -Xmx 相同,避免动态扩容
-Xmx堆内存最大值机器内存的 50% 左右
-Xmn年轻代大小堆内存的 40%-50%
-XX:MaxDirectMemorySize直接内存最大值与消息传输量相关
-XX:+UseG1GC使用 G1 垃圾收集器JDK 9+ 默认
-XX:MaxGCPauseMillisGC 最大停顿时间200ms

GC 调优

G1 GC 配置建议

# G1 基础配置
-XX:+UseG1GC
-XX:G1HeapRegionSize=16m # Region 大小
-XX:InitiatingHeapOccupancyPercent=45 # 触发并发 GC 的堆占用率
-XX:MaxGCPauseMillis=200 # 最大 GC 停顿时间
-XX:G1ReservePercent=10 # 保留空间百分比
-XX:G1HeapWastePercent=5 # 允许浪费的堆百分比

# 并发线程数
-XX:ConcGCThreads=4 # 并发 GC 线程数
-XX:ParallelGCThreads=8 # 并行 GC 线程数

GC 日志分析

# 查看 GC 日志
tail -f ~/logs/rocketmqlogs/gc.log

# 关注指标
# - GC 频率
# - GC 停顿时间
# - 老年代增长速度

操作系统调优

内核参数优化

修改 /etc/sysctl.conf

# 网络参数优化
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768

# TCP 参数优化
net.ipv4.tcp_max_syn_backlog = 65536
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 30

# 文件描述符限制
fs.file-max = 1000000

# 内存参数
vm.swappiness = 10
vm.dirty_ratio = 80
vm.dirty_background_ratio = 5

应用配置:

sysctl -p

文件描述符限制

修改 /etc/security/limits.conf

# 添加以下内容
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536

验证:

ulimit -n
# 输出: 65536

磁盘 IO 优化

1. 选择合适的磁盘

磁盘类型随机读 IOPS顺序写吞吐适用场景
HDD80-150150 MB/s低成本存储
SATA SSD80,000+500 MB/s一般生产环境
NVMe SSD500,000+3000 MB/s高性能场景

2. 文件系统选择

推荐使用 XFS 文件系统:

# 格式化磁盘
mkfs.xfs -f /dev/sdb

# 挂载选项
mount -o noatime,nodiratime,allocsize=64k /dev/sdb /data

3. IO 调度算法

# 查看当前调度算法
cat /sys/block/sdb/queue/scheduler

# 设置为 noop(SSD 推荐)
echo noop > /sys/block/sdb/queue/scheduler

内存优化

1. 关闭 Swap

# 临时关闭
swapoff -a

# 永久关闭,修改 /etc/fstab,注释 swap 行
# 或设置 swappiness
sysctl vm.swappiness=0

2. 使用大页内存

# 查看大页内存
cat /proc/meminfo | grep Huge

# 设置大页内存
echo 2048 > /proc/sys/vm/nr_hugepages

Broker 调优

存储配置

修改 conf/broker.conf

# 存储路径配置
storePathRootDir = /data/rocketmq/store
storePathCommitLog = /data/rocketmq/store/commitlog
storePathConsumeQueue = /data/rocketmq/store/consumequeue
storePathIndex = /data/rocketmq/store/index

# CommitLog 文件大小
mappedFileSizeCommitLog = 1073741824 # 1GB

# ConsumeQueue 文件大小
mappedFileSizeConsumeQueue = 300000

# 刷盘配置
flushDiskType = ASYNC_FLUSH # 异步刷盘,性能更好

# 刷盘间隔
flushCommitLogTimed = true
flushCommitLogInterval = 500 # 500ms 刷盘一次

# 消费队列刷盘
flushConsumeQueueThoroughInterval = 60000 # 60秒

线程池配置

# 发送消息线程池
sendMessageThreadPoolNums = 16 # 发送线程数

# 拉取消息线程池
pullMessageThreadPoolNums = 16 # 拉取线程数

# 查询消息线程池
queryMessageThreadPoolNums = 8

# 管理线程池
adminBrokerThreadPoolNums = 16

# 客户端管理线程池
clientManageThreadPoolNums = 32

# 消费者管理线程池
consumerManageThreadPoolNums = 32

内存配置

# TransientStorePool 配置(堆外内存)
transientStorePoolEnable = true
transientStorePoolSize = 5 # 堆外内存池大小

# 消息索引配置
maxHashSlotNum = 2000000
maxIndexNum = 20000000

# 消息过滤配置
enableCalcFilterBitMap = true
expectConsumerNumUseFilter = 32
maxErrorRateOfBloomFilter = 20

网络配置

# 监听端口
listenPort = 10911

# HA 端口
haListenPort = 10912

# 发送消息缓冲区大小
socketSendBuffer = 65535

# 接收消息缓冲区大小
socketReceiveBuffer = 65535

# 服务端 Socket 超时
serverSocketRcvBufSize = 131072
serverSocketSndBufSize = 131072

# 客户端连接数限制
maxConnectionNumPerIp = 100

消息相关配置

# 最大消息大小
maxMessageSize = 4194304 # 4MB

# 消息压缩阈值
compressMsgBodyOverHowmuch = 4096 # 超过 4KB 压缩

# 消息轨迹开关
traceTopicEnable = false

# 消息定时清理
deleteWhen = 04 # 凌晨 4 点清理
fileReservedTime = 72 # 保留 72 小时

# 物理磁盘使用率告警阈值
diskMaxUsedSpaceRatio = 75

性能基准测试

测试工具

RocketMQ 提供了性能测试工具:

# 生产者性能测试
sh bin/mqadmin producer -n localhost:9876 -t TopicTest -w 64 -s 1024

# 消费者性能测试
sh bin/mqadmin consumer -n localhost:9876 -t TopicTest -g TestGroup -w 64

参数说明

参数说明
-nNameServer 地址
-tTopic 名称
-g消费组名称
-w线程数
-s消息大小(字节)

性能指标

典型性能数据

测试环境

  • 机器配置:16 核 CPU,32GB 内存,NVMe SSD
  • 消息大小:1KB
  • 线程数:64

性能数据参考

场景发送 TPS消费 TPS平均延迟
单 Master80,000+60,000+< 5ms
异步复制70,000+55,000+< 10ms
同步双写50,000+45,000+< 15ms

常见性能问题

1. 发送消息延迟高

可能原因

  • 磁盘 IO 性能不足
  • GC 频繁导致停顿
  • 网络带宽不足
  • 线程池配置不合理

排查步骤

# 1. 检查磁盘 IO
iostat -x 1

# 2. 检查 GC 日志
tail -f ~/logs/rocketmqlogs/gc.log

# 3. 检查网络带宽
iftop -i eth0

# 4. 检查线程池状态
sh bin/mqadmin brokerStatus -n localhost:9876 -b broker-a

2. 消息堆积

可能原因

  • 消费者处理能力不足
  • 消费者数量不够
  • 下游系统响应慢
  • 消息处理逻辑耗时

解决方案

# 1. 增加消费者实例
# 2. 增加消费线程数
consumer.setConsumeThreadMin(64);
consumer.setConsumeThreadMax(128);

# 3. 优化消费逻辑
# - 减少数据库访问次数
# - 使用批量处理
# - 异步化非核心逻辑

# 4. 临时丢弃非重要消息
sh bin/mqadmin resetOffsetByTime -n localhost:9876 -g GroupName -t TopicName -s -1

3. 内存溢出

可能原因

  • 堆内存设置过小
  • 消息堆积导致内存占用
  • Direct Memory 不足

解决方案

# 1. 调整堆内存
-Xms8g -Xmx8g

# 2. 调整 Direct Memory
-XX:MaxDirectMemorySize=4g

# 3. 开启堆外内存池
transientStorePoolEnable = true

# 4. 分析内存快照
jmap -dump:format=b,file=heap.hprof <pid>

调优配置清单

JVM 配置清单

  • 堆内存大小设置为机器内存的 50% 左右
  • 年轻代大小设置为堆内存的 40%-50%
  • 使用 G1 垃圾收集器
  • 设置合适的 MaxDirectMemorySize
  • 开启 GC 日志

操作系统配置清单

  • 关闭 Swap 或设置 vm.swappiness=10
  • 增加文件描述符限制
  • 优化网络内核参数
  • 使用 XFS 文件系统
  • SSD 使用 noop 调度算法

Broker 配置清单

  • 设置合适的刷盘方式
  • 调整线程池大小
  • 开启堆外内存池
  • 设置消息保留时间
  • 配置磁盘告警阈值

小结

本章介绍了 RocketMQ 的性能调优方法:

  1. JVM 调优:堆内存、GC、直接内存配置
  2. 操作系统调优:内核参数、文件描述符、磁盘 IO
  3. Broker 调优:存储、线程池、网络配置
  4. 性能测试:基准测试工具和指标
  5. 问题排查:常见性能问题的原因和解决方案

性能调优是一个持续的过程,需要根据实际业务场景不断调整和优化。

延伸阅读