1.1 物联网MQTT单机压测130万参数调优
2019年1月,我的一项工作就是为公司搭建一套独立于阿里云之外的自己的物联网MQTT集群。MQTT是非常适合物联网场景的,它可以保持设备与服务器的长连接,避免反复轮询,并支持推送。和数据库连接池一样,它同样运行于TCP协议之上,MQTT相比HTTP具有协议开销低、容忍弱网络、低功耗、百万并发等优点。但是由于当前的阿里云MQTT不支持will、retain msg、QOS2,并且存在限流、断连等不稳定因素,自建MQTT集群这件事就显得格外重要。
在调研了Eclipse Mosquitto后,我又在EMQ(Erlang/Enterprise/Elastic MQTT Broker)的官网上发现了这么一段描述:“EMQ消息服务器1.x版本MQTT连接压力测试到130万,在一台8核心、32G内存的CentOS服务器上。”经过梳理后我认为,它的服务端调优主要分为Linux操作系统参数调优和TCP协议栈网络参数调优两部分。
Linux操作系统参数调优如下:
1)系统全局允许分配的最大文件句柄数。
sysctl -w fs.file-max=2097152 sysctl -w fs.nr_open=2097152 echo 2097152 > /proc/sys/fs/nr_open
2)允许当前会话或进程打开文件句柄数。
ulimit -n 1048576
TCP协议栈网络参数调优如下:
1)并发连接backlog设置。
sysctl -w net.core.somaxconn=32768 sysctl -w net.ipv4.tcp_max_syn_backlog=16384 sysctl -w net.core.netdev_max_backlog=16384
2)TCP Socket读写Buffer设置。
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_mem='167772161677721616777216' sysctl -w net.ipv4.tcp_rmem='1024409616777216' sysctl -w net.ipv4.tcp_wmem='1024409616777216'
3)TCP连接追踪设置。
sysctl -w net.nf_conntrack_max=1000000 sysctl -w net.netfilter.nf_conntrack_max=1000000 sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
4)TIME-WAITSocket最大数量、回收与重用设置。
net.ipv4.tcp_max_tw_buckets=1048576 # 注意: 不建议开启該设置,NAT模式下可能引起连接RST # net.ipv4.tcp_tw_recycle = 1 # net.ipv4.tcp_tw_reuse = 1
5)FIN-WAIT-2 Socket超时设置。
net.ipv4.tcp_fin_timeout = 15
TCP/IP参考模型可以分为应用层、传输层、网络层、链路层。TCP和UDP在传输层,应用层除了刚才我们介绍的MQTT,还有HTTP、FTP等。因为MQTT运行于TCP协议之上,所以它的调优也离不开TCP的参数调优,数据库连接池的出现也是为了解决应用与数据库之间TCP的性能问题,当前很多应用,比如服务端和算法服务的交互也离不开TCP的传输。所以了解TCP的调优方式可以夯实这个技术领域调优的基础,一通百通。
光阴荏苒,日月如梭,MQTT的这段调优配置不禁让我回想起了4年前在阿里巴巴公司做的将TCP中间件服务的QPS从百级提升到万级的全链路压测与技术改造的那件往事。