Hero Image
調整系統使得 EMQX 可以支援 1M 連線

Tuning EMQX to Scale to One Million Concurrent Connection on Kubernetes Performance Tuning (Linux) 矽谷牛的耕田筆記 Linux Kernel Tuning node level, basically the non-namespaced sysctls # Sets the maximum number of file handles allowed by the kernel sysctl -w fs.file-max=2097152 # Sets the maximum number of open file descriptors that a process can have sysctl -w fs.nr_open=2097152 namespaced sysctls # Sets the maximum number of connections that can be queued for acceptance by the kernel. sysctl -w net.core.somaxconn=32768 # Sets the maximum number of SYN requests that can be queued by the kernel sysctl -w net.ipv4.tcp_max_syn_backlog=16384 # Setting the minimum, default and maximum size of TCP Buffer sysctl -w net.ipv4.tcp_rmem='1024 4096 16777216' sysctl -w net.ipv4.tcp_wmem='1024 4096 16777216' # Setting Parameters for TCP Connection Tracking sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30 # Controls the maximum number of entries in the TCP time-wait bucket table sysctl -w net.ipv4.tcp_max_tw_buckets=1048576 # Controls Timeout for FIN-WAIT-2 Sockets: sysctl -w net.ipv4.tcp_fin_timeout=15 There are some more namespaced sysctls that will improve the performance but because of an active issue we are not able to set them on the container level # Sets the size of the backlog queue for the network device sysctl -w net.core.netdev_max_backlog=16384 # Amount of memory that is allocated for storing incoming and outgoing data for a socket sysctl -w net.core.rmem_default=262144 sysctl -w net.core.wmem_default=262144 # Setting the maximum amount of memory for the socket buffers sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.wmem_max=16777216 sysctl -w net.core.optmem_max=16777216 Erlang VM Tuning ## Erlang Process Limit node.process_limit = 2097152 ## Sets the maximum number of simultaneously existing ports for this system node.max_ports = 2097152 EMQX Broker Tuning # Other configuration… EMQX_LISTENER__TCP__EXTERNAL: "0.0.0.0:1883" EMQX_LISTENER__TCP__EXTERNAL__ACCEPTORS: 64 EMQX_LISTENER__TCP__EXTERNAL__MAX_CONNECTIONS: 1024000

Hero Image
Golang tips

GO 编程模式:切片,接口,时间和性能 Go 语言是一个高性能的语言,但并不是说这样我们就不用关心性能了,我们还是需要关心的。下面是一个在编程方面和性能相关的提示。 如果需要把数字转字符串,使用 strconv.Itoa() 会比 fmt.Sprintf() 要快一倍左右 尽可能地避免把 String 转成[]Byte 。这个转换会导致性能下降。 如果在 for-loop 里对某个 slice 使用 append()请先把 slice 的容量很扩充到位,这样可以避免内存重新分享以及系统自动按 2 的 N 次方幂进行扩展但又用不到,从而浪费内存。 使用 StringBuffer 或是 StringBuild 来拼接字符串,会比使用 + 或 += 性能高三到四个数量级。 尽可能的使用并发的 go routine,然后使用 sync.WaitGroup 来同步分片操作 避免在热代码中进行内存分配,这样会导致 gc 很忙。尽可能的使用 sync.Pool 来重用对象。 使用 lock-free 的操作,避免使用 mutex,尽可能使用 sync/Atomic 包。 (关于无锁编程的相关话题,可参看《无锁队列实现》或《无锁 Hashmap 实现》) 使用 I/O 缓冲,I/O 是个非常非常慢的操作,使用 bufio.NewWrite() 和 bufio.NewReader() 可以带来更高的性能。 对于在 for-loop 里的固定的正则表达式,一定要使用 regexp.Compile() 编译正则表达式。性能会得升两个数量级。 如果你需要更高性能的协议,你要考虑使用 protobuf 或 msgp 而不是 JSON,因为 JSON 的序列化和反序列化里使用了反射。