一、测试目的
测试EMQ X企业版4.3.5单节点每秒10万QoS 1、payload 200B的消息持久化缓存至Redis所需EMQ X资源及响应时间等性能指标。
二、测试架构
三、测试环境、机器配置及测试工具
测试环境:腾讯云南京区VPC
测试工具:Xmeter企业版v3.0
EMQX、Kafka集群配置、测试机配置:
服务 数量 版本 操作系统 CPU 内存 云主机型号 EMQX 1 4.3.5 Centos7.8 64核 128G C5.16XLARGE128 Redis 1 6.2.5 Centos7.8 32核 128G C5.16XLARGE128 XMeter管理机 2 3.0 Centos7.3 8核 16G C5.16XLARGE16 XMeter压力机 10 / Centos7.3 32核 32G C5.16XLARGE32
四、测试场景
如测试架构图中所示,XMeter压力机模拟10万MQTT客户端向EMQ X发起连接,新增连接速率为每秒5000,客户端心跳间隔(keep alive)300秒。所有连接成功后每个客户端每秒发送一条QoS为1、payload为200B的消息,所有消息通过规则引擎桥持久化发至Redis节点。这里Redis配置为消息缓存数据库(即消息总量超过Redis配置的最大内存限制,将按照相应机制删除Redis中的消息)。
测试执行1个小时。
规则引擎配置如下:
Redis资源配置
Redis规则设置
采用Hash结构存储消息
对Redis的 Hash存储进行ziplist优化,配置详见附录4
五、测试结果
具体测试结果及EMQ X资源使用截图如下:
EMQ X Dashboard统计:
EMQX规则引擎统计:
EMQX Doshborad消息数统计:
从EMQ X Dashboard上统计的测试期间的消息数,和规则上的命中次数、成功数一致。
Redis数据库收到的消息数量:
因为本场景中,Redis配置为缓存数据库。当消息总量超过redis最大内存限制,Redis中的多余消息会被删除。所以这里看到Redis中消息数量小于EMQ X 统计的消息数目。
EMQX节点资源使用:
XMeter测试报告截图:
六、测试总结
如以上结果所示,EMQ X 64C128G配置下可以支持10万连接、每秒10万QoS 1、payload 200B的消息缓存至Redis,消息吞吐期间,EMQ X所在机器CPU user平均67%,CPU idle平均20%。
附录1:操作系统调优
可参考:https://docs.emqx.io/enterprise/latest/cn/tutorial/tune.html
亦可直接sh附录3中的文件sys_tune.sh。
附录2:测试工具试用、下载地址
XMeter简介 (https://www.xmeter.net/):XMeter是基于开源测试工具JMeter扩展的性能测试平台。针对物联网具有的接入规模大、弹性扩展要求、多种接入协议、混合场景等特点,XMeter对JMeter进行了改造,实现了百万级别并发测试支持,并对测试数据进行实时处理并图形化展示。
XMeter官网和试用地址:https://www.xmeter.net/
XMeter MQTT插件下载:https://github.com/xmeter-net/mqtt-jmeter
JMeter下载地址:https://jmeter.apache.org
附录3:系统调优脚本
#!/bin/sh ## Linux Kernel Tuning sysctl -w fs.file-max=2097152 sysctl -w fs.nr_open=2097152 echo 2097152 > /proc/sys/fs/nr_open echo 2097152 > /proc/sys/fs/file-max ## The limit on opened file handles for current session ulimit -n 1048576 ## Add the ‘fs.file-max’ to /etc/sysctl.conf, make the changes permanent ## /etc/security/limits.conf ## ## ## * soft nofile 1048576 ## * hard nofile 1048576 cat <<- 'EOF' >> /etc/security/limits.conf * soft nofile 1048576 * hard nofile 1048576 EOF ## Network Tuning ## Increase number of incoming connections backlog sysctl -w net.core.somaxconn=32768 sysctl -w net.ipv4.tcp_max_syn_backlog=16384 sysctl -w net.core.netdev_max_backlog=16384 ## Local Port Range: sysctl -w net.ipv4.ip_local_port_range=1000 65535 ## Read/Write Buffer for TCP connections: sysctl -w net.core.rmem_default=262144 sysctl -w net.core.wmem_default=262144 sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.wmem_max=16777216 sysctl -w net.core.optmem_max=16777216 sysctl -w net.ipv4.tcp_rmem=1024 4096 16777216 sysctl -w net.ipv4.tcp_wmem=1024 4096 16777216 ## Timeout for FIN-WAIT-2 sockets: sysctl -w net.ipv4.tcp_fin_timeout=15 cat <<- 'EOF' >> /etc/sysctl.confnet.core.somaxconn=32768n et.ipv4.tcp_max_syn_backlog=16384 net.core.netdev_max_backlog=16384 net.ipv4.ip_local_port_range=1000 65535 net.core.rmem_default=262144 net.core.wmem_default=262144 net.core.rmem_max=16777216 net.core.wmem_max=16777216 net.core.optmem_max=16777216 net.ipv4.tcp_rmem=1024 4096 16777216 net.ipv4.tcp_wmem=1024 4096 16777216 net.ipv4.tcp_max_tw_buckets=1048576 net.ipv4.tcp_fin_timeout=15 EOF
附录4:Redis配置
bind * protected-mode no port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes pidfile /var/run/redis_6379.pid loglevel notice logfile "/var/log/redis.log" databases 16 always-show-logo no set-proc-title yes proc-title-template "{title} {listen-addr} {server-mode}" save "" stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb rdb-del-sync-files no dir ./ replica-serve-stale-data yes replica-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-diskless-load disabled repl-disable-tcp-nodelay no replica-priority 100 acllog-max-len 128 maxmemory 40gb maxmemory-policy allkeys-random lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no lazyfree-lazy-user-del no lazyfree-lazy-user-flush no oom-score-adj no oom-score-adj-values 0 200 800 disable-thp yes appendonly no appendfilename "appendonly.aof "appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 50000 hash-max-ziplist-value 5000 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 stream-node-max-bytes 4096 stream-node-max-entries 100 activerehashing yesclient-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 dynamic-hz yes aof-rewrite-incremental-fsync yes rdb-save-incremental-fsync yes jemalloc-bg-thread yes