转载 - Linux软中断不均的调优
背景
原文
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监控是否分布均匀了。