转载 - Linux软中断不均的调优

4 minute read

背景

原文

http://www.aichengxu.com/view/9627015

原文

Rpc程序主要是io bound程序,这里主要针对的是linux的网络的部分性能调优,对于具体的问题具体分析。

性能监控

主要使用sysstat包里的系列软件,用于观察服务器的CPU、内存、网络等使用情况。

ubuntu下通过如下命令进行安装

sudo apt-get install sysstat

CPU监控

通过mpstat可以方便监控多核系统下的CPU使用率以及处理的中断数量。

mpstat是Multiprocessor Statistics的缩写,是实时系统监控工具。

其报告与CPU的一些统计信息,这些信息存放在/proc/stat文件中。

在多CPUs系统里,其不但能查看所有CPU的平均状况信息,而且能够查看特定CPU的信息。

mpstat 语法如下

Usage: mpstat [ options ] [ <interval> [ <count> ] ]
Options are:
[ -A ] [ -I { SUM | CPU | SCPU | ALL } ] [ -u ]
[ -P { <cpu> [,...] | ON | ALL } ] [ -V ]
-P {<cpu> [,…] | ON | ALL}

表示监控哪个CPU, cpu在[0,cpu个数-1]中取值, ALL表示监控所有cpu。

-I {SUM | CPU | SCPU | ALL }

报告中断统计信息,SUM显示总的中断数量,CPU显示每个cpu处理的每个中断数量, SCPU显示每个cpu处理的软中断的数量。

internal

相邻的两次采样的间隔时间,以s为单位

count

采样的次数,如果不写采样次数,则一直进行采样。

当没有参数时,mpstat则显示系统启动以后所有信息的平均值。

有interval时,第一行的信息自系统启动以来的平均信息。从第二行开始,输出为前一个interval时间段的平均信息。

一般用法如下

mpstat -P ALL 1 
mpstat -I SUM 1

在旧版的mpstat里无-I选项,会将intr/s作为-P选项的一列显示。

网卡监控

查看网卡信息

lspci -vvv

搜索Ethernet查看网卡型号、驱动、能力等相关信息。

通过ethtool查看网卡的信息以及修改网卡配置

$ ethtool eth0

Settings for eth0:
Supported ports: [ TP ]
Supported link modes:   10baseT/Half 10baseT/Full 
                        100baseT/Half 100baseT/Full 
                        1000baseT/Half 1000baseT/Full 
Supported pause frame use: No
Supports auto-negotiation: Yes
Advertised link modes:  10baseT/Half 10baseT/Full 
                        100baseT/Half 100baseT/Full 
                        1000baseT/Half 1000baseT/Full 
Advertised pause frame use: Symmetric
Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
MDI-X: Unknown
Supports Wake-on: g
Wake-on: g
Current message level: 0x000000ff (255)
           drv probe link timer ifdown ifup rx_err tx_err
Link detected: yes

上面给出的例子说明网卡有 10baseT,100baseT 和 1000baseT 三种选择,目前正自适应为 100baseT(Speed: 100Mb/s)

查看Ring buffer的大小

$ ethtool -g eth0
  
Ring parameters for eth0:
Pre-set maximums:
RX:   511
RX Mini:  0
RX Jumbo: 0
TX:   511
Current hardware settings:
RX:   200
RX Mini:  0
RX Jumbo: 0
TX:   511

设置Ring buffer的大小

$ sudo ethtool -G eth0 rx 400

查看网卡统计信息

$ sudo ethtool -S eth0
  
NIC statistics:
   rx_octets: 277931
   rx_fragments: 0
   rx_ucast_packets: 1750
   rx_mcast_packets: 30
   rx_bcast_packets: 975
   rx_fcs_errors: 0
   rx_align_errors: 0
   rx_xon_pause_rcvd: 0
   rx_xoff_pause_rcvd: 0
   rx_mac_ctrl_rcvd: 0
   rx_xoff_entered: 0
   rx_frame_too_long_errors: 0
   rx_jabbers: 0
   rx_undersize_packets: 0
   rx_in_length_errors: 0
   rx_out_length_errors: 0
   rx_64_or_less_octet_packets: 0
   rx_65_to_127_octet_packets: 0
   rx_128_to_255_octet_packets: 0
   rx_256_to_511_octet_packets: 0
   rx_512_to_1023_octet_packets: 0
   rx_1024_to_1522_octet_packets: 0
   rx_1523_to_2047_octet_packets: 0
   rx_2048_to_4095_octet_packets: 0
   rx_4096_to_8191_octet_packets: 0
   rx_8192_to_9022_octet_packets: 0
   tx_octets: 290648
   tx_collisions: 0
   tx_xon_sent: 0
   tx_xoff_sent: 0
   tx_flow_control: 0
   tx_mac_errors: 0
   tx_single_collisions: 0
   tx_mult_collisions: 0
   tx_deferred: 0
   tx_excessive_collisions: 0
   tx_late_collisions: 0
   tx_collide_2times: 0
   tx_collide_3times: 0
   tx_collide_4times: 0
   tx_collide_5times: 0
   tx_collide_6times: 0
   tx_collide_7times: 0
   tx_collide_8times: 0
   tx_collide_9times: 0
   tx_collide_10times: 0
   tx_collide_11times: 0
   tx_collide_12times: 0
   tx_collide_13times: 0
   tx_collide_14times: 0
   tx_collide_15times: 0
   tx_ucast_packets: 1876
   tx_mcast_packets: 0
   tx_bcast_packets: 0
   tx_carrier_sense_errors: 0
   tx_discards: 0
   tx_errors: 0
   dma_writeq_full: 0
   dma_write_prioq_full: 0
   rxbds_empty: 0
   rx_discards: 0
   rx_errors: 0
   rx_threshold_hit: 0
   dma_readq_full: 0
   dma_read_prioq_full: 0
   tx_comp_queue_full: 0
   ring_set_send_prod_index: 0
   ring_status_update: 0
   nic_irqs: 0
   nic_avoided_irqs: 0
   nic_tx_threshold_hit: 0
   mbuf_lwm_thresh_hit: 0

结果如上,可以查看各种类型包的数量以及丢包量等相关数据。

通过sysstat的sar命令查看网卡流量等相关信息。

sar 的命令如下

sar [options] [ <interval> [ <count> ]]

主要用其中的-n选项监控网络子系统相关的数据。

-n { keyword [,...] | ALL }

keyword为DEV可以报告网络的流量相关信息,EDEV可以报告错误包的相关信息。

$ sar -n DEV 1
  
Linux 3.2.0-23-generic (ubuntu)   05/30/2012  _x86_64_  (4 CPU)

04:20:34 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
04:20:35 PM        lo      2.00      2.00      4.73      4.73      0.00      0.00      0.00
04:20:35 PM      eth0      9.00      3.00      5.33      0.25      0.00      0.00      0.00

04:20:35 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
04:20:36 PM        lo      2.00      2.00      4.63      4.63      0.00      0.00      0.00
04:20:36 PM      eth0      9.00      3.00      5.55      0.22      0.00      0.00      0.00
  
$ sar -n EDEV 1
  
Linux 3.2.0-23-generic (ubuntu)   05/30/2012  _x86_64_  (4 CPU)
  
04:23:48 PM     IFACE   rxerr/s   txerr/s    coll/s  rxdrop/s  txdrop/s  txcarr/s  rxfram/s  rxfifo/s  txfifo/s
04:23:49 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:23:49 PM      eth0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
  
04:23:49 PM     IFACE   rxerr/s   txerr/s    coll/s  rxdrop/s  txdrop/s  txcarr/s  rxfram/s  rxfifo/s  txfifo/s
04:23:50 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:23:50 PM      eth0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

调优设置

主要对于网卡中断负载以及tcp协议栈进行调优。

最大句柄数

linux限制了每个进程能开的最大句柄数,默认不进行修改的话为1024。可以通过ulimit进行参看以及设置。

$ ulimit -a
  
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 30006
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 30006
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited  
  
$ ulimit -n
1024
  
$ ulimit -n 32768

可以通过参看/proc/$pid/limits查看当前进程的限制::

$ cat /proc/11020/limits
  
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            8388608              unlimited            bytes     
Max core file size        unlimited            unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             30006                30006                processes 
Max open files            1024                 4096                 files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       30006                30006                signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us

软中断分布不均

对于网络程序,容易导致网络中断分布不均导致cpu某个核被压爆,通过mpstat可以进行监控。

对于内核版本为2.6.35的系统,默认已经安装RPS以及RFS补丁,可以参考如下文档进行设置。

http://code.google.com/p/kernel/wiki/NetScalingGuide

对于内核版本为2.6.35以下的系统,如果是多队列的网卡可以进行如下设置。

参看中断号

$ cat /proc/interrupts 
  
         CPU0       CPU1       CPU2       CPU3       
0:       1652          0          0          0   IO-APIC-edge      timer
1:     870400          0          0          0   IO-APIC-edge      i8042
8:          1          0          0          0   IO-APIC-edge      rtc0
9:        194          0          0          0   IO-APIC-fasteoi   acpi
12:    4429616          0          0          0   IO-APIC-edge      i8042
16:     134965          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb1, mmc0
23:    1546310          0     292374          0   IO-APIC-fasteoi   ehci_hcd:usb2
40:     236364          0          0          0   PCI-MSI-edge      ahci
41:         17          0          0          0   PCI-MSI-edge      mei
42:        142          0          0          0   PCI-MSI-edge      snd_hda_intel
43:   19547644          0          0          0   PCI-MSI-edge      i915@pci:0000:00:02.0
44:    1638700          0          0          0   PCI-MSI-edge      eth0-0
45:    1779727          0          0          0   PCI-MSI-edge      eth0-1
46:     725208          0          0          0   PCI-MSI-edge      eth0-2
47:     894102          0          0      50434   PCI-MSI-edge      eth0-3
48:     493319     106065          0          0   PCI-MSI-edge      eth0-4

如上所示,可以看到网络接口eth0分配了44-48的5个中断号。

设置中断亲和,将队列绑定到不同的CPU上。

计算中断亲和可以参考 http://www.vpsee.com/2010/07/smp-irq-affinity/

$ echo 2 > /proc/irq/44/smp_affinity
$ echo 4 > /proc/irq/45/smp_affinity
...

设置完后通过mpstat监控是否分布均匀了。

Flag Counter

digoal’s 大量PostgreSQL文章入口