EMQX 开源版三节点集群,创建600个规则动作左右后,集群崩溃

  • 版本:开源版 5.8.6

创建 600 个规则动作左右后,无法创建规则,内存和CPU占用高,集群崩溃

动作是 HTTP 动作,向 TDengine 写入 SQL 的插入语句

  • 前言
    • 已做过系统调优
    • 防火墙是开放的
    • 没有 nginx 转发相关端口,不会受限于 nginx 的连接数设置

集群节点(配置都一样)参数:内存 16GB;CPU 是 C86 的,架构为 x86_64,4 core

不太懂内部机制,还望大佬们帮我看一看

内存的占用忽高忽低,如果是erlang申请内存的行为,申请的内存是否有点大

  1. 占用低的时候


  1. 占用高的时候


  1. 崩溃日志

emqx.log.zip (111.5 KB)

  1. 崩溃 dump

erl_crash.dump.7z.zip (3.7 MB)

  1. 系统调优相关
swapoff -a
cat << EOF > /etc/sysctl.d/optimize.conf
vm.mmap_min_addr = 65536
vm.max_map_count = 655360
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 18446744073692774399
kernel.shmall = 18446744073692774399

fs.file-max = 9223372036854775807
fs.nr_open = 1073741816
fs.aio-max-nr = 1073741816
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 1024
net.core.netdev_max_backlog = 25000
net.ipv4.ip_local_port_range = 10000 65535
net.core.rmem_default = 67108864
net.core.wmem_default = 67108864
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.optmem_max = 20480

net.ipv4.tcp_rmem = 16384 26214400 26214400
net.ipv4.tcp_wmem = 32768 26214400 26214400
net.ipv4.udp_mem = 374394 26214400 26214400

net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_established = 3600
net.nf_conntrack_max = 1048576

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_window_scaling=1
net.ipv4.tcp_fin_timeout = 30

# Linux > 4.9
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
sysctl --system
sed -i s'|.*DefaultLimitNOFILE=.*|DefaultLimitNOFILE=1073741816:1073741816|' /etc/systemd/system.conf /etc/systemd/user.conf
sed -i s'|.*DefaultLimitCORE=.*|DefaultLimitCORE=infinity|' /etc/systemd/system.conf /etc/systemd/user.conf
sed -i s'|.*DefaultLimitNPROC=.*|DefaultLimitNPROC=1073741816|' /etc/systemd/system.conf /etc/systemd/user.conf
systemctl daemon-reload

cat << EOF > /etc/security/limits.conf
*      soft   nofile      1024000
*      hard   nofile      1024000
*      soft   nproc       127671
*      hard   nproc       127671
*      soft   stack       262140
*      hard   stack       262140
EOF

每个规则都可以(高级)配置中设置他的 buffer(缓存队列最大长度),默认是 256M,你有 600 个,要是规则处理不及时,理论上会最大申请可以到 600*256M 的空间。
占用高的时候,就是 buffer 里面的数据太多了(看 observer_cli里面全是 buffer worker)。

PS:600 个规则最好还是优化一下,不要搞这么规则,想象一下每来一条消息都得给所有规则匹配一下,肯定也非常消耗 CPU。
如果实在业务需要,就用配置高一点的服务器。4 core 太小了,先试试来个 32core。

哦哦,明白了,那我设置 “MQTT 配置” 里面,保留消息的存储方式为 disc,是不是可以解决内存的问题

不行,保留消息和这个不是一样意思。

好的,感谢解答