本文档摘录Linux系统性能调优的手段,以期为应用程序设计提供技术框架指导。 系统的性能问题不是孤立的,解决了一个性能瓶颈,可能会出现另一个性能瓶颈; 性能优化的最终目的是:在一定范围内,使系统的各项资源使用趋于合理并保持 一定的平衡(就是在硬件、操作系统、应用软件之间找到一个平衡点)。
- IOPS
- <常用指标> 每秒的输入、输出操作次数
- 吞吐量
- <常用指标> 评价工作执行效率
- 响应时间
- 一次操作的完成时间
- 延时
- <常用指标> 操作中等待服务的时间
- 使用率
- <常用指标> 在给定的时间区间内,资源的繁忙程度
- 饱和度
- 某一资源无法满足服务的排队工作量
- 瓶颈
- 限制系统性能的资源
- 工作负载
- 系统的输入,或对系统所施加的负载
- 缓存
- 用于复制或缓冲一定量数据的高速存储区域
- 罗列系统的硬件资源
CPU 插槽、核、硬件线程 内存 网卡接口 以太网端口 存储设备 磁盘 控制器 存储、网络 互联 CPU、内存、IO - 罗列软件资源
互斥锁 线程池 进程/线程容量 文件描述符容量 缓存 - 分析静态性能
处理的为架构配置的问题;其他方法着重负载加载后的性能,动态性能 该组件是需要的麽? 配置是针对预期的工作负载设定的麽? 组件的自动配置是最优的麽? 有组件出现错误麽?是在降级状态麽? - 检查工作负载
负载是谁产生的?进程ID、用户ID、远程IP 负载为什么会被调用?代码路径、堆栈跟踪 负载有什么特征?IOPS、吞吐量、方向、变动 负载的变化规率 - 了解资源的指标
使用率 超过60%,可能是问题 饱和度 任何程度的饱和都是问题 错误 所有错误都值得研究 - 向下深挖、逐步细化
以延时为主要指标,查找瓶颈点 以事件为驱动,查找瓶颈点
CPU推动所有软件的运行,因而通常是性能分析的首要目标;现代系统一般有多 颗CPU,通过内核调度器共享给所有运行软件,当所需求的CPU资源超过了系统力 所能及的范围时,进程里的线程将会排队,等待轮候自己运行的机会。等待将给 应用程序的运行带来严重延时,使得性能下降。
可分三个层次研究CPU的消耗:1)进程、线程或任务;2)应用程序或内核的代码 路径;3)CPU指令的执行和周期行为。
- CPI
- 每指令周期数
较高代表经常停滞,通常在访问内存;较低代表基本没有停滞,指令的吞吐量较高 - 平均负载
- 处于runnable或uninterruptable状态的进程个数
runnable进程,正使用CPU或等待使用CPU uninterruptable进程,等待IO操作(如磁盘)
- 超线程技术
可以使得当前线程在访问内存间隙,处理器去执行另外一个线程;一般超线 程的物理CPU被当作两个独立的CPU
- 使用率
- CPU繁忙程度
- 饱和度
- 可运行线程排队等待CPU的程度
- 错误
- CPU错误
- CPU负载
- 归纳出特征
平均负载 用户时间与系统时间比 系统调用频率 自愿上下文切换频率 中断频率
- 运算性能瓶颈
平均负载过重:
提升时钟频率 提高L1/L2缓存容量 改进CPU架构 - 调度性能瓶颈
IO wait占比过高 Context switch过高 硬中断占比过高 软中断占比过高, 如大量数据包从网卡到IP层
- 编译器选项
- 调整优先级
- 进程绑定
- 指令taskset
- 独占CPU组
- /dev/cpuset
- 资源控制
- cgroup
- BIOS调优
系统主存用于存储应用程序和内核指令,包括它们的工作数据,以及文件系统 缓存;一旦主存填满,系统会在主存和磁盘等慢速设备之间交换数据,此过程 比较缓慢,容易称为系统瓶颈。
- 主存
- 物理内存
- 虚拟内存
- 匿名内存
- 无文件系统位置(路径)的内存,如进程堆
- 使用情况
- 换页频率
- swap空间换入换出速率是表征内存出现瓶颈的重要标志
最重要的调优手段是保证应用程序保留在主存中,并且避免换页和交换经常发生
研究应用程序IO性能时,文件系统性能比磁盘性能更重要;一般文件系统通过 缓存、缓冲及异步IO等手段来缓和磁盘延时对应用程序的影响。
- 逻辑IO
- 应用程序发给文件系统的IO
- 物理IO
- 文件系统发给磁盘的IO
- inode
- 索引节点
包含文件系统对象元数据的数据结构,如访问权限、时间戳、数据指针等
- 操作频率
- 操作延时
- 使用内存文件系统tmpfs
- 调整进程最大文件句柄
sudo vi /etc/security/limits.conf *soft nofile 60000 * hard nofile 60000
网络往往是大系统的性能瓶颈点,改进网络性能可从以下入手:1)改进网络延时; 2)改善网络吞吐;3)消除丢包引起的延时异常。
- 接口
- 网络接口端口的逻辑实例
- 数据包
- IP级可路由的报文
- 帧
- 物理网络级的报文
- 带宽
- 最大数据传输速率
- 吞吐量
- 两个网络端点间的数据传输率
- 延时
- 报文往返端点所需的时间
主机名解析延时 ping延时 评估网络延时 连接延时 评估TCP等协议的新建延时 首字节延时 评估目标服务器的处理延时(连接建立后) - 连接积压队列
- 用户进程接受前的TCP连接队列
测量其导致的丢包是衡量网络连接饱和度的方法
- 使用率
接口忙于发送和接收帧的时间:
当前吞吐量/当前的协商速度 - 连接数
- 饱和度
由于接口满负载,额外的队列、缓冲或者阻塞的程度:
可通过TCP重传统计信息查看 - TCP重传输
- TCP乱序数据包
- 错误
校验错误、冲突等 - 工作负载特征
网络接口吞吐量 RX、TX,B/s 网络接口IOPS 帧每秒 TCP连接率 每秒连接数 - 延时
套接字读写耗时 连接延时(注意非阻塞) TCP连接延时(三次握手) TCP首字节延时(连接建立到接受到第一个字节) TCP连接持续时间 网络往返延时 中断延时(网卡收到中断到被协议栈处理) 跨栈延时(数据包穿越内核TCP/IP协议栈) - TCP发送/接收缓存
- TCP积压队列
- socket buffer出现泄露
sudo cat /proc/slabinfo | grep skb - 网卡丢包
- 网卡出错
- cpu软中断过高
- net.core.rmem_max = 16777216
- net.core.wmem_max = 16777216
- net.ipv4.tcp_rmem = 4096 87380 16777216
- net.ipv4.tcp_wmem = 4096 65536 16777216
- net.ipv4.tcp_max_syn_backlog = 4096
- net.core.somaxconn = 1024
- net.core.netdev_max_backlog = 10000
- net.ipv4.tcp_sack = 1
- net.ipv4.tcp_fack = 1
- net.ipv4.tcp_tw_reuse = 1
- net.ipv4.tcp_tw_recycle = 1
- ifconfig eth0 txqueuelen 10000
一般分为两类,CPU bound、IO bound;Web服务器等服务类程序属于前者;数据 库服务器、cache服务器属于后者。
检测工具要么基于计数器,要么基于跟踪事件;而它们的数据来源包括/proc、/sys、 kstat等。
内核维护了各种统计数据,称为计数器,用于对事件进行计数;被认为是“0开销”, 因为它们默认开启,并由内核维护。唯一的开销是从用户空间获取它们的数值。
跟踪是收集每一个事件的数据以供分析;跟踪框架一般不默认开启,因为有不小 的CPU和存储开销。
剖析(profiling)通过对目标收集采样或快照来归纳目标特征;当然,也能基于非 计时的硬件事件。
[系统级别][跟踪],块IO跟踪
统计系统资源的工具,类似于sar,集大成者;可替代vmstat/iostat/ifstat等; 可以同时观看系统的资源使用情况,如同时查看磁盘使用率和IDE控制器中断; 可以查看聚合起来的块儿设备统计信息,如基于同一文件系统的块设备吞吐; 可以直接输出为csv格式的文件,以便被office软件使用,或作图。
- dstat -c/-c -C 0,3,total
- 仅查看CPU统计
- dstat -d/-d -D total,sda
- 仅查看磁盘统计
- dstat -i/-i -I 5,10
- 仅查看中断
- dstat -l
- 查看CPU平均负载
- dstat -m
- 仅查看内存统计
- dstat -n/-n -N eth1,total
- 仅查看网络统计
- dstat -p
- 进程状态统计
- dstat -s
- swap统计
- dstat -r
- IO请求统计
- dstat -t/-T
- 显示行添加统计时间/时间戳
- dstat -y
- 查看系统统计,中断、上下文切换
- dstat –aio
- 异步IO统计
- dstat –fs
- 文件系统统计
- dstat –ipc
- IPC统计
- dstat –lock
- 文件锁统计
- dstat –socket
- 插口统计
- dstat –tcp
- TCP统计
- dstat –vm
- vm统计(hard页错误、软页错误)
- dstat –list
- 列举可以统计的项
查看内存使用情况
[系统级别][计数器],查看CPU统计信息,设备的输入输出统计信息;可用于监控 系统输入输出设备的负载。
- iostat 1
查看统计信息,1秒1次 avg-cpu: %user %nice %system %iowait %steal %idle nice, 运行在用户态nice优先级的CPU使用率 steal, 虚拟化CPU在等待Hypervisor调度执行的等待时间 Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn tps,设备每秒的事务数(IO请求) kB_read/s, 从设备读取的数据,单位k块儿/s(512-byte每块):
第一份显示的信息为自系统boot后的统计信息 - iostat -p -t -y -z -x
rrqm/s,每秒读请求数 r/s,每秒完成的读请求 rsec/s, 每秒从设备读取的sectors数 avgrq-sz,提交给设备的请求请求大小(单位sectors) avgqu-sz,请求队列平均长度 await,IO请求的平均等待时间(ms),包括排队及调度时间 svctm,平均响应时间(ms) %util,设备带宽利用率,接近100表示设备饱和
IO版本的top
- iotop -p <pid>
仅监控指定的进程
网络吞吐性能测试工具,可用于基线测试
- iperf -s -p 4000
- 以服务器身分运行,监听40000端口
- iperf -c <serv-IP> -p 4000 -t 30 -P 10
- 以客户端身分运行,并发度10,时间30s
[进程级别][跟踪],源代码级别的调试器
ab
查看网卡等PCI设备信息
调查库调用的工具
[系统级别][计数器],可查看CPU统计信息,或每个CPU使用情况
- mpstat -I <SUM/CPU/SCPU/ALL>
SUM 查看所有CPU上的平均中断统计 CPU 展示每个CPU的硬中断统计 SCPU 展示每个CPU的软中断统计 ALL 以上三个参数的总计 - mpstat -P <cpu-id/ON/ALL>
cpu-id 通过索引指定统计的CPU(0-n) ON 统计online的处理器 ALL 统计所有处理器:
iowait,等待磁盘IO请求的占比 nice,用户态nice优先级占比 steal,虚拟机CPU等待hypervisor调度的占比 gnice,nice用户的占比
todo
[系统级别][计数器],网络接口的统计,TCP/IP栈的统计,以及每个链接的信息统计
- netstat -s
- 查看协议栈统计信息
netstat -s -t 查看tcp统计 - netstat -i
- 查看接口统计信息
TX-DRP,丢包 TX-OVR,超限:
TX-DRP/TX-OVR是网络接口饱和的指示 - netstat -r
- 查看路由信息
- netstat -l
- 查看处于监听状态的插口
- netstat -p
- 显示插口归属的进程
- netstat -c
- 持续显示,每秒1次
打印网络接口吞吐统计
- nicstat -x
- 全量统计信息
- nicstat -t
- 显示TCP统计信息
- nicstat -i <itf>
- 指定网卡
Sat,饱和度 NoCP,no-can-puts,报文无法被进程(及时)处理 Defer,由于设备忙导致的延迟发送 AttF,三次握手失败 %ReTX,重传比例 Drops,连接丢弃数,包括全连接、半连接、syn队列等
[系统级别][剖析],linux系统剖析
linux任务的统计工具,可用监控特定任务的状态信息
- pidstat -p <pid/SELF/ALL>
挑选待展示的进程 - pidstat -G <comm>
- pidstat -C <comm>
展示命令名包含comm的任务信息 - pidstat -d
展示IO统计 - pidstat -I
展示CPU使用情况 - pidstat -l
展示进程名及其参数 - pidstat -R
展示实时优先级及调度策略信息 - pidstat -r
展示页错误及内存利用率信息 - pidstat -s
展示栈信息 - pidstat -t
展示对应进程的线程信息 - pidstat -u
展示cpu利用率 - pidstat -v
展示部分内核表信息 - pidstat -w
展示任务上下文切换信息
[进程级别][计数器],讲进程的内存段和使用统计一起列出
[进程级别][计数器],进程状态,显式进程的各种统计信息
[系统级别][计数器][监视],各种各样的统计,能归档历史数据
- 输入、输出简介
通过参数"-o"可指定输出文件,无参数,则默认存放在/var/log/sysstat/ 通过参数"-f"可指定输入文件,以显示存储的历史数据 - sar -P <cpu-id/ALL>/sar -u ALL
查看指定CPU统计 - sar -I <中断索引/SUM/ALL/XALL>
查看中断统计:
SUM,每秒总的中断数 ALL,前16个中断的统计 XALL,APIC支持的所有中断的统计 - sar -n <DEV/IP/TCP/IP6/FC/…/ALL>
网络统计信息:
DEV,网络设备统计 %ifutil,使用率 EDEV,网络设备错误信息统计 SOCK,插口统计信息 totsck,系统使用的插口总数 tcpsck,当前tcp插口数 ip-frag,队列中的IP分片数 tcp-tw,处于TIME_WAIT的插口数 IP,统计IPv4的网络传输信息 irec/s,每秒收到的报文总数,包含差错报文 fwddgm/s,每秒的转发报文 idel/s,每秒成功处理的报文 orq/s,本地发出的报文速率 asmrq/s,分片报文速率 asmok/s,重组成功速率 fragok/s,每秒需分片的报文数 fragcrt/s,每秒创建分片数 EIP,统计IPv4的差错信息 TCP,统计TCPv4的信息 active/s,主动模式的TCP新建速率 passive/s,被动模式的TCP新建速率 iseg/s,接收报文速率 oseg/s,发送报文速率 ETCP,TCPv4差错统计 atmptf/s,每秒新建失败次数 estres/s,链接断开速率 retrans/s,重传速率 isegerr/s,差错报文 orsts/s,发送RST报文的速率 - sar -b
查看IO速率统计:
tps,物理设备的每秒事务数 bread/s,每秒读取的块儿数(块儿512bytes) - sar -d -p
activity块儿设备的统计:
tps,设备每秒的事务数(IO请求) rd_sec/s, 每秒从设备读取的sectors数 avgrq-sz,提交给设备的请求请求大小(单位sectors) await,IO请求的平均等待时间(ms),包括排队及调度时间 svctm,平均响应时间(ms) %util,设备带宽利用率,接近100表示设备饱和 - sar -F MOUNT
显示挂载的文件系统的统计信息:
MSfsfree,总的空间空间,单位Mbytes %fsused,空间使用率 Ifree,空闲的文件节点数 %Iused,文件节点使用率 - sar -H
大页内存使用统计 - sar -m <CPU/FAN/DEVICE/FREQ/IN/TEMP/USB/ALL>
电源管理统计:
CPU,处理器信息 FAN,风扇信息 FREQ,CPU时钟频率 IN,输入电压 TEMP,设备温度信息 USB,插入的USB设备 ALL,以上信息的汇总 - sar -q
队列长度及平均负载信息:
runq-sz,运行队列长度,即等待运行的任务数 plist-sz,任务队列长度,即任务数 ldavg-1, 上1分钟的系统负载 ldavg-5, 上5分钟的系统负载 ldavg-15, 上15分钟的系统负载 blocked,等待IO的任务数 - sar -R/-r
内存信息:
frmpg/s,每秒释放的内存页数(负数表示分配内存) bugpg/s,每秒用于buffer的内存页数 campg/s,每秒缓存的内存页数 kbcommit,当前负载需要的内存总量,kilobytes - sar -S/-W
swap空间的使用统计 - sar -w
任务创建、上下文切换统计 - sar -v
内核inode、file及表统计:
file-nr,使用的文件句柄数 pty-nr,使用的伪终端数
[系统级别][跟踪][剖析],跟踪内核的内部活动和所有资源的使用情况,支持静态和 动态跟踪;另外,支持程序化剖析,基于时间的剖析,基于硬件事件的剖析等 参考《githubDB/scatter/systemtap.org》
[进程级别][跟踪],基于linux系统的系统调用跟踪
- strace -ttt -T -p pid
展示系统调用起始时间及耗时:
-ttt 结果第一栏,unix时间戳,单位s,精确度毫秒 -T 最后一栏,系统调用耗时,单位s - strace -c -p pid
统计总结系统调用活动
控制网络流量
[系统级别][跟踪],网络包跟踪
- tcpdump -A
- 以ASCII打印报文,适用于WEB报文
- tcpdump -c <num>
- 接收num个报文后,退出
- tcpdump -D
- 罗列可以抓包的接口
- tcpdump -i <intf>
- 指定监听的接口
- tcpdump -n
- 显示地址,而不是名称
- tcpdump -Q <in/out/inout>
- 指定监听方向
- tcpdump -ttt
- 打印时间差(相对于上一个报文)
- tcpdump -w <file>
- 保存抓取的报文
- tcpdump -XX
- 打印报文内容
- tcpdump host <ip/name>
- 仅关注特定主机的报文
- tcpdump ip host xx and not host yy
- 关注xx与非yy之间的ip报文
- tcpdump tcp port 80
- 仅关注80端口的报文
运行程序,并归纳系统资源用量
- sudo time -f “%<修饰符>” ls > /dev/null
定制输出内容:
r,此进程收到的插口报文数 s,发送的插口报文数 w,资源上下文切换数 x,进程退出状态 - /usr/bin/time -v <command>
有某些参数没有绑定到shell的time命令,需利用原生态的程序 显示命令执行的详细信息
[进程级别][计数器]<耗CPU>,按一个统计数据排序,显示排名高的进程
- top -p pid
- 查看指定进程的状况
- man top
检查负载平均数,确认CPU负载随时间变化规率
- uptime
17:52:08 up 18 days, 6:55, 1 user, load average: 0.93, 0.95, 0.97 当前时间 系统运行总时间 登录用户数 最近1,5,15分钟负载平均数:
超过CPU数量,代表CPU饱和 每个CPU的进程数不大于3, 那么系统性能良好 每个CPU的进程数大于5, 说明系统性能有严重问题 Linux上平均负载过重,也可能是不可中断的磁盘IO造成的
[系统级别][计数器],虚拟内存和物理内存的统计, 同时也收集进程、分业、阻塞IO、 磁盘、CPU统计等信息。
- vmstat -a -w 1
- 以1s为周期显示
r, runnable进程数 b,uninterruptiable进程 in,每秒中断数 cs, 每秒content switch数(上下文切换) wa, 等待IO的时间 st, 偷取,CPU在虚拟化环境下在其他租户上的开销:
第1行结果为自上次启动依赖的各项数据平均值 r连续大于cpu个数,表示运行缓慢;大于cpu总数4倍,则系统面临CPU短缺 si/so长期不为0, 表示内存不足 bi/bo长期不为0, 且b的数值比较大,表示io性能不好 单用户us+sy<90%,不认为是CPU受限;多用户us+sy>80%, 可能就是CPU受限 id持续为0,且sy是us的两倍及以上,则面临CPU短缺
在可控的状态下做性能基准测试,对不同的选择做比较,让我们可以在生产环境 遇到性能极限之前对性能极限做了解。
- 系统设计
- 调优
- 开发
- 容量规划
- 排错
- 市场营销
- iperf
- 网络吞吐基线
apt-get install graphviz for dot
https://github.com/jrfonseca/gprof2dot for gprof2dot.py
Linux下性能调优主要是其自带的Gprof、Sprof, 可进行函数调用次数、调用时 间、调用关系等的分析
- 编译、链接添加-pg选项
make CFLAGS=-pg LDFLAGS=-pg - 运行程序, 产生gmon分析文件/gmon.out
./a.out - 分析gmon文件,获得分析数据
gprof -b a.out gmon.out -p #调用频次、时间 gprof -b a.out gmon.out -q #调用关系 - 生成调用关系图
gprof a.out | python3 /path/to/gprof2dot.py |dot -Tpng -o outpu.png
- 编译共享库, 携带-g参数
- 执行运行共享库的主程序
export LD_PROFILE_OUTPUT=${PWD} export LD_PROFILE=xxx.so export LD_LIBRARY_PATH=. - 分析共享库
sprof xxx.so xxx.so.profile
Linux内核原生提供的性能分析工具, [系统级别][跟踪][剖析],linux性能事件; 借助此工具可打印火焰图, 快速分析系统瓶颈
- 安装
ubuntu sudo apt-get install linux-tools-common sudo apt-get install linux-tools-4.4.0-31-generic sudo apt-get install linux-generic Centos yum install perf - 火焰图工具集
git clone https://github.com/brendangregg/FlameGraph.git
- 采集数据
- 生成perf.data
perf record -F 997 -a -g -- sleep 60 以997的采集频率,对所有进程采样, 时长60s perf record -F 997 -p <pid> -g -- sleep 60 以997的采集频率,对pid进程采样, 时长60s
- 生成火焰图
perf script -i perf.data > perf.unfold ./FlameGraph/stackcollapse-perf.pl perf.unfold > perf.folded ./FlameGraph/flamegraph.pl perf.folded > perf.svg
- perf sched record
- 调度器统计信息
利用perf sched latency等查看结果 - perf stat -p <pid>
- 基于计数的CPU周期行为统计
通过CTRL-C退出后,可用查看性能计数器统计信息
- perf top -p <pid>
系统剖析工具
- perf list
- 罗列可以检查的计数器
通过perf stat -e xx,yy,zz -p <pid>观察对应的事件计数器 通过perf record -e xx,yy,zz -p <pid>观察对应的软件跟踪点
- 性能之颠
- 高性能linux服务器构建实战 I、II