在单台服务器承载数十万并发的情况下,影响服务器接入能力的因素已经不在是CPU、内存、带宽等表层因素,而是内核参数、设备配置、应用优化等多种细节因素。
1、最大打开文件数
Linux 中所有内容都是以文件的形式保存和管理的, 包括套接字、网络通信等资源,即一切皆文件,因此提升最大打开文件数是提高服务器并发性能的重要一步。
Linux的最大打开文件数限制包括系统级(系统可打开的最大文件数)、用户级(单个用户可打开的最大文件数)、进程级(单个进程可打开的最大文件数),可分别通过如下方式修改:
- # 系统级
- # 默认值为内存总量的10%, 需根据内存大小设置
- echo "fs.file-max=XXXX" >> /etc/sysctl.conf
- sysctl -p
-
- # 用户级
- # 默认值为1024, 可通过ulimit -n查看, 重新登录生效
- echo "* soft nofile 102400" >> /etc/security/limits.conf
- echo "* hard nofile 102400" >> /etc/security/limits.conf
-
- # 进程级
- # 默认值为1048576
- echo "fs.nr_open=XXXX" >> /etc/sysctl.conf
- sysctl -p
2、nf_conntrack
对开启iptables的服务器,iptables的connection-tracking模块使用系统内存的一部分来跟踪表中的连接。nf_conntrack表中记录了服务器的所有连接细节。
- # conntrack -L 或
- # cat /proc/net/nf_conntrack
- ipv4 2 udp 17 135 src=10.0.2.15 dst=192.168.61.200 sport=52162 dport=53 src=192.168.61.200 dst=10.0.2.15 sport=53 dport=52162 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
- ipv4 2 tcp 6 431999 ESTABLISHED src=10.0.2.2 dst=10.0.2.15 sport=19365 dport=22 src=10.0.2.15 dst=10.0.2.2 sport=22 dport=19365 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
- ipv4 2 udp 17 142 src=10.0.2.15 dst=178.215.228.24 sport=123 dport=123 src=178.215.228.24 dst=10.0.2.15 sport=123 dport=123 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
- ipv4 2 udp 17 16 src=10.0.2.15 dst=192.168.61.200 sport=54059 dport=53 src=192.168.61.200 dst=10.0.2.15 sport=53 dport=54059 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
- ipv4 2 udp 17 142 src=10.0.2.15 dst=202.118.1.130 sport=123 dport=123 src=202.118.1.130 dst=10.0.2.15 sport=123 dport=123 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
- ipv4 2 udp 17 142 src=10.0.2.15 dst=193.182.111.143 sport=123 dport=123 src=193.182.111.143 dst=10.0.2.15 sport=123 dport=123 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
- ipv4 2 udp 17 76 src=10.0.2.15 dst=192.168.61.200 sport=60831 dport=53 src=192.168.61.200 dst=10.0.2.15 sport=53 dport=60831 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
在高并发场景下,该表条目数可能达到最大值,而造成网络丢包。因此需要增加连接跟踪条目的最大数量。调整方法参考华为云文档:https://support.huaweicloud.com/intl/zh-cn/trouble-ecs/ecs_trouble_0324.html
CentOS 6系列操作系统处理方法
- # 执行以下命令,查看nf_conntrack_max参数。
- sysctl net.netfilter.nf_conntrack_max
-
- # 检查当前正在跟踪的连接数。
- cat /proc/sys/net/netfilter/nf_conntrack_count
-
- # 如果该值达到nf_conntrack_max值则会出现包被丢弃的现象。
- # 提高net.netfilter.nf_conntrack_max值(以内存为64G,net.netfilter.nf_conntrack_max值2097152为例)。
- # 执行以下命令,使配置即时生效。
- sysctl -w net.netfilter.nf_conntrack_max=2097152
-
- # 执行以下命令确保重启后配置仍然生效。
- echo "net.netfilter.nf_conntrack_max = 2097152" >> /etc/sysctl.conf
-
- # 说明:net.netfilter.nf_conntrack_max不是越高越好,通常根据内存大小进行设置。
- # nf_conntrack_max计算公式(64位)
- # CONNTRACK_MAX = RAMSIZE (inbytes)/16384/2
- # 例如你的机器是一个64GB 64bit的系统,那么最合适的值是
- # CONNTRACK_MAX = 64*1024*1024*1024/16384/2 = 2097152
- # 如果conntrack表中的条目数量显著增加(例如以4倍的速度增加),则还应增加存储conntrack条目的哈希表的大小以提高效率。
- # 计算新的哈希值:在CentOS 6及以上版本,计算公式是hashsize = conntrack_max/4
-
- # 执行以下命令,设置新的哈希大小。
- echo "options nf_conntrack expect_hashsize=131072 hashsize=131072" >/etc/modprobe.conf
-
- # 重启iptables。
- service iptables restart
CentOS 7系列操作系统处理方法
- # 执行以下命令,在/etc/modprobe.d/firewalld-sysctls.conf中设置conntrack条目的哈希值。
- # 在CentOS 6及以上版本,计算公式是hashsize = conntrack_max/4
- echo "options nf_conntrack expect_hashsize=131072 hashsize=131072" >> /etc/modprobe.d/firewalld-sysctls.conf
-
- # 重启firewalld。
- systemctl restart firewalld
-
- # 确认参数修改成功。
- sysctl -a |grep nf_conntrack_max
hashsize = conntrack_max/4,此表达式可看作较优设置,实际哈希表大小通常为总表的1/8~1/2。
https://www.kernel.org/doc/html/latest/networking/nf_conntrack-sysctl.html
3、网卡多队列
网卡多队列技术概述
当今的高档服务器上运行着更多的处理器,运行在其上的客户机所拥有的vCPU数量也越来越多。在单一的virtio-net队列中,由于网络性能无法随着vCPU的数量动态的伸缩,导致客户机的协议栈规模受限。因为传统的单virtio-net只有单一的TX(发送)和RX(接收)队列,客户机不能并行的传输和接收数据包。
为了解决这个问题,我们需要在nova启动的客户实例中加入网卡多队列的功能。virtio-net的数量根据客户机中vCPU的数量手动伸缩,从而提升系统的网络性能。
在下面这些场景时,网卡多队列提升了系统的性能:
- 传输的数据包变大;
- 客户机中同时存在多个网络连接;
- 客户机有多个vCPU,队列最大数与vCPU数量一致;
然而,网卡多队列受到一系列的限制且带来一些负面效果:
- 受限于MSI vector:message signal interrupt的数量;
- 有时会造成对外流量传输性能下降;
- 增加CPU负载;
- 多网卡情况下,多队列特性不那么重要。
不同的云厂商对此有不同的支持,可以参考厂商操作文档,例如:
- 华为云:https://support.huaweicloud.com/usermanual-ecs/zh-cn_topic_0058758453.html
- 移动云: https://ecloud.10086.cn/op-help-center/doc/article/23738
- 阿里云:https://help.aliyun.com/document_detail/52559.html
大致有两步:
- # 开启网卡的多队列功能。
- # 此命令作用是设置主网卡eth0使用两个队列。
- ethtool -L eth0 combined 2
-
- # 开启irqbalance服务,让系统自动调整网络中断在多个CPU核上的分配
- /etc/init.d/irqbalance start
4、网卡txqueuelen
网卡传输队列长度Transmit Queue Length (txqueuelen),在大流量业务场景下,会影响网卡的处理性能。默认值为1000,不宜设置过大,可能会增加网络时延。
调整方法为:
- ifconfig eth0 txqueuelen 10000
- # 或者
- ip link set dev eth0 txqueuelen 10000
-
- # 永久生效
- echo 'ifconfig eth0 txqueuelen 10000' >> /etc/rc.local
- # 或者
- echo 'ip link set dev eth0 txqueuelen 10000' >> /etc/rc.local
外部因素
除系统本身外,单节点高并发能力还严格受限于外部设备如防火墙、交换机、虚拟化环境中的虚拟交换机的最大并发连接数、最大新建连接数等因素,均是在生产环境中需要密切关注的点,不过最根本的方法还是通过业务架构改造实现负荷的平均分担和系统的灵活伸缩。