linux内核参数优化重要项

it2024-12-26  11

#optimize network performance

net.ipv4.tcp_synack_retries= 3

net.ipv4.tcp_syn_retries = 3

net.core.somaxconn = 262144

kernel.sysrq = 1

net.ipv4.ip_no_pmtu_disc = 1

net.ipv4.tcp_tw_recycle = 1    (nat网络下,客户端主动出访问经过nat网关,该参数请设置为0)

#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

net.ipv4.tcp_tw_reuse = 1

 

#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。

net.ipv4.tcp_fin_timeout = 30

 

#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为30秒。

net.ipv4.tcp_keepalive_time = 30

 

#表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65535。

net.ipv4.ip_local_port_range = 1024 65535

 

#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。

net.ipv4.tcp_max_syn_backlog = 8192

 

#表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为5000。

net.ipv4.tcp_max_tw_buckets = 5000

net.ipv4.tcp_rmem = 4096 131072 1048576

net.ipv4.tcp_wmem = 4096 131072 1048576

kernel.msgmnb = 655360

kernel.msgmax = 655360

 

 

 

百万并发之 tcp_mem

在服务端,连接达到一定数量,诸如50W时,有些隐藏很深的问题,就不断的抛出来。 通过查看dmesg命令查看,发现大量TCP: too many of orphaned sockets错误,也很正常,下面到了需要调整tcp socket参数的时候了。

第一个需要调整的是tcp_rmem,即TCP读取缓冲区,单位为字节,查看默认值

cat /proc/sys/net/ipv4/tcp_rmem4096 87380 4161536

默认值为87380 byte ≈ 86K,最小为4096 byte=4K,最大值为4064K。

第二个需要调整的是tcp_wmem,发送缓冲区,单位是字节,默认值

cat /proc/sys/net/ipv4/tcp_wmem4096 16384 4161536

解释同上

第三个需要调整的tcp_mem,调整TCP的内存大小,其单位是页,1页等于4096字节。系统默认值:

cat /proc/sys/net/ipv4/tcp_mem932448 1243264 1864896

tcp_mem(3个INTEGER变量):low, pressure, high

low:当TCP使用了低于该值的内存页面数时,TCP不会考虑释放内存。pressure:当TCP使用了超过该值的内存页面数量时,TCP试图稳定其内存使用,进入pressure模式,当内存消耗低于low值时则退出pressure状态。high:允许所有tcp sockets用于排队缓冲数据报的页面量,当内存占用超过此值,系统拒绝分配socket,后台日志输出“TCP: too many of orphaned sockets”。

一般情况下这些值是在系统启动时根据系统内存数量计算得到的。 根据当前tcp_mem最大内存页面数是1864896,当内存为(1864896*4)/1024K=7284.75M时,系统将无法为新的socket连接分配内存,即TCP连接将被拒绝。

实际测试环境中,据观察大概在99万个连接左右的时候(零头不算),进程被杀死,触发out of socket memory错误(dmesg命令查看获得)。每一个连接大致占用7.5K内存(下面给出计算方式),大致可算的此时内存占用情况(990000 * 7.5 / 1024K = 7251M)。

这样和tcp_mem最大页面值数量比较吻合,因此此值也需要修改。

三个TCP调整语句为:

echo "net.ipv4.tcp_mem = 786432 2097152 3145728">> /etc/sysctl.confecho "net.ipv4.tcp_rmem = 4096 4096 16777216">> /etc/sysctl.confecho "net.ipv4.tcp_wmem = 4096 4096 16777216">> /etc/sysctl.conf

备注: 为了节省内存,设置tcp读、写缓冲区都为4K大小,tcp_mem三个值分别为3G 8G 16G,tcp_rmem和tcp_wmem最大值也是16G。

目标达成

经过若干次的尝试,最终达到目标,1024000个持久连接。1024000数字是怎么得来的呢,两台物理机器各自发出64000个请求,两个配置为6G左右的centos测试端机器(绑定7个桥接或NAT连接)各自发出640007 = 448000。也就是 1024000 = (64000) + (64000) + (640007) + (64000*7), 共使用了16个网卡(物理网卡+虚拟网卡)。 终端输出

......online user 1023990online user 1023991online user 1023992online user 1023993online user 1023994online user 1023995online user 1023996online user 1023997online user 1023998online user 1023999online user 1024000

在线用户目标达到1024000个!

服务器状态信息

服务启动时内存占用:

total used free shared buffers cached Mem: 10442 271 10171 0 22 78 -/+ buffers/cache: 171 10271 Swap: 8127 0 8127

系统达到1024000个连接后的内存情况(执行三次 free -m 命令,获取三次结果):

total used free shared buffers cached Mem: 10442 7781 2661 0 22 78 -/+ buffers/cache: 7680 2762 Swap: 8127 0 8127 total used free shared buffers cached Mem: 10442 7793 2649 0 22 78 -/+ buffers/cache: 7692 2750 Swap: 8127 0 8127 total used free shared buffers cached Mem: 10442 7804 2638 0 22 79 -/+ buffers/cache: 7702 2740 Swap: 8127 0 8127

这三次内存使用分别是7680,7692,7702,这次不取平均值,取一个中等偏上的值,定为7701M。那么程序接收1024000个连接,共消耗了 7701M-171M = 7530M内存, 7530M*1024K / 1024000 = 7.53K, 每一个连接消耗内存在为7.5K左右,这和在连接达到512000时所计算较为吻合。 虚拟机运行Centos内存占用,不太稳定,但一般相差不大,以上数值,仅供参考。

执行top -p 某刻输出信息:

top - 17:23:17 up 18 min, 4 users, load average: 0.33, 0.12, 0.11Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombieCpu(s): 0.2%us, 6.3%sy, 0.0%ni, 80.2%id, 0.0%wa, 4.5%hi, 8.8%si, 0.0%stMem: 10693580k total, 6479980k used, 4213600k free, 22916k buffersSwap: 8323056k total, 0k used, 8323056k free, 80360k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2924 yongboy 20 0 82776 74m 508 R 51.3 0.7 3:53.95 server 

执行vmstate:

vmstatprocs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st0 0 0 2725572 23008 80360 0 0 21 2 1012 894 0 9 89 2 0

获取当前socket连接状态统计信息:

cat /proc/net/sockstatsockets: used 1024380TCP: inuse 1024009 orphan 0 tw 0 alloc 1024014 mem 2UDP: inuse 11 mem 1UDPLITE: inuse 0RAW: inuse 0FRAG: inuse 0 memory 0

获取当前系统打开的文件句柄:

sysctl -a | grep filefs.file-nr = 1025216 0 1048576fs.file-max = 1048576

此时任何类似于下面查询操作都是一个慢,等待若干时间还不见得执行完毕。

netstat -nat|grep -i "8000"|grep ESTABLISHED|wc -l netstat -n | grep -i "8000" | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

以上两个命令在二三十分钟过去了,还未执行完毕,只好停止。

小结

本次从头到尾的测试,所需要有的linux系统需要调整的参数也就是那么几个,汇总一下:

1

2

3

4

5

6

7

8

echo "* - nofile 1048576" >> /etc/security/limits.conf

 

echo "fs.file-max = 1048576" >> /etc/sysctl.conf

echo "net.ipv4.ip_local_port_range = 1024 65535" >> /etc/sysctl.conf

 

echo "net.ipv4.tcp_mem = 786432 2097152 3145728" >> /etc/sysctl.conf

echo "net.ipv4.tcp_rmem = 4096 4096 16777216" >> /etc/sysctl.conf

echo "net.ipv4.tcp_wmem = 4096 4096 16777216" >> /etc/sysctl.conf

  

其它没有调整的参数,仅仅因为它们暂时对本次测试没有带来什么影响,实际环境中需要结合需要调整类似于SO_KEEPALIVE、tcpmax_orphans等大量参数。

最新回复(0)