文章目录
  1. 1. Linux TCP/IP tuning for scalability
  2. 2. 1. Open File Descriptors
  3. 3. 2. TIME_WAIT
  4. 4. 3. Ephemeral Ports
  5. 5. 4. Connection Tracking
  6. 6. 5. nf_conntrack_tcp_timeout_established
  7. 7. 6. Speed bump
  8. 8. 7. TCP Window Sizes
  9. 9. 8. Window size after idle
  10. 10. 附上完整的Kernel Parameters

Linux TCP/IP tuning for scalability

今天在微博上看到一篇关于服务器TCP/IP扩展性优化的文章,在逐一学习的过程发现多数是我们进行过调优的,但之前一直没有系统的学习,今天借此总结一下。

总结,所有优化项为:

  1. Open files
  2. TIME_WAIT
  3. Ephemeral Ports
  4. Connection Tracking
  5. nf_conntrack_tcp_timeout_established
  6. Speed bump
  7. TCP Window Sizes
  8. Window size after idle

1. Open File Descriptors

Linux在系统调用,大量的系统调用都依赖于文件描述符,而文件描述符可分配给进程的最大大小由资源限制来定义。
因此,如果文件描述符大小不够,或有不正常网络连接(Socket也算)、文件IO没有关闭并释放出文件描述符。也可以说是文件句柄(File Operator),会导致出现Too many open files的错误。
该错误很常见,因此OP几乎都有做优化。
使用如下命令可以查看系统相关的配置:

1
2
3
4
5
ulimit -u 查看open files设置
ulimit -a 查看所有配置
ulimit -u 65535 临时修改open files65535
ulimit -n 65536 用户可以同时打开的最大文件数(max open files)
lsof -p pid ID 查看某进程当前打开的文件资源

针对所有用户及session有效的长期修改方法为:

1
2
3
4
5
$ sudo vim /etc/security/limits.conf 
# allow all users to open 100000 files
# alternatively, replace * with an explicit username
* soft nofile 100000 #限制单个进程最大文件句柄数
* hard nofile 100000

说明:

1
2
3
4
* 通配符
soft 当前系统生较的设置
hard 系统中能设置的最大值
限制:soft 值不能高于hard

同时需要修改/etc/sysctl.conf,设置整个系统最大文件句柄数,运行sysctl -p生效

1
2
3
# /etc/sysctl.conf
# Increase system file descriptor limit    
fs.file-max = 100000

2. TIME_WAIT

TCP time wait间隔指定的时间长度,一个socket在等待FIN数据包从发送者发送时强行关闭。如果TCP没有进入CLOSED状态,主动关闭在发送最后一个ack后,就会进入TIME_WAIT。
这在Cache软件里最为常见,但其它Server也存在。

为此TIME_WAIT的优化项也不少,但主要是如下几点。笔者归纳总结下,供参考:
IBM官方建议优化为5秒:

1
2
echo "1024 61000" > /proc/sys/net/ipv4/ip_local_port_range
echo "5" > /proc/sys/net/ipv4/tcp_fin_timeout

其它参数资料优化为10秒:

1
2
3
4
5
net.core.netdev_max_backlog = 50000
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10

国内资料优化为:

1
2
3
4
5
6
7
8
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 1024    65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000

要理解这些参数意义,需要先明白为什么会有ip_local_port_range的优化?具体请看下一节优化说明。[Ephemeral Ports]
其次,要先理解服务器TCP链接状态。
命令1:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
命令2:ss -n -t -a sport = :80 | awk '{++S[$1]};END {for(a in S) print a, S[a]}'

状态解释:

1
2
3
4
5
6
7
8
9
10
SYN_SEND     请求服务端建立连接。
SYN_RECEIVED 服务器接收到了来自客户端的SYN。
ESTABLISHED  客户端接收到了服务端的SYN,会话建立完成。
LISTEN	     服务器端开始接收连接。
FIN_WAIT_1   指示活动结束。
TIMED_WAIT   客户端在活动结束后将进入此状态。
CLOSE_WAIT   表示被动关闭。服务器只是从客户端收到第一个翼片。
FIN_WAIT_2   客户端从服务器收到其第一个 FIN 的确认。
LAST_ACK     发送自己的FIN后进入此状态。
CLOSED       服务器从客户端收到 ACK,连接已关闭。

再来看下优化参数的详解:

1
2
3
4
5
6
7
8
9
10
net.ipv4.tcp_fin_timeout =5  保持FIN-WAIT-2状态时间。
net.ipv4.tcp_tw_reuse = 1     开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认0,表示关闭;
net.ipv4.tcp_tw_recycle = 1   开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认1024,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 5000 
# 表示系统同时保持TIME_WAIT套接字最大数量.
# 如果超出TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为5000。
net.ipv4.ip_local_port_range = 18000    65535 
# 表示用于向外连接的端口范围。
# 缺省情况下很小:32768到61000,改为18000到65535。

其它参数是否需要配置呢?

1
2
3
4
5
net.core.netdev_max_backlog = 3000  
#在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。原值1000,可以优化为3000。
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 1  
#ip_conntrack 工作在3层,跟nat有关,用来跟踪连接信息,它会使用一个哈希表来记录established的记录。
#如果哈希表满会出现`nf_conntrack: table full, dropping packet`错误。

3. Ephemeral Ports

优化输出端口数量,配合TIME_WAIT优化时一起使用。

1
2
# Increase ephermeral IP ports
net.ipv4.ip_local_port_range = 1024 65535

配置说明:

1
2
3
4
配置/proc/sys/net/ipv4/ip_local_port_range 显示或设定Linux使用那个连接端口(port)作客户端连线。
被分配的值102465535的整数,分别表示作为源连接端口的下限和上限。
也就是系统连接服务器时,会以 102465535 之间( 包括 102465535) 作为连线的源连接端口。
这个设定同同决定了系统在同一时间可以发出多少个活跃连线至其他 TCP extension timestamps 的系统。

4. Connection Tracking

连接优化,通过优化TCP连接table的大小。优化参数为:

1
2
net.netfilter.nf_conntrack_count
net.nf_conntrack_max

当count达到max设置值时,OS将停止接受新的TCP连接请求,可以通过/var/log/syslog查看到相关内容。

! 需要补充一下比较好。

5. nf_conntrack_tcp_timeout_established

会话连接超时时间,ESTABLISHED 客户端接收到了服务端的SYN,会话建立完成。默认这个超时时间为432000秒,(有点吓着我了)将这个值优化为10分钟,600秒。
net.netfilter.nf_conntrack_tcp_timeout_established = 600

6. Speed bump

7. TCP Window Sizes

TCP窗口大小优化,在Kernel 3.5 之后,默认值为10。

8. Window size after idle

在默认窗口大小内,新的TCP建立连接之后,在很长时间内没有数据传输。在Kernel 3.5 这个时间为1秒,同时也取决为net.sctp.rto_initial的配置。
为了保证HTTP连接,我们将其设置为0.
net.ipv4.tcp_slow_start_after_idle = 0

附上完整的Kernel Parameters

/etc/sysctl.conf的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# /etc/sysctl.conf
# Increase system file descriptor limit    
fs.file-max = 100000

# Discourage Linux from swapping idle processes to disk (default = 60)
vm.swappiness = 10

# Increase ephermeral IP ports
net.ipv4.ip_local_port_range = 10000 65000

# Increase Linux autotuning TCP buffer limits
# Set max to 16MB for 1GE and 32M (33554432) or 54M (56623104) for 10GE
# Don't set tcp_mem itself! Let the kernel scale it based on RAM.
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.optmem_max = 40960
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# Make room for more TIME_WAIT sockets due to more clients,
# and allow them to be reused if we run out of sockets
# Also increase the max packet backlog
net.core.netdev_max_backlog = 50000
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10

# Disable TCP slow start on idle connections
net.ipv4.tcp_slow_start_after_idle = 0
 
# If your servers talk UDP, also up these limits
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192

# Disable source routing and redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0

# Log packets with impossible addresses for security
net.ipv4.conf.all.log_martians = 1

参考文档:
Lognormail_linuxt-tcpip-tuning
Nateware_linux-network-tuning-for-2013
Hong-Kong-Linux-User-Group
Frozentux_ipsysctl-tutorail
IBM_Edge-Components
CU_Linux-proc-sys-net

文章目录
  1. 1. Linux TCP/IP tuning for scalability
  2. 2. 1. Open File Descriptors
  3. 3. 2. TIME_WAIT
  4. 4. 3. Ephemeral Ports
  5. 5. 4. Connection Tracking
  6. 6. 5. nf_conntrack_tcp_timeout_established
  7. 7. 6. Speed bump
  8. 8. 7. TCP Window Sizes
  9. 9. 8. Window size after idle
  10. 10. 附上完整的Kernel Parameters