UNIT 13 Essential Network Tuning  网络性能调整
 
     目标:1. 应用队列技术最大化网络吞吐量
           2. 调整TCP和non-TCP网络sockets的buffer
    
  13.1 Simplified transmit model 简化传输的模式
      A. Output/writer发送数据
        a. 把数据传到socket ”file” (相当于传输了buffer) **
        b. 内核把数据封装到PDU(协议数据单元)
        c. PDU会被传送到每个设备传输队列    **
        d. 驱动程序会把队列最前面的PDU传送到网卡
        e. PDU到达后网卡会提升中断号
 
13.2  Simplified receive model 简化接收的模式
A. Input/reader 接收数据
        a. 网卡接收到发来的数据帧后用DMA把帧拷贝到接收buffer
        b. 网卡提升CPU中断号
        c. 内核对中断号进行处理并调度一个软中断
        d. 软中断处理完后把数据包放到IP层并由路由决定发送到哪个地址
        e. 本地主机接收到后:
           1)把接收到的数据包解封装放到socket 的接收buffer里面
           2) 从socket 的等待队列里唤醒进程
           3) 进程从socket 接收buffer读取数据。
 
13.3 Kernel socket buffers
     A. Kernel buffers
       a. UDP:core read and write buffers 核心读写buffer
       b. TCP: core+TCP read and write buffers
       c. Fragmentation buffer 碎片buffer
       d. DMA for NIC receive
     B.内核会根据流量自动调整buffer的大小
       a. buffer 必须是空闲的内存页
       b. buffer太大会增加ZONE_NORMAL的 压力
       c. 接收数据流量的多少取决于buffer的大小。
        
13.3  Calculating total buffer size 计算整个 buffer 的大小
 A.Bandwidth delay product (DBP) :单次发送数据包的数量
      Lpipe=Bandwidth * DelayRTT = A * W 带宽*延时= Buffer size
      用ping命令计算RTT(延时)
 B.  All connections share pipe 所有连接共享pipe时 :
   Socket buffer =DBP / #sockets (接口数)
 
13.4   Calculating per-socket buffer size 计算每个 socket buffer 大小
   Max connections => Min buffer
   Min connections => Max buffer
   连接数越大,buffer变小
   连接数越小,buffer变大。
 
13.5  Tuning core buffer size (UDP) 调整 UDP buffer 大小
  A. 在/etc/sysctl.conf 文件里调整 BDP/#connections buffer
    a.   Input/reader in Bytes 接收数据
      net.core.rmem_default    默认值
      net.core.rmem_max      最大值
    b.  Output/write in Bytes 发送数据
      net.core.wmem_default
      net.core.wmem_max
  B.   Reload /etc/sysctl.conf
    sysctl –p
 
13.6 Tuning TCP buffer size 调整 TCP buffer 大小
      A. Tune core buffers for DBP / #connections
      B. 在/etc/sysctl.conf 文件里调整TCP buffer
         a. TCP 内存总页面数
           net.ipv4.tcp_mem
         b. Input/reader in Bytes 接收数据
            net.ipv4.tcp_rmem
         c. Output/writer in Bytes 发送数据
            net.ipv4.tcp_wmem
 C.  Reload /etc/sysctl.conf
        Sysctl -p
 注: 以上每个参数都有三个值:最小值,默认值,最大值
        最大值一般设为默认值的1.5倍.
 
13.7    Tuning DMA buffer size  调整 DMA buffer 大小
  A.  如果NIC driver 有DMA buffer可调整的话:
    Modinfo –p e1000 查看网卡模块信息
  B. 更新 /etc/modprobe.conf
        alias eth0 e1000
        options eth0 RxDescriptors=1024 TxDescriptors=1024
  C.  TCP connections :
        Increase socket buffer size by 25% 增加socket buffer * 25%
 
13.8     Is packet fragmentation a problem ?
  A.  查看各种协议数据包情况
        netstat –s
  B. 查看数据包重组失败情况
      cat /proc/net/snmp | grep ‘^Ip:’ | cut –f17 –d ‘’
      注: 重组失败表明需要调整buffer
  C. 引起碎片的原因:
    a. Denial of Service (DOS) attacks    DOS***
    b. NFS
    c. Noisy networks
    d. Failing network electronics 网络底层物理链路电子信号问题
 
13.9  Tuning fragmentation buffers 调整碎片 buffer
       
        net.ipv4.ipfrag_time 碎片在buffer里停留的时间,默认值30秒,超时丢弃。
        net.ipv4.ipfrag_high_thresh: 默认值262144bytes, 256KiB
  net.ipv4.ipfrag_low_thresh: 默认值196608bytes, 192KiB
        当buffer空间大于这个值时,后面新增的碎片会被丢弃,直到buffer的值net.ipv4.ipfrag_low_thresh的值以下碎片才重新重组。
  注: NFS SMB 等服务很容易造成碎片,所以使用这些服务时可以适当调大buffer 值,但调得太大的话也会造成网络延时。
 
13.10 Network interrupt handling 网络中断处理
     A. 网卡为每一个数据包分配一个硬CPU中断。
         a. 为每个进程接收队列调度一个软中断。
     B. 中断处理会抢占进程队列:
        a. 传输队列满时数据包会被丢弃。
        b. 接收socket buffer满时数据包被丢弃。
        c. 重负载会导致receive-livelock发生。
     C.  查看硬中断
          cat /proc/interrupts
     D. 查看软中断
         ps axo pid,comm.,util | grep softirq
    
 注:receive-livelock: 在中断驱动系统里,接收中断的优先级高于其它进程,如果数据包到达得太快的话,CPU会花很多时间去处理接收中收,因此没有资源去把到达的数据包传递给应用程序。
 
13.11  Improving interrupt handling 提升中断处理性能
     A. 两种基本技术:
         a. Interrupt coalescing(中断合并):一个中断处理多个帧。
         b. Polling: 用定时中断来处理进程队列。
    B. 在高负载下驱动会自动调整中断处理。
    C. 总结:
        a. 减少CPU服务时间和利用率。
        b. 把receive buffer 调高一些
        c.  低负载时把延时调大一些。
        d.   根据不同特征的数据包采用不同策略来调整吞吐量。
 
13.12 Tuning interrupt handling 调整中断处理
   A. 确定模块参数
        modinfo –p e1000
   B . Update /etc/modprobe.conf
        alias eth0 e1000
        alias eth1 e1000
        options e1000 InterruptThrottleRate=1,3000
 
       0 禁用
       1 动态自动调整
       3 保守取值
       3000 buffer大小,根据流量自动调整。
 
   设备调整相关命令:
       ethtool
       mii-tool
       ip link
      /sbin/ifup-local
    systool 查询内核模块信息,例:systool –avm usbcore
 
13.13  Network sockets 网络套接字
    A.应用程序是通过socket连接到网络栈来进行读写的
    B. Socket API把每个socket(网络连接)当作一个虚拟文件来处理。
       a. 传输数据相当于写文件。
       b. 接收数据相当于读文件。
       c. 关闭网络连接相当于删除文件。
    C. 读和写buffer是用来为应用程序存数据的.
    D. TCP sockets 需要额外的连接处理。
 
13.14  TCP sockets TCP 套接字
    A.  TCP 使用三次握手来建立连接,开启三次握手:
       a. Client -------syn packet----------- à Server
       b. Server--------syn-ack------------- àClient
       c. Client--------ack----------------- à Server
    B. 系统结束cocket 连接:
        a.  一端发送fin包
        b.  另一端发送fin-ack包
        c.   如果连接空闲超时后会被关闭
        d.   连接需要用keepalives来保持活动状态
        e.  半关闭连接(wait状态)在没有收到FIN-ACK之前超过默认超时时间的话会被关闭。
 
13.15  Viewing network sockets 查看网络套接字
     A. Passive opens(listeners) 查看已打开的连接(监听状态)
         netstat -tulpn
     B.Active sockets 活动连接端口
         sar –n SOCK
        lsof    - i 查看正在操作的连接
        netstat - tu
    C. All sockets 所有连接端口
        netstat - taupe
    D.Half-closed connections 半关闭连接
       netstat -tapn | grep TIME_WAIT
 
13.16  Tuning TCP socket creation 创建 TCP 套接字
   A.TCP connection(syn) 重新连接的次数
        net.ipv4.tcp_syn_retries 默认为5次
   B.重新连接队列的长度
     net.ipv4.tcp_max_syn_backlog 默认为1024,超过此值后丢弃
   C.重新使用TCP连接
      net.ipv4.tcp_tw_recycle 默认为0关闭,1打开
 
13.17  Tuning TCP socket keepalive 调整 TCP 套接字存活时间
   A.连接空闲多长时间开始发送keepalive.
         net.ipv4.tcp_keepalive_time 空闲时间,默认值7200秒
   B.间隔多久探测一次keepalive
       net.ipv4.tcp_keepalive_intvl  间隔时间,默认值75秒
  C.探测多少次
       net.ipv4.tcp_keepalive_probes 探测次数,默认值9次