Skip to content

Latest commit

 

History

History
198 lines (149 loc) · 10.5 KB

linux-performance-analysis-and-optimization.md

File metadata and controls

198 lines (149 loc) · 10.5 KB

linux性能分析及调优

##第一节:性能瓶颈 计算机中,cpu是最重要的一个子系统,负责所有计算任务。基于摩尔定律的发展,cpu是发展最快的一个硬件,所以瓶颈很少出现在cpu上。

机器CPU使用情况监控

良好状态指标

CPU利用率:User Time <= 70%,System Time <= 35%,User Time + System Time <= 70%。
上下文切换:与CPU利用率相关联,如果CPU利用率状态良好,大量的上下文切换也是可以接受的。
可运行队列:每个处理器的可运行队列 <=3 个线程。

监控工具vmstat

$ 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
14 0  140  2904316 341912 3952308   0  0     0  460 1106 9593  36 64 1  0  0
17 0  140  2903492 341912 3951780   0  0     0  0   1037 9614  35 65 1  0  0
20 0  140  2902016 341912 3952000   0  0     0  0   1046 9739  35 64 1  0  0
17 0  140  2903904 341912 3951888   0  0     0  76  1044 9879  37 63 0  0  0
16 0  140  2904580 341912 3952108   0  0     0  0   1055 9808  34 65 1  0  0

重要参数:

r   可运行队列的线程数,这些线程都是可运行状态,只不过CPU暂时不可用;一般要求小于CPU*3的数量。
    cat /proc/stat 可以看到有几个CPU。
b   被blocked的进程数,正在等待IO请求。
in  interrupts,被处理过的中断数。
cs  context switch,系统上正在做上下文切换的数目。
us  用户占用CPU的百分比。
sys 内核和中断占用CPU的百分比。
id  CPU完全空闲的百分比。

上例可得:

sy高us低,以及高频度的上下文切换(cs),说明应用程序进行了大量的系统调用。
这台4核机器的r应该在12个以内,现在r在14个线程以上,此时CPU负荷很重。

一般我们认为,如果是4核机器,r高于8是,应该就是负载很高了。

可调优性能参数

通过调整进程优先级调整

nice 命令来调整进程优先级别;可调范围从 -20 到 19,如:renice 5 pid

通过调整cpu的亲和度来集中处理某一个中断类型

将系统发出的中断都绑定在一个cpu上,这样其他cpu继续执行自己正在执行的线程,不被中断打扰,从而较少了线程上下文切换时间,增强性能。

cpu亲和度的概念:在多核cpu中,linux操作系统抢占式调度系统,按照cpu时间片/中断/等不断调度进程给cpu去执行的。如果在一个时间片调度线程1在cpu1上运行,另外一个时间片调度线程1在cpu2上去运行,这样会造成线程执行速度慢,性能降低。而linux的进程调度有个亲和度算法可以将尽量将进程每次都调度到同一个cpu上处理;linux调度时当然也有Loadbalance算法保证进程调度的均匀负载的。

$ sudo echo 03 > /proc/irq/19/smp-affinity   # 将中断类型为19的中断绑定到第三个cpu上处理

第二节:内存性能瓶颈

首先,linux的内存管理是聪明和智能的;linux通过(virtual memory manage)来管理内存的;对于大多数应用,linux是不直接写到硬盘上去的,而是先写到 virtual memory manage 管理的文件系统缓存(也在内存中的)里 ,方便应用的后续的读请求;因为和磁盘的I/O操作是昂贵的;linux会根据一些算法策略适当的时候同步到硬盘的;这就是为什么我们运行linux一段时间后,发现可用内存那么少的原因,多数被 cache+buffer 占用;所以**我们提高性能的办法就是减少写到磁盘的次数,提高每次写磁盘时的效率质量**。

机器内存使用情况监控

良好状态指标

swap in(si)==0,swap out(so)==0
应用程序可用内存/系统物理内存 <= 70%

监控工具vmstat

$ 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 3   252696 2432 268  7148  3604  2368  3608  2372   288  288   0  0  21 78  1
0 2   253484 2216 228  7104  5368  2976  5372  3036   930  519   0  0  0  100 0
0 1   259252 2616 128  6148  19784 18712 19784 18712  3821 1853  0  1  3  95  1
1 2   260008 2188 144  6824  11824 2584  12664 2584   1347 1174  14 0  0  86  0
2 1   262140 2964 128  5852  24912 17304 24952 17304  4737 2341  86 10 0  0   4

重要参数

swpd   已使用的 SWAP 空间大小,KB 为单位。
free   可用的物理内存大小,KB 为单位。
buff   物理内存用来缓存读写操作的buffer大小,KB 为单位。
cache  物理内存用来缓存进程地址空间的 cache 大小,KB 为单位。
si     数据从 SWAP 读取到 RAM(swap in)的大小,KB 为单位。
so     数据从 RAM 写到 SWAP(swap out)的大小,KB 为单位。

上例可得

物理可用内存 free 基本没什么显著变化,swapd 逐步增加,说明最小可用的内存始终保持在
256MB(物理内存大小) * 10% = 2.56MB 左右,当脏页达到10%的时候就开始大量使用swap。

这个10%来自”/proc/sys/vm/dirty_background_ratio“。

可调优性能参数

通过调节缓存的脏数据同步到硬盘的策略:

脏数据表示没有被当前的线程使用的数据。

# 当脏数据占据物理内存10%时,触发pdflush同步到硬盘;小心调节,会大幅度的影响性能。
$ sudo echo 10 > /proc/sys/vm/dirty_background_ratio

# 当脏数据在物理内存的逗留时间超过2000ms时被同步到硬盘
$ sudo echo 2000 > /proc/sys/vm/dirty_expire_centisecs

通过调节swap参数,来优化linux虚拟内存管理

基于程序的局部性原理,linux通过虚拟内存机制来实现并发运行进程,linux发现物理内存不够用时,会根据LRU算法将一部分内存swap out到硬盘;当运行被换出的那个线程时,在swap in 到内存里。

# 值为0表示尽量都用物理内存,值为100表示积极的使用swap分区,一般为60; 在紧急处理线上问题时,可以紧急使用一下。
$ sudo echo 10 > /proc/sys/vm/swappiness

更多的参数

pdfulsh 设置

       变量            |   描述

--------------------------|--------------------------------------------------------------- dirty_background_ratio | 占全部内存的百分比。当内存中空闲页到达这个比例时,pdflush线程开始回写脏页 dirty_expire_centisecs | 该数值以百分之一秒为单位,它描述超时多久的数据将被周期性执行的pdflush写出 dirty_ratio | 占全部内存百分比,当一个进程产生的脏页达到这个比例时,就开始被写出 dirty_writeback_centisecs | 该数值以百分之一秒为单位,它描述pdflush线程的运行频率 laptop_mode | 一个布尔值,用于控制laptop电脑模式

第三节:磁盘I/O可调性能参数

linux的子系统VFS(virtural file system)虚拟文件系统;从高层将各种文件系统,以及底层磁盘特性隐藏,对程序员提供:read、write、delete等文件操作;这就是之所以我们可以在linux上mount多种不同格式的文件系统的,而window确不行。

当然基于虚拟文件系统、文件系统、文件系统驱动程序、硬件特性方面,都能找到性能瓶颈。

(1) 选择适合应用的文件系统。
(2) 调整进程I/O请求的优先级,分三种级别:1代表real time; 2代表best-effort; 3代表idle。
    如:ionice -c 1 -p 1113  # 给进程1113的I/O优先级设置为最高优先级
(3) 根据应用类型,适当调整page size 和block size。
(4) 升级驱动程序。

第四节:网络可调性能参数

对于我们web应用来说,网络性能调整如此重要,linux的网络支持是无与伦比的;是作为网络服务器的首先;对于web服务来说:除了应用的响应速度外,linux网络管理子系统,网卡,带宽都可能成为性能瓶颈。

网络参数可以在/proc/sys/net/ipv4/下面的文件中进行配置,see IPv4的一般设置

可以查看和设置的参数

查看网卡设置是否全双工传输的

$ echtool eth0

设置MTU(最大传输单元)

如果数据包的长度大于mtu的长度时,很容易出现丢包情况。在带宽G以上的时候,要考虑将MTU增大,提高传输性能。

$ ifconfig eth0 mtu 9000 up

增加网络数据缓存

传输数据时linux是将包先放入缓存,填满缓存后即发送出去;读操作类似。

$ sysctl -w net.ipv4.tcp_rmem="4096 87380 8388608"  # 设置tcp读缓存:最小缓存,初始化时,最大缓存
$ sysctl -w net.ipv4.tcp_wmem="4096 87380 8388608"  # 设置tcp写缓存:最小缓存,初始化时,最大缓存

由于是先将数据放入缓存再发送,或收取收据,那么当内存紧张或内存不够用时,网络丢包就可能出现。

禁用window_scaling,并且直接设置window_size

$ sysctl -w net.ipv4.tcp_window_scaling=0

设置TCP连接可重用性

对于 TIME_OUT 状态的TCP连接可用于下一个TCP重用,这样减少了三次握手和创建时间,非常提高性能,尤其对于web server。如: 开启可重用tcp功能:

$ sysctl -w net.ipv4.tcp_tw_reuse=1
$ sysctl -w net.ipv4.tcp_tw_recyle=1

禁用掉没必要的tcp/ip协议功能

比如:icmp、broadcast包的接收。

减小处于keepalive的TCP连接的默认过期时间

$ sysctl -w net.ipv4.tcp_keepalive_time=1800   # 设置过期时间为 1800s

设置最大tcp正在连接状态(还没ESTABLISHED)队列长度

避免由于太多的tcp连接过来,导致服务器挂掉,比如DoS攻击。

$ sysctl -w net.ipv4.tcp_max_syn_backlog=4096

绑定tcp类型的中断到一个cpu上

让cpu去亲和这个类型中断,避免频繁的中断,影响线程调度性能。

总结

我们在性能优化一个应用时,首要的是设定优化要达到的目标,然后寻找瓶颈,调整参数,达到优化目的;但是寻找瓶颈时可能是最累的,要从大范围,通过很多用例,很多测试报告,不断的缩小范围,最终确定瓶颈点。以上这些参数只是个认识,系统性能优化中可能用到,但并不是放之四海而皆准的; 有的参数要边测试,边调整的。


From: http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520123724410678/