Linux系统优化之网络IO调优

 

 

首先说明,对于linux系统而言,tcp/ip协议栈是工作在内核空间中实现而且在内核中是按照流水线方式实现的

当我们去接收一个报文时,由各栈去解封装,而这是由流水线去处理的

而流水线是非copy类型的,所谓非copy类似就是直接送往下一个流水线而不是从TCP内存中复制到IP栈的内存,而是直接将此段空间让给IP使用,所以交给下一个关口的时候挪动的不是数据而是协议栈,所以数据一直在同一段内存中存放,接收数据的时候要先在内存中应用IP协议栈、解ip封装然后交给TCP协议栈进行工作以此类推

 

通常一般而言不需要复制任何数据,性能非常不错的,需要注意的是对于整个主机来讲,无论是接收还是发送,只要跟非本机进行交互都需要通过网卡设备向外发送或向内接收

 

那当一个来自web的报文到达网卡的时候,那接下来访问哪个服务我们不得而知,但是我们要对信号接收并进行处理的话,那么首先需要将报文接收下来,并存放在内存空间中

而内存又分为内核空间内核和用户空间内存 ,所以当一段信号到达网卡的时候必须立即通知cpu进行处理,这个过程叫做中断

因此一旦有中断产生需要处理中断有权限处理中断的只有内核,因此在硬件级别只有内核才有权限访问

 

所以这个时候,通常情况下,某一进程正在运行,网卡突然接收到某一信号,于是网卡中断CPU,进程切换出去,接下来执行内核中的代码,将此代码接下来并在内存中开辟一段空间将数据存放下来,如果数据量很大的话也就意味着在内核的内存中可能开辟多块内存来存放这段数据,也就意味着CPU会被中断N次,由此的话性能会很低

 

为了避免这种情况,DMA机制产生了

 本文来自http://yijiu.blog.51cto.com  转载需经博主本人许可,盗帖可耻!

DMA机制

cpu只需要开辟一段内存空间,于是接下来的所有控制都交给DMA芯片,由DMA控制整个总线,当复制数据到内存的过程结束了,于是DMA会通知cpu(内核)任务结束

 

中断下的数据放进来了,但是可能未必会特别紧急,有可能cpu上正在执行其他进程,比如内核正在执行刷写内容到磁盘,也就意味着刷写过程中是不允许随意切断的

所以接进来的网络报文有可能暂存几毫秒,等待内核执行完其他操作了而后马上切换至当前任务中来,以完成操作给予响应

 

但不管怎么说,只要将用户的来源请求暂存到本地内存中就可以处理了,如果在处理之前又来了很多请求,那么会将其继续暂存依次处理

当队列被写满了,后续再来的请求则会丢弃,也就是我们常说的拒绝服务

 

同样道理,当我们本机接收下来,通过本机拆ip 拆tcp 拆应用首部 等一系列操作,事后会发现这是某一对应的用户空间的进程应用 比如web服务器,很显然这个web服务器要关联到这个套接字上,最终用户就会根据这个套接字接口将数据从套接字发送至这个进程 

 

这个进程接收到请求后发现用户所访问的是某个静态页面,则会构建响应报文

但是需要注意几个问题:

构建响应报文是否要发起本地磁盘IO

是否要装载本地文件

是否装载完成之后封装成响应报文,而后发送给用户,但是如果还有其他往外发送的报文的话,则将其放到发送队列中

 

发送队列

简单来讲是内存空间,那么网卡驱动程序会从这段内存空间里首部依次将报文发送出去

而我们内存也是优先的,而是否内存空间越大就意味着能缓存的请求越多

 

那么网络调优无非就是调整缓冲大小以及连接数,而网络功能不仅仅有tcp协议栈,还包括udp icmp等等

 

缓冲类别

如果不是tcp协议栈的话,那它仍然需要其他缓冲区,因此我们系统上缓冲对于linux分为两大类:

・核心缓冲

    为所有协议提供的空间,如果没有定义则使用这类空间,事实上,我们可以将tcp独立出来,因为tcp比较独特而且tcp有限状态机制在多个状态之间可以进行转换的,也就是tcp缓冲也被称为sock缓冲

・TCP缓冲(sock缓冲)

  如果将scok缓冲独立出来的话,那么核心缓冲只为udp等其他非tcp协议栈进行缓冲,那么在某一文件中很可能是分开进行定义的 

 

当一个用户请求到来,通过网卡将其连接进来,也就意味着在此之间需要进行三次握手

,连接进来之后这时候我们的连接状态为established,在这个状态中我们进程正在构建响应报文,当这个报文构建完成之后则向这个连接进行响应了,发送过程中属于established,假如我们使用的是非持久连接,当报文发送完之后,就表示需要断开了,尤其是在使用非持久连接必须是服务器端进行断开,不然客户端一直处于挂机状态则会很麻烦。

 

在内核中,视为系统一切皆文件,也就是说任何一个连接进来了其实是通过文件句柄来保存,也就意味着内核必须要为这个内核使用一个文件句柄,内核所打开的文件必须能够追踪到这个文件

 

对于用户来讲在内核中能够持有的文件句柄数是有限的65536个

问题是我们所生产的文件越来越多,而且这个文件而且其实是tcp连接文件,而这个文件还要用于描述tcp的状态的,正常情况下正在发送传输数据的状态就是established,传完了双方要四次断开

 

断开的某种可能性:比如传输完成假设等待客户端进行断开,客户端需要发送了FIN请求,但是客户端一直没有发送,由服务器进行发送,服务器发送FIN至客户端,客户端接收到了信息,状态从established转为FIN_WITE1等待对方的第一次对我们关闭连接的请求,处于write1的时候 这个进程所包含的信息量也是非常大的。如果对方始终不回复的话,我们需要定义一个超时时间。

 

如果对方对我们回复响应,那么除了等待对方的fin_wirte1之外还需要等待对方的响应确认报文达到之后立马等待用户进入fin报文,接下来等待第二次的fin_wirte的时候,这时我们的状态会处于fin_write2状态

 

接收到对方第一个报文之后,立刻转为第二种等待状态--fin_write2,当进入此状态的时候,此时跟需要向对方确认的数据将会被清理出去

清理出去会,fin_write2大概会在1.5k信息量左右

 

如果对方迟迟不回应其信息的话,那么对于一个非常繁忙的服务器来讲是不允许等待太长时间的,于是我们有两种方案:

1 超时,因为迟迟等不来也不能始终维持连接,从而不再维护一个非有效的套接字句柄

2 快速回收,tcp time weite2连接重用,一旦接收到了对方第一次确认之后,里面根据用户相关的用户协议都会被清出去,其里面的敏感信息都会消失,由此我们可以将新的连接请求的数据填入到此文件句柄中从而归类为一个新的请求进行处理     

 

如果我们没有进行重用,而超时时间定义的非常长,结果会发生连接耗尽,同而会有大量的time_wite2的连接状态,而新的连接再也进不来了

 

对网卡而言,一定是当一个报文到来的时候要中断CPU,由内核接受请求在内存中应用保存的,所以内存需要一段空间,空间有多大需要自行去定义的,如果内存足够大的话可以定义大一点,所以内存空间越大就越意味着越能够及早的将请求接入到本地服务器中,只不过响应速度比较慢而已,至少拒绝服务攻击不会发生。

 

万一队列满了,我们还有补救措施

在系统上还有一个叫做cookie机制,其机制可以将另外的内存空间补充进来

 

事实上在linux还有其他的功能需要调整:

比如tcp建立会话是独立的,两者之间建立连接后,发送报文的时候为了更好的性能,将其批量发送,批量发送一次性发送多少取决于tcp的滑动窗口

 

 

批量发送

首先,发送方有发送方的缓冲,接收方有接收缓冲,中间还要有网线管道

至于取决于发送多大,而两个相邻比较近的主机之间可以尽可能调整窗口大小

对于tcp而言滑动窗口对发送/接收来讲是一个非常重要的衡量手段(网络性能调整机制)只不过通常在网络调优中,这个功能我们触及到的非常少而已

 

如下图所示:

wKioL1QpG_6QFhVIAAG6rlgH4Lo783.jpg

我们的报文真正在互联网上传送的时候,或者在tcp ip中传送的时候

一切都是有sock_buff接收的

sock_buffer需要在某一个接收方的协议栈中自下而上的进行流水线处理

 

 

回顾:tcp的有限状态

wKiom1QpG92A8FUTAAFWCtnjP_8694.jpg

server默认状态为listen 

当client开始发送请求的时候状态为syn_sent ,于是将状态从close转为sync

对方接收到syn报文以后就从listen状态转为syn_recv,并发送sync_ack 并确认对方的请求 ,一直等待对方接收

对方接收下来,发送syn+ack 从其转为established ,而服务器收到ack 从而也转为established

 

四次断开就略过不谈了,具体请看 http://yijiu.blog.51cto.com/433846/1356254

 

查看当前网络打开的套接字状况

使用netstat查看

[root@node2~]# netstat -tunlp

ActiveInternet connections (only servers)

ProtoRecv-Q Send-Q Local Address               Foreign Address             State       PID/Program name  

tcp        0     0 0.0.0.0:80                 0.0.0.0:*                   LISTEN      4733/nginx         

tcp        0     0 0.0.0.0:22                 0.0.0.0:*                   LISTEN     1092/sshd          

tcp        0     0 127.0.0.1:6010             0.0.0.0:*                   LISTEN      9707/sshd          

tcp        0     0 :::22                      :::*                        LISTEN      1092/sshd          

tcp        0     0 ::1:6010                   :::*                        LISTEN      9707/sshd          

tcp        0     0 :::3306                    :::*                        LISTEN      11572/mysqld 

 

查看当前处于活动状态的套接字

[root@node3 ~]# sar -n SOCK

#SOCK是关键字,不用改

[root@localhost~]# sar -n SOCK 1 3

Linux2.6.32-358.2.1.el6.x86_64 (localhost)     09/29/2014_x86_64_    (4CPU)

 

03:21:01PM    totsck    tcpsck   udpsck    rawsck   ip-frag   tcp-tw

03:21:02PM       455       166         4         1         0        78

03:21:03PM       459       166         4         1         0        77

03:21:04PM       460       168         4         1         0        70

Average:          458       167         4         1         0        75

参数解释:

#totsck    系统持有的socket个数

#tcpsck   当前正在处于使用中的tcp socket文件个数

#udpsck   当前正在处于使用中的udp socket文件个数

#rawsck   raw套接字个数,raw可以理解为数据流,无法归类tcp/udp

#ip-frage  当前正在使用的ip分片个数

#tcp-tw   处于tw状态的tcp套接字个数

 

sar还可以显示根据IP相关的信息

[root@localhost~]# sar -n IP 1 3

Linux2.6.32-358.2.1.el6.x86_64 (localhost)     09/29/2014_x86_64_    (4CPU)

 

03:22:41PM    irec/s  fwddgm/s   idel/s     orq/s   asmrq/s  asmok/s  fragok/s fragcrt/s

03:22:42PM    126.00      0.00   124.00    123.00      0.00     0.00      0.00      0.00

03:22:43PM     69.70      0.00    69.70     63.64      0.00     0.00      0.00      0.00

03:22:44PM     98.02      0.00    98.02    176.24      0.00     0.00      0.00      0.00

Average:        98.00      0.00    97.33    121.33      0.00     0.00      0.00      0.00

 本文来自http://yijiu.blog.51cto.com  转载需经博主本人许可,盗帖可耻!

lsof 查看打开的文件

lsof -l   #显示关联当前用户上所有的文件

 

我们当前是root用户,root用户可能大多数进程都是以其进程运行,所以这些进程打开的文件都关联到一个用户上去了

如果我们想查看某个pid打开的文件的话,如下所示:

[root@localhost~]# lsof -i :80

COMMAND   PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME

squid   30197 squid  13u  IPv6 136216148      0t0 TCP 172.23.215.252:http->172.23.200.148:prat (ESTABLISHED)

squid   30197 squid  14u  IPv6 136164788      0t0 TCP *:http (LISTEN)

squid   30197 squid  15u  IPv6 136164801      0t0 TCP 172.23.215.72:http->172.23.200.154:53616 (ESTABLISHED)

squid   30197 squid  16u  IPv6 136208979      0t0 TCP 172.23.215.251:http->172.23.200.34:ufastro-instr (ESTABLISHED)

squid   30197 squid  18u  IPv4 136216350      0t0 TCP 172.23.215.72:58292->108.126.126.124.broad.bjtelecom.net:http(ESTABLISHED)

squid   30197 squid  19u  IPv6 136214917      0t0 TCP 172.23.215.251:http->172.23.214.43:saphostctrl (ESTABLISHED)

squid   30197 squid  20u  IPv6 136204102      0t0 TCP 172.23.215.252:http->172.23.200.31:epl-slp (ESTABLISHED)

squid   30197 squid  21u  IPv4 136217076      0t0 TCP 172.23.215.72:56237->203.208.37.25:http (ESTABLISHED)

squid   30197 squid  23u  IPv6 136212725      0t0 TCP 172.23.215.72:http->172.23.215.60:menandmice-dns (ESTABLISHED)

squid   30197 squid   26u IPv6 136208054      0t0  TCP172.23.215.251:http->172.23.200.109:ndl-tcp-ois-gw (ESTABLISHED)

squid   30197 squid  36u  IPv6 136207570      0t0 TCP 172.23.215.251:http->172.23.200.109:inova-ip-disco (ESTABLISHED)

squid   30197 squid  37u  IPv6 136216808      0t0 TCP 172.23.215.251:http->172.23.201.71:fc-faultnotify (ESTABLISHED)

squid   30197 squid  38u  IPv6 136216906      0t0 TCP 172.23.215.251:http->172.23.200.42:tappi-boxnet (ESTABLISHED)

squid   30197 squid  39u  IPv6 136203186      0t0 TCP 172.23.215.251:http->172.23.201.44:adrep (ESTABLISHED)

以上是80端口打开的所有文件,很显然,如果所有的繁忙的web服务器使用此命令查看,可能会显示的非常多,除了LISTEN状态的,其他的都表示当前状态处于打开状态的TCP web服务的会话数

 

lsof -i的格式:

lsof -i[46][protocol][@hostname|hostaddr][:service|port]
     46
:IPv4或IPv6
     protocol:TCP or UDP
     hostname:Internet host name
     hostaddr:IPv4地址
     service:/etc/service中的服务名称(可以不只一个)
     port:端口号 (可以不只一个)

 

例:

查看22端口现在运行的情况

[root@localhost~]# lsof -i :22

COMMAND   PID USER  FD   TYPE    DEVICE SIZE/OFF NODE NAME

sshd     1291 root    3u IPv4      9070      0t0 TCP *:ssh (LISTEN)

sshd     1291 root    4u IPv6      9072      0t0 TCP *:ssh (LISTEN)

sshd     5516 root    3r IPv4 133312373      0t0  TCP 172.23.215.72:ssh->172.23.214.52:10827(ESTABLISHED)

sshd    30520 root    3r IPv4 136203961      0t0  TCP 172.23.215.72:ssh->172.23.215.1:61817(ESTABLISHED)

查看22端口打开情况,我们当前的 172.23.215.1:60536连接到node3.test.com 主机上来,状态是established

 

 

查看某个用户所打开的文件

[root@localhost~]#  lsof -u squid | more

COMMAND   PID USER   FD   TYPE             DEVICE  SIZE/OFF     NODE NAME

squid   30197 squid  cwd   DIR              252,3      4096  2752513 /root

squid   30197 squid rtd    DIR              252,3      4096         2 /

squid   30197 squid txt    REG              252,3  32944005  2102844 /usr/local/squid-3.3.12/sbin/squid

squid   30197 squid  mem   REG              252,3     22536  2883586 /lib64/libdl-2.12.so

squid   30197 squid mem    REG              252,3     43392  2883591 /lib64/libcrypt-2.12.so

squid   30197 squid mem    REG              252,3    386040  2883590 /lib64/libfreebl3.so

squid   30197 squid mem    REG              252,3    124624  2883606 /lib64/libselinux.so.1

squid   30197 squid mem    REG              252,3    944712  2883654 /lib64/libkrb5.so.3.3

##########略过##############

 

可以看到,运行squid服务的用户名为squid,所以我们可能还没有被用户监控就已经打开很多文件了,更何况一旦打开很多网络套接字文件让网络用户建立连接可能需要打开的连接会更多

所以将来如果建立高并发服务器的时候首先要调整运行服务的运行用户的文件描述符

 

netstat -tu  当前处于活动状态的连接

[root@localhost~]# netstat  -tun | wc -l

515

可以看到有515个连接,为了看起来方便,我们以连接数统计各个状态

[root@localhost~]# netstat  -tun | awk '/^tcp/{stat[$NF]++}END{for(S in stat) print S,stat[S]}'

TIME_WAIT87

FIN_WAIT11

SYN_SENT1

FIN_WAIT210

ESTABLISHED549

CLOSING1

另外ss -tuan 会比netstat更快,根据习惯来选择

 

很多时候只是观测某一服务的值,比如我们只想看80端口相关的值

,只需要抓取80端口相关状态即可,因此根据自己需要灵活变化命令以实现需求

 

 

使用dstat查看哪个进程占用IO量最大

[root@node3~]# dstat -top-io


查看哪个进程占用cpu最多

[root@localhost~]# dstat -d -r --top-io

-dsk/total---io/total- ----most-expensive----

 read writ| read  writ|     i/o process     

9121B  148k|0.95 4.59 |init         96k  143k

   0    0 |   0     0 |stunnel     427k 424k

   0 8192B|   0  2.00 |(squid-1)    93k 135k

   0  168k|   0  8.00 |(squid-1)  1185k 1241k

   0  968k|   0  24.0 |(squid-1)   398k 489k

8192B  392k|2.00 92.0 |(squid-1)   175k  253k

   0    0 |   0     0 |(squid-1)   668k 875k

  56k   0 |12.0     0 |(squid-1)   429k 567k

   0  240k|   0  12.0 |(squid-1)   116k 244k

 

 本文来自http://yijiu.blog.51cto.com  转载需经博主本人许可,盗帖可耻!

网络参数优化

net.ipv4.tcp_max_tw_buckets
time_wait
的数量,默认为8192;

如果默认8192如果我们有其值以上的连接数则会被请出去,一般来讲尤其是time wite2状态清理或重用都是没有问题的。

 

net.ipv4.ip_local_port_range = 1024 65000
允许系统打开的端口范围,前而为下限,后面的数字为上限;默认为“32768 到 61000”;

对于繁忙的服务器或高并发web服务器很明显是不够用的,假如使用nginx等做反向代理,这个范围尽可能调大,这里我们调整为 1024 到 65000,只要是没有人用的则直接拿来去用


注意:此可用范围决定了最后time_wait状态的连接的数量;也就意味着处于time_wite状态连接都于各种状况没有断开而很多都处于time wite状态,那么这个量会很高,但无论多高也不能高出net.ipv4.ip_local_port_range = 1024 65000 的差值的

如果time_wite状态的连接数达到了这个区间的所有最大值,结果意味着新的连接已经连接不进来,所有的time_wite都被占据,所有的新链接都可能被拒绝连接了

无论是time wite还是其他状态,所有的连接数字都不能超过这个差值的,所以tw的状态越少,那么我们正常连接的就越多

 本文来自http://yijiu.blog.51cto.com  转载需经博主本人许可,盗帖可耻!

下面的两项可有效降低tw状态连接的数量,如下所示:

 

降低tw状态连接的数量:

net.ipv4.tcp_tw_recycle = {0|1}  

#快速回收并重用
是否启用timewait快速回收;很显然在一个非常繁忙的服务器是必须要快速回收的,但是要启用这个功能的话,在LVS的NAT环境下可能会出现严重的问题:

开启此功能在NAT环境下可能会出现严重的问题:因为TCP有一种行为,它可以缓存每个连接最新的时间戳,后续请求中如果时间戳小于缓存中的时间戳,即被视为无效并丢弃相应的请求报文;很多时候服务端和服务器端的时间可能会不一致,所以当一个用户请求连接进来了为其分发至一台服务器上,并且启动了快速重用,意味着前面的用户断开了然后又来了个用户重用了这个连接,重用之后往外发送的时候会遇到一个问题:

为了实现连接重用,而这个连接重用的报文跟前面还是同一个链接,于是被当前系统识别为当前用户的连接是同一个,因为我们允许了重用而重用发现后面的连接的时间戳的系统时间与我们当前系统时间不一致,那导致时间戳不一致,因为请求的时间戳可能小于缓存的时间戳。比如我们缓存3:30:50 的时间戳 ,而过来的请求时间3:30:58

慢了几秒,它就认为这个时间已经被请求过了,所以这种请求就会被丢弃,因此在这种情况下可能大量的用户请求出现异常行为,都是处于time out等 各种情况,这在nat模型下的ipvs框架是极为常见的,如果请求tcp_tw_recycle的话Linux是否启用这种行为取决于tcp_timestamp和tcp_tw_recycle,而前一个参数默认是启用的,所以启用后面的参数就会激活此功能;因此,如果是基于LVS的NAT环境,安全起见,应该禁用tcp_tw_recycle。

 

另一种解决方案把tcp_timestamps设置为0,tcp_tw_recycle设置为1并不会如想象中奏效,因为一旦关闭了tcp_timestamps,那么即便打开了tcp_tw_recycle,后面的参数也没有效果。此时降低net.ipv4.tcp_max_tw_buckets的值就可以显著降低tw连接的数量了。但是仍然不能避免问题

#回收不代表重用,重用还需要取决于tw_reuse

 

 

net.ipv4.tcp_timestamps= 0
tcp
报文时间戳,关闭时可以避免序列号的卷绕,如上所述;

net.ipv4.tcp_syncookies = {0|1}
是否开启SYN Cookies,即当SYN等待队列溢出时,是否启用cookies功能;
用户的请求到达后,会被列入到请求队列中,而队列满了之后再有信的请求进来则被拒绝服务,为了避免此种情况,我们会在另一内存段中开辟一段内存--被称为后背队列

sync cookies 一般都是启用的,只要内存足够大将timestamps调大即可

 

 

net.ipv4.tcp_max_syn_backlog = 262144
保存的那些尚未收到客户端确认信息的连接请求的最大值;默认为128,可增大此值

#在等待最后发送ack的时候允许多少个等待,前提是有足够内存

#加大有助于为更多连接提供相应的

 

 本文来自http://yijiu.blog.51cto.com  转载需经博主本人许可,盗帖可耻!

net.ipv4.tcp_synack_retries = #
为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK,这也即所谓的三次握手中的第二次;这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量;繁忙的服务器上建议设置为0或者1;0表示只要最多回应一次,如果不回应则断开连接

 本文来自http://yijiu.blog.51cto.com  转载需经博主本人许可,盗帖可耻!

 

net.ipv4.tcp_syn_retries = #
在内核放弃建立连接之前发送SYN包的数量;

#tcp握手的第一次,重启几次

繁忙的服务器上建议设置为0或者1;

 

 

net.ipv4.tcp_max_orphans = 262144
系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上;如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息;
这个限制仅仅是为了防止简单的DoS 攻击,不能过分依靠它或者人为地减小这个值,如果需要修改,在确保有足够内存可用的前提下,应该增大此值;

#这个数值越大越好,越大对于抗攻击能力越强

 

net.ipv4.tcp_fin_timeout = 5
如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间;缺省值是60秒。
然而,对端可能会出错或意外宕机并永远不关闭连接。即使你的机器是一个轻载的WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN-WAIT-2 的危险性比FIN-WAIT-1要小,因为每个连接最多只能消耗1.5K内存,但是它们的生存期长些;

#假如说没有打开套接字的重用,那就意味着如果发送fin报文并等待对方相应,对方相应了又等待对方的fin 这时对方不发fin了,这种处于fin的连接数最多可以设置为多长时间,如果超时,则断开,60秒太长,可以将其设置为5

 

net.ipv4.tcp_keepalive_time = 30
当keepalive起用的时候,TCP发送keepalive消息的频度,默认是是2小时;

#长连接,如果没有fin的断开的话则一直处于长连接状态

#默认是7200秒,当时间已到会尝试着重新建立连接,如果能重新建立成功则继续,如果不成功则重试,如果重试几次都失败了则断开连接,当然连接数有点长,但是不建议更改,因为跟tcp协议相关,而更改了以后可能不符合规定,可能会出现异常,当然可以尝试

 本文来自http://yijiu.blog.51cto.com  转载需经博主本人许可,盗帖可耻!

关于内存参数调优

我们说过对于网络协议栈来讲,有接收缓冲 发送缓冲等,参数就是为了调整网络功能的内存大小的

 

net.core.rmem_max=8388608
定义内核用于所有类型的连接的最大接收缓冲大小;

#核心缓冲接收缓冲的最大值。最大值表示如果需要的话从默认值增长到最大值,万一内存不够用了,就不再分配

net.core.rmem_default=65536
定义内核用于所有类型的连接的默认接收缓冲大小;
#核心缓冲接收缓冲的默认值,至少要保证的值,就是最大打开的文件描述符,不用解释了吧

net.core.wmem_max=8388608
定义内核用于所有类型的连接的最大发送缓冲大小;

net.core.wmem_default=65536
定义内核用于所有类型的连接的默认发送缓冲大小;

 

以上两点,需自行设定

 

调整tcp缓冲

 

net.ipv4.tcp_mem='8388608 83886088388608' 

定义TCP协议栈使用的内存空间;分别为最小值,默认值和最大值;#既接收有发送

net.ipv4.tcp_rmem='4096 87380 8388608'
定义TCP协议栈用于接收缓冲的内存空间;

第一个值为最小值,即便当前主机内存空间吃紧,也得保证tcp协议栈至少有此大小的空间可用;

第二个值为默认值,它会覆盖net.core.rmem_default中为所有协议定义的接收缓冲的大小;

第三值为最大值,即能用于tcp接收缓冲的最大内存空间;

net.ipv4.tcp_wmem='4096 65536 8388608'

定义TCP协议栈用于发送缓冲的内存空间;

 

作为服务器来讲,响应的报文数要大,我们在发送之前用户的请求数可能比响应数要大所以并不意味着发送方大于接收数,因为接收进来的或响应用户的请求量可能会非常大,反而接收进来的内存会更大一点,虽然接收进来的请求没有数据,这就是为什么我们在以下参数tcp_rmem 设置为默认8万多 而tcp_wmem 为6万多的原因

本文来自http://yijiu.blog.51cto.com  转载需经博主本人许可,盗帖可耻!

 

付:以下为国内著名电商某服务器的内核优化参数:

#Controls the default maxmimum size of a mesage queue
kernel.msgmnb = 65536

# Controls the maximum size of a message, in bytes
kernel.msgmax = 65536

# Controls the maximum shared segment size, in bytes
kernel.shmmax = 68719476736

# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 4294967296
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 0
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.ip_local_port_range = 1024  65535
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 100
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 20000

 

本文来自http://yijiu.blog.51cto.com  转载需经博主本人许可,盗帖可耻!


本文出自 “心情依旧” 博客,转载请与作者联系!

你可能感兴趣的:(网络IO,内核参数,IO优化,网络调优,内核调优)