RocketMQ Performance Test

测试环境

硬件配置4C 4G SSD
操作系统centeOS 6.5
MQ版本rocketmq-broker-4.2.0-incubating-SNAPSHOT (2017-08-23)

测试程序运行机器:Macbook Pro i7 2.3GHz, 16G

单Broker场景

单broker同步发送(单发送进程),每条message大小:30bytes

NameServer与Broker分别在不同机器部署,broker采用异步持久化

topic设置:
    perm: 6
JVM设置:
    NameServer: -Xms1g -Xmx1g -Xmn512m
    Broker: -Xms2g -Xmx2g -Xmn1g
发送条数成功率耗时(s)发送速率(条/秒)备注
100000100%74.2651346.52写queue数量:4
100000100%75.3471327.22写queue数量:8

结论

成功率非常有保证,调整topic的queue数量并不能提升发送速率。broker的能力并没有完全被发挥出来,CPU非常闲。

单broker异步发送(单发送进程),每条message大小:30bytes

NameServer与Broker分别在不同机器部署,broker采用异步持久化

topic设置:
    perm: 6
JVM设置:
    NameServer: -Xms1g -Xmx1g -Xmn512m
    Broker:    -Xms2g -Xmx2g -Xmn1g
发送条数成功率耗时(s)发送速率(条/秒)备注
1000000100%33.42029922.20写queue数量:4,每发送37条休眠一毫秒,限制生产者速度不超过37000条/秒
100000096.6024%20.87146285.46写queue数量:4,发送端不限速
1000000100%33.47729871.25写queue数量:8,每发送37条休眠一毫秒,限制生产者速度不超过37000条/秒
100000097.9327%22.96148844.23写queue数量:8,发送端不限速

结论

  1. 吞吐量较大时,会触发broker端的流控限制,会导致消息发送失败,出现异常:Rocketmq:MQBrokerException: CODE: 2 DESC: [TIMEOUT_CLEAN_QUEUE]
  2. 通过多次反复测试,发现在保证发送成功率100%的情况下,发送速率最大为29922.20条/秒,测试过程中,测试程序最大上传网速达到15.9MB/s
  3. 在成功率100%的情况下,吞吐量是同步发送的超20倍。不限速(允许少量失败)的情况下,吞吐量是同步发送的超34倍。
  4. 在单发送进程场景下,增加topic的queue数量并不能提升生产速率。

发现的问题(或BUG)

测试发现producer.shutdown()时,并没有完全等待SendCallBack执行完就退出,可能会导致有部分callback无法接收到。因此在在测试程序异步发送完成之后,还需要添加一个线程休眠,确保全部消息全部发送到broker。

单broker消费(单消费进程),每条message大小:30bytes

NameServer与Broker分别在不同机器部署

topic设置:
    perm: 6
JVM设置:
    NameServer: -Xms1g -Xmx1g -Xmn512m
    Broker:    -Xms2g -Xmx2g -Xmn1g
consumer设置:
    consumeThreadMax: 64
    pullBatchSize: 32
消费条数成功率耗时(s)消费速率(条/秒)备注
3000000100%21.353140495.48读queue数量:8
3000000100%34.37187282.88读queue数量:4

结论

  1. RocketMQ的消息消费能力非常高,只要消费端的业务处理足够快。单broker的消费超过7w条每秒,基本上可以说满足大部分的实际业务场景。
  2. 增加topic的queue数量,能明显提高消费速率。(前提是生产的消息要平均分布在各个queue)
  3. 从测试环境看,消费高峰每秒下载流量超过31MB,Broker的CPU会占用维持在50%左右,消费过程中CPU的IOWait在某一瞬间会超过20%

单broker消费(双消费进程),每条message大小:30bytes

NameServer与Broker分别在不同机器部署

topic设置:
    读队列数量:4
    写队列数量:4
    perm: 6
JVM设置:
    NameServer: -Xms1g -Xmx1g -Xmn512m
    Broker:    -Xms2g -Xmx2g -Xmn1g
consumer设置:
    consumeThreadMax: 64
    pullBatchSize: 32
消费条数成功率耗时(s)消费速率(条/秒)
消费进程 11000000100%22.54944347.86
消费进程21000000100%21.36046796.76

结论

增加消费者进程并不能提高整体的消费速度,因为消费者本身就是多线程的模式消费。但可以通过增加消费者进程来提升消费端高可用能力,避免消费端的单点故障。

多Master Broker场景

双Master Broker 同步发送,每条message大小:30bytes

三台主机,一台部署NameServer,另外两台各部署Broker master

topic设置:
    perm: 6
JVM设置:
    NameServer: -Xms1g -Xmx1g -Xmn512m
    Broker: -Xms2g -Xmx2g -Xmn1g
发送条数成功率耗时(s)发送速率(条/秒)备注
100000100%66.8451495.99每个broker4个queue

结论

同步发送速率双Master Borker与单broker基本在一个数量级 双Master Broker 异步发送(单发送进程),每条message大小:30bytes

三台主机,一台部署NameServer,另外两台各部署Broker master

topic设置:
    perm: 6
JVM设置:
    NameServer: -Xms1g -Xmx1g -Xmn512m
    Broker: -Xms2g -Xmx2g -Xmn1g
Broker设置:
    为提高成功率,将waitTimeMillsInSendQueue的默认值从200调整到1000
发送条数成功率耗时(s)发送速率(条/秒)备注
1000000100%20.86247934.04每个broker各4个queue, 每发送70条休眠1毫秒,确保每秒发送数量不超过7w条
1000000100%20.61648506.01每个broker各8个queue, 每发送70条休眠1毫秒,确保每秒发送数量不超过7w条
100000099.7571%16.02662247.03每个broker各4个queue,生产者不限速
100000099.8807%17.10858,382.45每个broker各8个queue,生产者不限速

结论

  1. 在保证成功率100%的情况下,双master broker比单broker的发送速率明显提高,提升超60%
  2. 增加topic的queue数量,但发送进程并不能提高发送速率

双broker消费(单消费进程),每条message大小:30bytes

三台主机,一台部署NameServer,另外两台各部署Broker master

topic设置:
    perm: 6
JVM设置:
    NameServer: -Xms1g -Xmx1g -Xmn512m
    Broker:    -Xms2g -Xmx2g -Xmn1g
consumer设置:
    consumeThreadMax: 64
    pullBatchSize: 32
消费条数成功率耗时(s)消费速率(条/秒)备注
2000000100%11.170179051.02读queue数量:4
3000000100%11.979250438.26读queue数量:8

结论

  1. 由于topic在每个broker上都有4个queue,发送的消息基本是均匀分配在两个broker的,因此在消费时能从两个broker分别进行消费,消费速率较单broker的消费提升了近1倍。
  2. 增大topic的queue数量,明显能提高消费速率。

双Master双Slave异步复制,异步发送,每条message大小:30bytes

五台主机,一台部署NameServer,两台分别部署broker-a-master、broker-a-slave,两台分别部署broker-b-master、broker-b-slave。

topic设置:
    perm: 6
JVM设置:
    NameServer: -Xms1g -Xmx1g -Xmn512m
    Broker: -Xms2g -Xmx2g -Xmn1g
Broker设置:
    master broker设置: brokerRole=ASYNC_MASTER
发送条数成功率耗时(s)发送速率(条/秒)备注
100000100%20.75548181.16每个broker各8个queue,每发送70条休眠1毫秒,确保每秒发送数量不超过7w条

结论

  1. Master与Slave采用异步复制时,基本不影响消息发送的吞吐量。
  2. 发送100w条消息到broker后(平均分配到broker-a与broker-b),关掉broker-b-master,启动消费者时,如果订阅组之前不存在,则不能从broker-b-slave上进行消费。如果订阅组存在,则能从broker-b-slave上进行消费,但当broker-b-master恢复之后,会重复消费broker-b-master上的消息。

发现的问题(或BUG)

在slave上进行消费时,消费的offset近保存到了slave上,当master恢复时,slave上的消费offset并没有被同步到master上,master上的offset还是最初在master上的消费位置,因此会导致master故障期间从slave上消费的消息会被重复消费。这应该不是RocketMQ的设计初衷,感觉像是个bug。

RocketMQ vs Kafka

  1. RocketMQ与Kafka一样,都没有JMS中定义的Queue的存在,只有Topic的存在。但他们都可以基于Topic来实现Queue的功能与特性。
  2. RocketMQ可以创建只有1个queue的topic,再结合Cluster的消费方式来实现JMS queue的功能与特性。
  3. Kafka则可以创建只有一个partition的topic来实现JMS Queue的功能与特性。
  4. RocketMQ中queue的概念可类比为Kafka中的partition,若要实现消息的强顺序消费,RocketMQ需要设置topic只有一个queue,Kafka则需要设置topic只有一个partition。
  5. 若业务规定只需保证同一订单编号的状态变更的顺序性,RocketMQ可以在发送时通过订单编号与MessageQueueSelector来实现同一编号的订单消息放置在topic的同一个queue中,Kafka则可以将订单编号作为消息的key来确保同一编号的订单消息放置在了同一个partition。

   转载规则


《RocketMQ Performance Test》 Angus_Lu 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
高可用HDFS搭建 高可用HDFS搭建
HDFS+HA架构图上图大致架构包括:利用共享存储来在两个NN间同步edits信息。以前的HDFS是share nothing but NN,现在NN又share storage,这样其实是转移了单点故障的位置,但中高端的存储设备内部都有各
2018-01-30 19:12:21
下一篇 
JVM内存结构简介 JVM内存结构简介
Java运行时内存结构+-------------------------------------------------+ | Runtime Memory Structure Chart | | +-
2018-01-10 11:34:55
  目录