首页 > 代码库 > (转)linux性能优化总结
(转)linux性能优化总结
通常监控的子系统有:
CPU
Memory
IO
Network
应用类型
IO相关,处理大量数据,需要大量内存和存储,频繁IO读写数据,对CPU的要求比较小,大部分时候CPU都在等待硬盘,比如,数据库服务器、文件服务器等。
CPU相关,需要使用大量的CPU能力,比如高并发的web/mail服务器、图像/视频处理、可续计算等。
查看机器状态命令
>vmstat 1
一些常用的监控命令和工具。
top 查看进程活动状态以及一些系统状况
vmstat 查看系统状态、硬件和系统信息等
iostat 查看CPU 负载,硬盘状况
sar 综合工具,查看系统状况
mpstat 查看多处理器状况
netstat 查看网络状况
iptraf 实时网络状况监测
tcpdump 抓取网络数据包,详细分析
mpstat 查看多处理器状况
tcptrace 数据包分析工具
netperf 网络带宽工具
dstat 综合工具,综合了 vmstat, iostat, ifstat, netstat 等多个信息
CPU底线
65%-70% User Time,
30%-35% System Time,
0%-5% Idle Time;
上下文切换,上下文切换应该和 CPU 利用率联系起来看,如果能保持上面的 CPU 利用率平衡,大量的上下文切换是可以接受的;
可运行队列,每个可运行队列不应该有超过1-3个线程(每处理器)。双处理器系统的可运行队列里不应该超过6个线程。
工具vmstat
>vmstat 1
参数记录:
r,可运行队列的线程数,这些线程都是可运行状态,只不过 CPU 暂时不可用;
b,被 blocked 的进程数,正在等待 IO 请求;
in,被处理过的中断数
cs,系统上正在做上下文切换的数目
us,用户占用 CPU 的百分比
sys,内核和中断占用 CPU 的百分比
wa,所有可运行的线程被 blocked 以后都在等待 IO,这时候 CPU 空闲的百分比
id,CPU 完全空闲的百分比
比较闲的机器返回情况:
>vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 2672604 570440 5243936 0 0 1 10 2 4 1 0 99 0 0
0 0 0 2672648 570440 5243936 0 0 0 52 14 462 0 0 99 0 0
0 0 0 2672648 570440 5243936 0 0 0 0 5 444 0 0 100 0 0
0 0 0 2672648 570440 5243936 0 0 0 0 11 458 0 0 100 0 0
0 0 0 2672648 570440 5243944 0 0 0 0 21 478 0 0 100 0 0
0 0 0 2672648 570440 5243944 0 0 0 8 8 476 1 1 98 0 0
0 0 0 2672648 570440 5243944 0 0 0 0 5 471 0 0 100 0 0
跑了一个虚拟机的机器:
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 40 1735980 210932 8855852 0 0 0 6 3 1 3 3 94 0 0
1 0 40 1736088 210932 8855852 0 0 0 21 7 1264 10 9 81 0 0
工具mpstat
>mpstat -P ALL 5
我的目标机器没有这个工具。
参考:
http://www.blogjava.net/cssseek/archive/2010/10/25/335791.html
内存包括物理内存和虚拟内存,虚拟内存(Virtual Memory)把计算机的内存空间扩展到硬盘,物理内存(RAM)和硬盘的一部分(SWAP)组合在一起作为虚拟内存为计算机提供连贯的虚拟内存空间。
好处是内存变多了,缺点是硬盘读写速度比内存慢很多,并且RAM和SWAP之间的交换增加了系统负担。
在 操作系统里,虚拟内存被分成页,在X86系统上每个页大小事4KB。Linux内核读写虚拟内存是以“页”为单位操作的,把内存移动到硬盘交换空间 (SWAP)和从交换空间读取到内存都是按页来读写的。内存和SWAP的这种交换过程称为页面交换(Paging),值得注意的是paging和 swapping是两个完全不同的概念。swapping在操作系统里是指把某程序完全交换到硬盘以腾出内存给新程序使用,paging只交换程序的部 分。
kswapd daemon 用来检查 pages_high 和 pages_low,如果可用内存少于 pages_low,kswapd 就开始扫描并试图释放,并且重复扫描释放的过程直到可用内存大于 pages_high 为止。扫描的时候检查3件事:
1)如果页面没有修改,把页放到可用内存列表里;
2)如果页面被文件系统修改,把页面内容写到磁盘上;
3)如果页面被修改了,但不是被文件系统修改的,把页面写到交换空间。
pdflush daemon 用来同步文件相关的内存页面,把内存页面及时同步到硬盘上。比如打开一个文件,文件被导入到内存里,对文件做了修改后并保存后,内核并不马上保存文件到硬 盘,由 pdflush 决定什么时候把相应页面写入硬盘,这由一个内核参数 vm.dirty_background_ratio 来控制,比如下面的参数显示脏页面(dirty pages)达到所有内存页面10%的时候开始写入硬盘。
# /sbin/sysctl -n vm.dirty_background_ratio
10
我的系统是
>/sbin/sysctl -n vm.dirty_background_ratio
5
>vmstat 5
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 40 1735980 210932 8855852 0 0 0 6 3 1 3 3 94 0 0
1 0 40 1736088 210932 8855852 0 0 0 21 7 1264 10 9 81 0 0
参数解释:
swpd, 已使用的 SWAP 空间大小,KB 为单位;
free, 可用的物理内存大小,KB 为单位;
buff, 物理内存用来缓存读写操作的 buffer 大小,KB 为单位;
cache, 物理内存用来缓存进程地址空间的 cache 大小,KB 为单位;
si, 数据从 SWAP 读取到 RAM(swap in)的大小,KB 为单位;
so, 数据从 RAM 写到 SWAP(swap out)的大小,KB 为单位;
bi, 磁盘块从文件系统或 SWAP 读取到 RAM(blocks in)的大小,block 为单位;
bo, 磁盘块从 RAM 写到文件系统或 SWAP(blocks out)的大小,block 为单位;
IO介绍
磁盘通常是最慢的子系统,CPU访问磁盘要设计到机械操作,比如转轴、寻轨等。
查看页面大小的命令:
>/usr/bin/time -v date
Thu Nov 25 14:20:03 CST 2010
Command being timed: "date"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: ?%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 0
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 217
Voluntary context switches: 1
Involuntary context switches: 1
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
缺页中断
当程序启动的时候,LINUX内核首先检查CPU的缓存和物理内存,如果数据已经在内存就忽略,如果数据不再内存就引起一个缺页中断(Page Fault),然后从硬盘读取缺页,并把缺页缓存到物理内存里。
缺页中断可以分为主缺页中断(Major Page Fault)和次缺页中断(Minor Page Fault)。从硬盘读取数据而产生的中断时主缺页中断,数据已经读入内存并被缓存起来,从内存缓存区中而不是直接从硬盘中读取数据而产生的中断是次缺页中断。
上 面的内存缓存区起到了预读硬盘的作用,内核先在物理内存里寻找缺页,没有的话产生次缺页中断从内存缓存里找,如果还没有发现的话就从硬盘读取。很显然,把 多余的内存拿出来做成内存缓存区提高了访问速度,这里还有一个命中率的问题,运气好的话如果每次缺页都能从内存缓存区读取的话将会极大提高性能。要提高命 中率的一个简单方法就是增大内存缓存区面积,缓存区越大预存的页面就越多,命中率也会越高。下面的 time 命令可以用来查看某程序第一次启动的时候产生了多少主缺页中断和次缺页中断:
>/usr/bin/time -v date
...
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 217
...
File Buffer Cache
从 上面的内存缓存区(也叫文件缓存区 File Buffer Cache)读取页比从硬盘读取页要快得多,所以 Linux 内核希望能尽可能产生次缺页中断(从文件缓存区读),并且能尽可能避免主缺页中断(从硬盘读),这样随着次缺页中断的增多,文件缓存区也逐步增大,直到系 统只有少量可用物理内存的时候 Linux 才开始释放一些不用的页。
查看服务器上的物理内存和文件缓存区的情况:
>cat /proc/meminfo
MemTotal: 16 469 796 kB
MemFree: 1 530 664 kB
Buffers: 211 048 kB
Cached: 8 955 204 kB
MemTotal总内存 16G;
MemFree空闲内存 1.5G;
磁盘缓存(Buffers)200MB;
文件缓存区(Cached)8G;
页面类型
Read pages 只读页,那些通过主缺页中断从硬盘读取的页面,包括不能修改的静态文件、可执行文件、库文件等。当内核需要它们的时候把它们读到内存中,当内存不足的时候,内核就释放它们到空闲列表,当程序再次需要它们的时候需要通过缺页中断再次读到内存。
Dirty pages脏页,那些在内存中被修改过的数据页,比如文本文件等。这些文件由 pdflush 负责同步到硬盘,内存不足的时候由 kswapd 和 pdflush 把数据写回硬盘并释放内存。
Anonymous pages匿名页,那些属于某个进程但是又和任何文件无关联,不能被同步到硬盘上,内存不足的时候由 kswapd 负责将它们写到交换分区并释放内存。
IO‘s Per Second(IOPS)
顺序IO和随机IO
顺 序 IO 是指同时顺序请求大量数据,比如数据库执行大量的查询、流媒体服务等,顺序 IO 可以同时很快的移动大量数据。可以这样来评估 IOPS 的性能,用每秒读写 IO 字节数除以每秒读写 IOPS 数,rkB/s 除以 r/s,wkB/s 除以 w/s. 顺序 IO 更应该重视每次 IO 的吞吐能力(KB per IO)
随机 IO 是指随机请求数据,其 IO 速度不依赖于数据的大小和排列,依赖于磁盘的每秒能 IO 的次数,比如 Web 服务、Mail 服务等每次请求的数据都很小,随机 IO 每秒同时会有更多的请求数产生,所以磁盘的每秒能 IO 多少次是关键。
运行命令:
[root@cd5 ~]# iostat -kx 1
-bash: iostat: command not found
没有安装对应的包,执行安装命令:
>yum install sysstat
>iostat -kx 1
Linux 2.6.26.8-57.fc8 (xxxxxxxx) 11/25/2010
avg-cpu: %user %nice %system %iowait %steal %idle
0.44 2.60 3.14 0.02 0.00 93.80
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 0.01 4.66 0.11 1.11 1.57 23.06 40.43 0.01 10.86 0.72 0.09
sda1 0.00 0.00 0.00 0.00 0.00 0.00 14.67 0.00 3.68 2.74 0.00
sda2 0.01 4.66 0.11 1.11 1.57 23.06 40.43 0.01 10.86 0.72 0.09
dm-0 0.00 0.00 0.12 5.76 1.57 23.06 8.37 0.61 103.20 0.15 0.09
dm-1 0.00 0.00 0.00 0.00 0.00 0.00 8.00 0.00 3.01 0.78 0.00
SWAP
当 系统没有足够物理内存来应付所有请求的时候就会用到 swap 设备,swap 设备可以是一个文件,也可以是一个磁盘分区。不过要小心的是,使用 swap 的代价非常大。如果系统没有物理内存可用,就会频繁 swapping,如果 swap 设备和程序正要访问的数据在同一个文件系统上,那会碰到严重的 IO 问题,最终导致整个系统迟缓,甚至崩溃。swap 设备和内存之间的 swapping 状况是判断 Linux 系统性能的重要参考,我们已经有很多工具可以用来监测 swap 和 swapping 情况,比如:top、cat /proc/meminfo、vmstat 等:
>cat /proc/meminfo
MemTotal: 16 469 796 kB
MemFree: 1 524 940 kB
Buffers: 211 776 kB
Cached: 8 960 460 kB
SwapCached: 28 kB
...
SwapTotal: 2 031 608 kB
SwapFree: 2 031 568 kB
>free -m
total used free shared buffers cached
Mem: 16083 14595 1487 0 206 8751
-/+ buffers/cache: 5637 10446
Swap: 1983 0 1983
关系:total(1002M) = used(769M) + free(232M)
第二部分(-/+ buffers/cache):
(-buffers/cache) used内存数:286M (指的第一部分Mem行中的used - buffers - cached)
(+buffers/cache) free内存数: 715M (指的第一部分Mem行中的free + buffers + cached)
可见-buffers/cache反映的是被程序实实在在吃掉的内存,而+buffers/cache反映的是可以挪用的内存总数。
参考:
http://www.blogjava.net/cssseek/archive/2010/10/27/335794.html
Linux性能检查(三)网络
我们可以通过 ethtool 工具来查看网卡的配置和工作模式:
>/sbin/ethtool eth0
Settings for eth0:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 1
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: g
Wake-on: d
Current message level: 0x000000ff (255)
Link detected: yes
说明网卡有 10baseT,100baseT 和 1000baseT 三种选择,目前正自适应为 100baseT(Speed: 100Mb/s)。
iptraf
iptraf 就是一个很好的查看本机网络吞吐量的好工具
[root@cd5 ~]# iptraf -d eth
-bash: iptraf: command not found
安装该工具
>yum install iptraf
netperf
略过
iperf
略过
tcpdump 和 tcptrace
先用 tcpdump 按要求捕获数据包把结果输出到某一文件,然后再用 tcptrace 分析其文件格式。
>/usr/sbin/tcpdump -w network.dmp
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
安装tcptrace工具
首页:http://www.tcptrace.org/download.html
解开压缩
>tar zxvf tcptrace-6.6.7.tar.gz
>mv tcptrace-6.6.7 /opt/
>cd /opt/tcptrace-6.6.7/
>./configure
>make
出错提示:
tcpdump.c:66:18: error: pcap.h: No such file or directory
tcpdump.c:72: error: expected declaration specifiers or ‘...’ before ‘pcap_handler’
tcpdump.c:75: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
tcpdump.c: In function ‘callback’:
tcpdump.c:100: error: dereferencing pointer to incomplete type
tcpdump.c:104: error: ‘pcap’ undeclared (first use in this function)
tcpdump.c:104: error: (Each undeclared identifier is reported only once
tcpdump.c:104: error: for each function it appears in.)
tcpdump.c: In function ‘pread_tcpdump’:
tcpdump.c:251: error: ‘pcap’ undeclared (first use in this function)
tcpdump.c:251: error: ‘pcap_handler’ undeclared (first use in this function)
tcpdump.c:251: error: expected ‘)’ before ‘callback’
解决方案,安装libpcap
下载文件:
http://www.tcpdump.org/release/
>tar zxvf libpcap-1.1.1.tar.gz
>mv libpcap-1.1.1 /opt/
>./configure
>make
>make install
问题解决。
继续make tcptrace的包
>cd /opt/tcptrace-6.6.7/
>make
>make install
安装成功后,直接执行命令
>tcptrace network.dmp
报错如下:
tcptrace: error while loading shared libraries: libpcap.so.1: cannot open shared object file: No such file or directory
解决方法,在libpcap里面查找这个文件:
[root@localhost libpcap-1.1.1]# ls *.so.*
libpcap.so.1.1.1
拷贝该文件过去:
>cp libpcap.so.1.1.1 /usr/lib/libpcap.so.1
问题解决,执行命令
>tcptrace network.dmp
[root@localhost tmp]# tcptrace network.dmp
1 arg remaining, starting with ‘network.dmp‘
Ostermann‘s tcptrace -- version 6.6.7 -- Thu Nov 4, 2004
4 packets seen, 4 TCP packets traced
elapsed wallclock time: 0:00:05.403615, 0 pkts/sec analyzed
trace file elapsed time: 0:00:30.744403
TCP connection info:
1: 192.168.56.104:pcanywherestat - 192.168.56.101:53290 (a2b) 2> 2<
参考:
http://www.blogjava.net/cssseek/archive/2010/10/29/335797.html