概述
如何使一台服务器充分发挥它的性能,其实是有很多讲究的。除了提升它的硬件配置,包括CPU、内存、硬盘、网络带宽等,也还需要合理设置它的操作系统参数,只有软硬件都设置得当,才能发挥最大能力。
这里不对如何进行硬件配置的优化展开讲,我们讲的主要还是操作系统层次的设置优化。参考官方性能调优指南:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/performance_tuning_guide/index。
具体调优点
常见需要调优的有如下几类,具体在后面会详细介绍如何调整:
- 调整文件数限制
- fs.file_max:允许打开的最大文件数,在linux中一切皆文件,所以要最大化利用计算机资源需要调大这个数值
- 其他:在/etc/security/limits.conf中调整linux系统用户可打开的文件数
- 调整网络参数:
- 调整端口范围,修改net.ipv4.ip_local_port_range,设置为一个较大范围
- 修改net.core.somaxconn:这个参数是优化最大允许同时连接数
- net.ipv4.tcp_max_syn_backlog
- net.core.netdev_max_backlog
- 其他优化
查看系统内核参数的方法
一种方法是在/etc/sysctl.conf看,但是有些参数没有被显示配置,但是在系统中是有默认值的,那么就可以使用sysctl
命令查看该参数的数值。
常用的命令:
- sysctl -a:查看所有内核参数
- sysctl -N ${name}:查看某个参数是否存在,比如sysctl -N net.core.somaxconn
- sysctl -n ${name}:查看某个参数的具体值,比如sysctl -n net.core.somaxconn
- sysctl -w ${name}=${value}:临时设置某个参数的具体值,比如sysctl -w net.core.somaxconn=65535 注意值是有类型的,比如无符号短整型
- sysctl -p:重新加载这个配置文件
调整文件数限制
编辑/etc/security/limits.conf,修改文件数限制:
- 查看最大可打开文件书:cat /proc/sys/fs/file-max
- 修改/etc/security/limits.conf限制,最后添加
root - nofile 1000000
- 执行ulimit -n 1000000动态修改文件数限制,和上面第二部结合起来,就不需要重启电脑
对于上述第二点,可能需要设置其他用户或所有用户的打开文件数限制,可以通过添加* - nofile 1000000
为所有用户打开限制。
修改网络参数
调整端口范围
默认的端口打开范围是3万多到6万多,调整为从10000到65535:net.ipv4.ip_local_port_range = 10000 65535
后面如果没有提到修改哪个文件,默认就是修改/etc/sysctl.conf。
修改允许连接的最大数
首先查看网络允许连接的最大数:sysctl -n net.core.somaxconn
,发现只有128,因此需要调整,调整为10万应该够了:sysctl -w net.core.somaxconn=100000
。
设置的时候遇到sysctl: setting key "net.core.somaxconn": 无效的参数
错误。经过搜索了解,somaxconn值类型是USHRT(无符号短整型),最大值不应超过65535(USHRT_MAX)。
经过测试,确实如此,因为当我把该参数值设为65536的时候失败了,而65535可以成功。测试通过。
设置成功后的输出:
[root@hadoop2 ~]# sysctl -w net.core.somaxconn=65535 net.core.somaxconn = 65535 |
记得在/etc/sysctl.conf中配置,否则重启后上述临时设置会失效。在该文件增加net.core.somaxconn = 65535
。
据说也有办法可以调整,如果真的需要调整,可能需要打补丁,这点没有测试过,不做保证。参考:https://lists.ubuntu.com/archives/kernel-team/2013-October/033041.html
修改发送和接收队列数
在/etc/sysctl.conf
设置:
262144 = 262144 = |
tcp_max_syn_backlog
指Tcp syn队列的最大长度,与tcp连接建立时的三次握手相关。
参数net.core.netdev_max_backlog
表示当每个网络接口接受数据包的速率比内核处理这些包的速率快时,允许接收队列(原文是INPUT side)的数据包的最大数目,我们调整为262144。
设置完成后执行sysctl -p
加载配置。
相关解释:
- 中文材料:http://www.lmyw.net.cn/?p=1390
- 看起来是官方内核参数手册:https://www.kernel.org/doc/html/latest/admin-guide/sysctl/net.html?highlight=netdev_max_backlog
使用tuned工具调优服务器
tuned是什么?是一款用于优化Linux系统性能的工具,可以配置cockpit使用。该工具相当于对服务器的运行模式做了调整,并不能替代上述我们所做的操作。
tuned并不是系统自带,需要另行安装。
执行命令tuned-adm active
可以查看活跃的性能配置。另外,tuned可以设置多个profile,但是目前发现如果使用tuned-admin profile a b c
这个命令设置throughput-performance和其他profile混用,则命令会报错。
对于需要充当服务器角色的机器,应该设置为throughput-performance
配置类型,如果是使用vmware创建的虚拟机,默认应该是virtual-guest
。
那么问题来了,调了以后有用吗?
在测试中,使用了throughput-performance
这个配置。经过测试,配合相关参数的优化,最终服务器的的CPU使用率几乎达到满负荷。这证明我们的设置是有效的。
参考:
- 安装及使用:https://computingforgeeks.com/optimize-linux-system-performance-with-tuned-adm/。
- 创建个性化的tuned profile:https://www.tecmint.com/tuned-automatic-performance-tuning-of-centos-rhel-servers/
- 在centos 7上创建自己的tuned profile:https://www.golinuxcloud.com/how-to-create-custom-tuned-profile-in-linux-rhel-centos-7/
验证
上面已经说了如何优化,但是生产环境是不能随意改的,所以我们在alpha做下优化,看是否确实正确且有效。
首先验证在缺省的sysctl.conf
配置下系统性能
使用nginx下的index.html来验证,性能工具使用wrk。
测试结果:
- 一开始吞吐量还比较大,系统TPS比较大,随着请求越来越多,连接错误越来越多,tps由一开始的接近1w下降到几百,性能急剧下降,错误主要是连接被拒绝
- 上述连接错误是因为系统参数设置太小,主要是
net.core.somaxconn
太小,这个参数太小导致系统同时建立的连接数被限制在128以内。下面是运行过程中统计的连接情况:
[root@localhost lizhiqiang]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' TIME_WAIT 13 ESTABLISHED 128 |
验证使用新的sysctl.conf配置后系统性能
使用下述附录所示的sysctl.conf
配置以及上述内容提到的其他配置后,运行在一台8C16G的linux虚拟机上的NGINX web服务的性能可达到10w qps,CPU利用率几乎100%,这说明了优化措施的有效性。
附录
sysctl.conf完整配置示例
# Max listen queue backlog # make sure to increase nginx backlog as well if changed net.core.somaxconn = 65535 # 是指定所能接受SYN同步包的最大客户端数量。 # Increase max half-open connections. net.ipv4.tcp_max_syn_backlog = 262144 # 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。 # Max number of packets that can be queued on interface input # If kernel is receiving packets faster than can be processed # this queue increases net.core.netdev_max_backlog = 262144 # 允许系统打开的端口范围,扩大端口数 # 可配成1024 65535进一步扩大可用范围 net.ipv4.ip_local_port_range = 1024 65535 # 在TIME_WAIT数量等于该值时,不会有新的产生, # 这个参数表示操作系统允许TIME_WAIT套接字数量的最大值,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。该参数默认为65536(在centos7),过多的TIME_WAIT套接字会使Web服务器变慢。注:主动关闭连接的服务端会产生TIME_WAIT状态的连接 # max number of sockets allowed in TIME_WAIT net.ipv4.tcp_max_tw_buckets = 6000 # 是否启用timewait 快速回收。如果服务器身处NAT环境,tcp_timestamps为1,安全起见,要禁止 net.ipv4.tcp_tw_recycle = 1 # # 开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接。 net.ipv4.tcp_tw_reuse = 1 #这个参数表示内核套接字接受缓存区默认的大小。 net.core.rmem_default = 6291456 ##这个参数表示内核套接字发送缓存区默认的大小。 net.core.wmem_default = 6291456 ##这个参数表示内核套接字接受缓存区的最大大小。12MB net.core.rmem_max = 12582912 ##这个参数表示内核套接字发送缓存区的最大大小。12MB net.core.wmem_max = 12582912 # 打开文件句柄数量 fs.file-max = 1000000 # 默认是1,对于负载均衡服务器来说必须设为1,此处设为0没有关系,可设可不设 net.ipv4.ip_forward = 0 # sysrq允许系统在任何时候响应用户按键操作,除非被锁定 # 默认是16,表示启动sysrq命令,0表示完全禁用 sysrq # It is a ‘magical’ key combo you can hit which the kernel will respond to regardless of whatever else it is doing, unless it is completely locked up. # https://www.kernel.org/doc/html/latest/admin-guide/sysctl/kernel.html?highlight=kernel%20sysrq#sysrq # 是否设置无所谓 kernel.sysrq = 0 #IPC通信相关参数,建议可以增加 #MSGMNB - Default maximum size in bytes of a message queue: 16384 bytes (on Linux, this limit can be read and modified via /proc/sys/kernel/msgmnb). The superuser can increase the size of a message queue beyond MSGMNB by a msgctl() system call. kernel.msgmnb = 65536 #Maximum size for a message text: 8192 bytes (on Linux, this limit can be read and modified via /proc/sys/kernel/msgmax). kernel.msgmax = 65536 #共享内存相关参数 #Maximum size in bytes for a shared memory segment。实际是16GB物理内存,设成64GB,可以根据实际测试情况调整,但最小应该在4GB以上(在32位linux系统上最小是4GB) kernel.shmmax = 68719476736 # shmall最少得是ceil(shmmax/PAGE_SIZE),执行getconf PAGE_SIZE可得到PAGE_SIZE大小。centos7中是4096 kernel.shmall = 4294967296 # The first value tells the kernel the minimum receive/send buffer for each TCP connection, # and this buffer is always allocated to a TCP socket, # even under high pressure on the system. … # The second value specified tells the kernel the default receive/send buffer # allocated for each TCP socket. This value overrides the /proc/sys/net/core/rmem_default # value used by other protocols. … The third and last value specified # in this variable specifies the maximum receive/send buffer that can be allocated for a TCP socket. # Note: The kernel will auto tune these values between the min-max range # If for some reason you wanted to change this behavior, disable net.ipv4.tcp_moderate_rcvbuf #这个参数定义了TCP接受缓存(用于TCP接受滑动窗口)的最小值、默认值、最大值。 #默认情况下这几个值是4096 16384 4194304 net.ipv4.tcp_rmem = 10240 87380 12582912 #这个参数定义了TCP发送缓存(用于TCP发送滑动窗口)的最小值、默认值、最大值。 net.ipv4.tcp_wmem = 10240 87380 12582912 #这个参数表示内核套接字发送缓存区默认的大小。默认是212992 net.core.wmem_default = 8388608 #这个参数表示内核套接字接受缓存区默认的大小。 net.core.rmem_default = 8388608 #这个参数表示内核套接字接受缓存区的最大大小。默认是212992 net.core.rmem_max = 16777216 #这个参数表示内核套接字发送缓存区的最大大小。 net.core.wmem_max = 16777216 # 系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。默认是65536 # Increase max TCP orphans # These are sockets which have been closed and no longer have a file handle attached to them net.ipv4.tcp_max_orphans = 262144 # 开启时就是同一个源IP来连接同一个目的端口的数据包时间戳必须是递增的,否则就丢弃。默认是打开的 net.ipv4.tcp_timestamps = 0 # Only retry creating TCP connections twice # Minimize the time it takes for a connection attempt to fail # 为了打开对端的连接,内核需要发送一个SYN,以确认收到上一个 SYN连接请求包。也就是所谓三次握手中的第二次握手。 # 这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。有文章建议设为2个 net.ipv4.tcp_synack_retries = 1 # 对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。有文章建议设为2个 net.ipv4.tcp_syn_retries = 1 # Units are in page size (default page size is 4 kb) # These are global variables affecting total pages for TCP # sockets # 8388608 * 4 = 32 GB # low pressure high # When mem allocated by TCP exceeds “pressure”, kernel will put pressure on TCP memory # We set all these values high to basically prevent any mem pressure from ever occurring # on our TCP sockets #默认是378357 504477 756714(单位页大小,即4KB),对应的大小大约是1.5GB 1.9GB 2.9GB # 提高配置避免出现内存分配压力(根据实际内存大小可以计算一下) net.ipv4.tcp_mem = 94500000 915000000 927000000 ## timeout状态时间 #表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。默认是60s,可以设置小一些 net.ipv4.tcp_fin_timeout = 15 #这个参数表示当keepalive启用时,TCP发送keepalive消息的频度。默认是2小时(7200秒),若将其设置的小一些,可以更快地清理无效的连接。 #How often TCP sends out keepalive messages when keepalive is enabled. Default: 2hours. net.ipv4.tcp_keepalive_time = 30 |
探索系统配置工具Cockpit Web
Cockpit Web是一个查看系统配置的web工具。在https://computingforgeeks.com/optimize-linux-system-performance-with-tuned-adm/的推荐下,搜索了工具怎么使用。
我的观点是,如果有可视化界面可以一览式查看系统的配置,可以节省很多精力。因为它可以让我们把精力放在最重要或最值得关注的点上面。另外,如果工具可以让我了解有哪些可以用的最优设置,然后就可以和之前摸索工的、自己修改过的配置对比,了解自己的设置是否是正确的,两相印证。
安装操作见https://www.hangge.com/blog/cache/detail_3024.html。cockpit web页面的访问地址是https://ip:9090/system。
总结一下必要的命令:
#启用 epel-release yum install epel-release #安装 dnf:entOS 8 自带了 dnf可以不装 yum install dnf #安装cockpit dnf install cockpit cockpit-machines #启动cockpit服务或设置自动启动服务 systemctl start cockpit.socket systemctl enable cockpit.socket |
参考
- 关于
/proc/sys/net/
的说明:https://www.kernel.org/doc/html/latest/admin-guide/sysctl/net.html?highlight=netdev_max_backlog - linux ipc and limits: https://tech.vys.in/2007/08/ipc-limits-in-linux.html
转载请注明:无趣的人生也产生有意思的事件 » CentOS7调优实践