ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

用sar打造Linux性能“时光机”:安装、配置与实战排查指南

用sar打造Linux性能“时光机”:安装、配置与实战排查指南 上周日凌晨2点我被值班电话叫醒。监控面板上一台线上Linux服务器的CPU飙到了100%业务接口超时告警刷了一屏。等我匆忙登录上去准备排查时一切已经恢复正常——top显示空闲free显示内存充足vmstat看起来也人畜无害整个现场干净得像是没发生过任何事。我盯着终端除了挠头什么都做不了。如果那台机器提前装好了sysstat并且打开了sar的定时采集我完全可以翻出凌晨2点前后精确到秒的CPU、负载、内存、磁盘和网络数据直接看到底是谁在作妖。sar这个工具就是Linux性能排查里少有的“时光机”。可能有人会反驳top也能看CPUvmstat也能看负载为什么要特意学sar看完这篇文章你会发现它们根本不是一回事。这篇文章会从工具安装、初始化配置、常用命令、指标解读到实际排障案例把sar的使用完整讲透适合运维工程师、SRE、后端开发以及所有经常要在Linux上排查性能问题的同学。1. 为什么最终选择了sar那次“查无证据”的教训先说说工具选择的逻辑。很多人以为性能分析就是出问题时打开top盯几秒这其实是个挺普遍的误区。真实的生产环境里性能问题是突发的、短暂的绝大多数时候你根本不在现场。等你收到告警再登录服务器CPU可能早就降下来了内存也回收完了现场被系统本身“打扫”得干干净净。这时候你面对的是一台看起来毫无异常的机器唯一能做的就是靠经验和猜。top、free、vmstat、pidstat这类实时工具本质上都是“现场工具”它们只能回答“此时此刻系统发生了什么”。可性能排查最需要的恰恰是另一类能力两个小时前这台机器经历了什么sarSystem Activity Reporter就是干这个的。它是sysstat性能监控工具包里的核心组件通过系统内置的定时任务周期性调用sadc把各项性能指标写入二进制数据文件默认存放在/var/log/sa/目录下。你随时可以用sar -f指定任意历史文件把某一天、某个时间段的CPU、内存、磁盘、网络数据完整拉出来复盘。为了更直观地理解这个差异我把自己常用的几个工具放在一起做过对比工具能看什么能否看历史适合场景topCPU、内存、负载、进程实时状态否正在出事时的现场观察free物理内存与swap使用情况否查看当前内存水位vmstatCPU、内存、IO、swap、上下文切换否短时间内手动观察趋势pidstat按进程维度统计CPU、内存、IO否定位具体是哪个进程在消耗资源sarCPU、内存、磁盘、网络、负载等全维度是事后回溯、趋势分析、容量规划表格展示的只是功能差异真正的价值差异在场景里体现。半夜的CPU尖峰、凌晨的磁盘抖动、每周固定一次的load飙高这类“查无证据”的问题是sar的主场。没有它你很难解释为什么业务方坚称“就是某个时间卡了”而监控系统却拿不出对应的明细。装了sar之后你可以直接把那个时间窗口的数据打出来让机器自己“开口说话”。另外说一句sar还特别适合做容量规划。比如你要评估服务器是否需要扩内存与其拍脑袋不如拉出最近一个季度的sar -r数据观察kbmemused的上升斜率用数据说话。这一点在后面章节会展开讲。2. 环境准备sysstat安装与定时采集的搭建过程sar属于sysstat工具包所以第一步是把整包装上。不同发行版的安装命令略有差异但都是走自带包管理器不需要编译源码过程很轻量。# RHEL / CentOS / Rocky Linux yum install sysstat -y # Ubuntu / Debian / Deepin apt install sysstat -y # Fedora dnf install sysstat -y装完之后先别急着用有两个关键开关必须确认否则sar只能看实时数据不能回看历史一是sadc数据采集任务有没有被挂进cron二是sysstat服务有没有开机自启。在RHEL系发行版里sysstat安装后会自动在/etc/cron.d/sysstat写入定时任务内容大致长这样# 每5分钟采集一次系统数据每次采样1秒 */5 * * * * root /usr/lib64/sa/sa1 1 1 # 每天23:53对当日数据进行归档 53 23 * * * root /usr/lib64/sa/sa2 -Asadc是实际的数据采集程序sa1是它的shell封装sa2负责把当天数据归档成最终的历史文件。/usr/lib64/sa/是RHEL系64位的路径如果系统是32位或者某些发行版路径不同通常在/usr/lib/sa/下可以用which sa1确认一下。服务方面RHEL系建议执行一次自启设置systemctl enable --now sysstat systemctl status sysstatDebian系有个很容易被忽略的细节安装sysstat的过程中会弹一个交互式配置界面问你是否启用历史数据采集。如果当时选了“否”即使安装成功sar也不会记录任何历史数据。遇到这种情况不需要重装执行一下重新配置就行dpkg-reconfigure sysstat选“是”然后service sysstat restart或systemctl restart sysstat同时检查一下/etc/cron.d/sysstat是否存在。Debian系在/etc/default/sysstat里还有一个ENABLEDtrue的开关建议确认它没有被改成false。HISTORY参数也是我习惯第一时间改的。在/etc/sysconfig/sysstat文件里有一个HISTORY字段默认值可能是7表示只保留7天的历史数据文件。对于生产服务器7天实在太短很多偶发问题隔了一周才被业务方反馈等你再去翻数据文件早就被清理了。我通常改成30甚至60# 保留30天的历史数据 HISTORY30这里有个小坑提醒一下修改HISTORY只影响之后生成的文件保留策略之前已经存在的旧文件不会自动补回保留天数。所以如果你想把历史留下来最好在服务器上线时就设置好不要等出问题了才想起来。容器里就没有Systemd了sysstat在容器环境中默认不会自动采集。我一般会在容器启动命令里手动挂一个后台采集进程或者写进业务进程之前的启动脚本用sadc直接跑nohup sadc -D 60 /var/log/sa/sa$(date %d) 这个命令表示每60秒采集一次数据并追加到当天的sa文件。效果和cron定时任务基本一样适合没有定时任务系统的环境。3. 核心指令拆解CPU、内存、磁盘、网络四维排查sar的命令格式非常规整sar [选项] [间隔时间] [次数]后面还可以接-f指定历史数据文件、-s和-e限定时间窗口。先记住这个骨架剩下的就是往里面填你关心的维度。3.1 CPU维度sar -u看整体sar -q看负载sar -P ALL看单核先说最常用的-u查看CPU整体使用率。执行sar -u 1 3表示每秒采样一次连续采样3次。输入看起来是这样Linux 5.10.0-60.18.0.el7.x86_64 (web01) 2025年11月17日 _x86_64_ (4 CPU) 14:00:01 CPU %user %nice %system %iowait %steal %idle 14:00:02 all 12.30 0.00 3.20 0.50 0.00 84.00 14:00:03 all 88.71 0.00 6.94 0.00 0.00 4.35 14:00:04 all 31.17 0.00 5.90 0.00 0.00 62.93字段并不复杂%user是用户态占用比例应用层代码跑得越多它越高%system是内核态占用文件系统、网络协议栈、系统调用这类工作它负责%iowait是CPU在等待磁盘IO完成的时间占比%steal要特别关注它表示虚拟机被宿主机抢占的CPU时间份额云服务器上如果%steal长期超过10%说明邻居在挤占宿主机资源这属于服务商侧的物理资源超卖问题你改自己代码是没用的。%iowait高是个很迷惑人的指标。不要看到它高就立刻断定磁盘坏掉了它只代表“CPU闲着但有些进程被卡在IO上”如果此时CPU本身还有大量空闲系统可能仍然在正常工作。要真正判断磁盘是否瓶颈需要配合磁盘维度的sar -d来看IO队列深度。-q看的是系统负载和任务队列对应load average14:00:01 runq-sz plist-sz ldavg-1 ldavg-5 ldavg-15 blocked 14:00:02 3 402 15.20 12.30 18.20 2runq-sz是当前处于运行等待态的进程数plist-sz是系统总的进程和线程数ldavg分别对应1分钟、5分钟、15分钟的平均负载blocked是阻塞在IO上的进程数。这个指标的用处在于拆解“load高”的真相。如果你看到ldavg很高但runq-sz很低说明大部分负载并不是真正的CPU排队背后另有原因可能是大量的D状态进程卡在IO或锁等待上。如果一个12核的机器cpu quota不服——好吧关键还是看分布。-P ALL用来逐核观察sar -P ALL 1 3。排查CPU尖峰的时候我会先看这个如果发现个别核心打满、其他核心很闲就要怀疑是不是单线程瓶颈或者锁竞争如果所有核心同时飙高更可能是流量洪峰或者GC这类全局事件。3.2 内存维度sar -r看水位sar -B看换页sar -S看Swap空间内存排查我最依赖三个指令。sar -r给的是最基础的内存水位14:00:01 kbmemfree kbavail kbmemused %memused kbbuffers kbcached 14:00:02 102400 102587 38334500 70.35 1024000 8000000kbmemused和%memused是一眼就能看到的内存占用但要注意kbbuffers和kbcached是内核的页缓存这部分内存虽然“已用”但遇到压力时内核可以随时回收利用所以我更倾向于看kbavail它才是真正“还有多少可用”的指标。sar -B看的是内存换页情况重点看两个字段pgpgin/s和pgpgout/s即每秒从磁盘换入和换出的内存页数量以及pswpin/s、pswpout/s即每秒换入换出的swap页面数。如果swap换入换出频繁说明物理内存已经吃紧系统正在用磁盘当内存用这个状态会带来严重的性能下降。此时结合sar -r确认物理内存是否打满再结合top找到吃内存的大户。sar -S输出的是swap分区本身的状态pswpin/s可能比较小主要看pswpout/s和%swused的变化趋势。要注意一个常见误判swap的使用率为0并不代表物理内存富裕只是说明当前数据都还能放进内存还需要结合页交换的幅度判断是否接近临界。内存这类问题特别适合用历史趋势来看。比如我排查过一次内存缓慢增长光看某个时间点没什么异常但拉出连续两周的sar -r数据能明显看到kbmemused每天上涨1%这种缓坡就是典型的内存泄漏特征时间越长越清楚。3.3 磁盘IO维度sar -b看汇总sar -d看单盘sar -b输出的是整机IO汇总字段有tps、rtps、wtps、bread/s、bwrtn/s。它适合快速确认磁盘活动量级但要说瓶颈还得落到单块盘。sar -d是我看磁盘用得最多的命令14:00:01 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util 14:00:02 sda 500 0 300 512 12.0 158.0 2.0 98.6重点指标拆开说await是IO请求从发出到完成平均等待的时间包括在队列里排队的时间和磁盘真正处理的时间单位是毫秒。svctm是磁盘处理单个请求的实际服务时间老版本sar里有这个字段新版本因为很多存储硬件并发处理能力很强这个值容易失真所以我一般不怎么依赖它。avgrq-sz代表平均每个IO请求的大小数值小说明以小文件读写为主这类IO更消耗IOPS。avgqu-sz是平均IO请求队列长度这是判断磁盘是否饱和的重要信号。%util是设备繁忙百分比接近100%意味着磁盘几乎一直在干活没有喘息窗口。这里要给一个很实在的提醒%util达到100%不一定就是磁盘瓶颈。在SSD和云盘时代很多设备的%util长期漂在90%以上但实测的await也很低说明这些盘有不错的并发能力和硬件队列处在“忙但没堵住”的状态。真正要关注的是avgqu-sz和await两个指标同时起飞一般await持续超过几十毫秒业务上就明显能感受到刷页和操作卡顿。3.4 网络维度sar -n DEV与sar -n TCP/ETCP网络排查先看接口流量sar -n DEV 1 3输出包括rxpck/s每秒收包、txpck/s每秒发包、rxkB/s、txkB/s和%ifutil等。%ifutil是接口利用率但要注意它是基于接口速率计算的如果网卡是万兆但你业务流量才几百兆利用率会非常低需要先确认网卡带宽上限再判断是否接近饱和。sar -n TCP看的是TCP层连接活动active/s是主动发起的连接数passive/s是服务端接受的连接数iseg/s和oseg/s是收发报文段数。配合sar -n ETCP看重传率retrans/s如果某个时段重传数明显上升说明网络上出现了丢包或者链路质量恶化链路本身是好的还是烫的从这就能看出迹象。3.5 历史数据读取与时间窗口控制搞明白了要盯哪些指标之后接下来这步很重要让sar去读历史文件。默认情况下sar执行后会读取当天当前时段的文件但你可以用-f指定某天的历史文件用-s和-e限定时间范围# 查看本月15号整天的CPU记录 sar -u -f /var/log/sa/sa15 # 查看15号早上8点到中午12点的内存记录 sar -r -f /var/log/sa/sa15 -s 08:00:00 -e 12:00:00 # 把当天所有维度的数据全部输出 sar -A注意时间参数必须写成HH:MM:SS格式08:00:00这样漏了秒数不会报错但解析结果很可能不是你想要的。还有一个小细节是文件命名规则默认是sa加两位日期某月5号就是sa0515号就是sa15跨月的时候记得别只看日期要结合目录里实际文件来确认。4. 实战复盘三个让我对sar改观的真实排查过程理论知识说再多不如一次实操来得有记忆点。我挑三个自己印象最深的排查经历讲讲当时是怎么从一个模糊的告警一步步通过sar定位到具体原因的。4.1 场景一load高达80CPU却闲得发呆有一台业务服务器某天午后监控显示load average冲到了80但业务方反馈服务并没有完全不可用只是响应变慢。我登录上去用top一看CPU整体idle还有70%多完全不符合load这么高的表现。当时我第一反应是怀疑top展示的idle没算对顺手拉了一下sar -q15:32:01 runq-sz plist-sz ldavg-1 ldavg-5 ldavg-15 15:32:02 12 2800 80.2 45.3 30.1这里有信息runq-sz只有12但load是80说明并不是CPU运行队列积压导致的。plist-sz高达2800系统里进程线程数量异常多。于是我又补了一个pidstat确认发现进程数量多是因为有个业务进程开启了大量线程有些线程卡在D状态不可中断睡眠等待网络IO返回。最后定位到根因某个模块依赖的远程存储服务出现了慢请求客户端重试逻辑又不够完善导致同一类线程大量堆积进程数暴涨把load average顶了上去。CPU本身并没有被打满问题是卡在外部依赖的慢IO上。没有sar -q的历史数据对比我很难在告警消失后解释清楚当时load从哪来。4.2 场景二每天凌晨3点固定CPU尖峰另一个服务更诡异每天凌晨3点左右CPU都会100%持续大概10分钟白天完全正常。业务方确认凌晨3点没有定时任务流量也很低所有人都在疑惑是谁在“偷跑”。第一次遇到时我刚好错过了现场于是第二天提前把sar -u的实时采样挂上凌晨3点那次尖峰被完整记录下来了03:00:01 CPU %user %system %iowait 03:00:02 all 85.20 5.10 0.00 03:00:03 all 91.47 3.32 0.00%user高得离谱%system不高于是判断是某个应用进程在跑计算密集的任务而不是内核或IO层面的问题。接着用sar -P ALL看单核分布发现4个核里只有1个核被打满其他核还比较空闲这种“单核尖峰”在Java服务里非常典型多半是JVM在做Full GC。顺着这个思路让开发团队查了GC日志果然每天凌晨3点定时触发了大批量数据处理任务产生了大量对象并引发Full GCSTWStop The World导致CPU被单个GC线程吃满业务在这段时间出现明显停顿。修复方案很简单把数据处理任务从凌晨挪到业务低谷但避开GC高峰时段同时调整堆内存参数。这个过程你可以看到sar负责缩小问题范围GC日志负责确认根因两者配合排查效率完全不一样。4.3 场景三磁盘IO延迟莫名升高一个数据库实例最近频繁被业务方投诉慢查询但数据库本身的CPU和内存监控都正常连接数也没问题看起来像是数据库层面“没什么毛病”。我拉出业务高峰期两小时的sar -d某个设备的数据让我立刻警觉起来15:00:01 DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await %util 15:00:02 vdb 850 0 2600 16 14.2 176.0 99.8await到176毫秒avgqu-sz超过14%util接近100%这不是健康的磁盘状态。再回头看sar -b的聚合数据整机tps在高峰期冲到了几千读写的请求块大小并不大整体呈现的是典型的高IOPS吞吐压力云盘底层IOPS配额达到上限请求全在排队。这个结论直接改变了处理方向不是慢SQL的问题而是底层云盘IO容量已经跑满属于存储规划问题。随后我们联系云服务商确认了该云盘的IOPS上限与当前峰值量化数值确认确实是配额瓶颈采取扩容与读流量拆分后等待时间立刻降回个位数。想通过调SQL优化来解决大概率是徒劳的因为瓶颈根本不在数据库引擎层而在它脚下的存储设备。这三个案例里sar不像top那样告诉你“当前谁在跑”它更像一份持续记录的体检档案先告诉我哪天哪个部位不舒服再让我根据记录找到可能的原因最后才去用其他工具做定向确认。这种“先缩小范围再精确定位”的排查思路比靠直觉瞎猜高效很多。5. 数据文件与进阶玩法从sa文件到自动化报告看到这里你应该对sar的常用命令有了基本认识。但只有掌握了它底层的数据文件机制和一些进阶用法才算真正“彻底搞定”。5.1 sa文件的存储与保留历史数据以二进制格式存储在/var/log/sa/RHEL系或/var/log/sysstat/Debian系下文件名是sa加两位数字如sa17表示17号的数据。为什么是二进制因为要考虑性能每几秒就要追加一行全维度指标如果用文本格式磁盘写入量会大得多而且回溯读取效率也低。用二进制的另一面是不方便直接用cat查看必须通过sar -f sa17这类命令来解析。文件占用空间其实不大每天大约几MB量级保留30天的成本完全可以接受。但要注意清理策略如果你自己设了HISTORY系统会在归档时自动清理过期的历史文件如果是容器这种没有完整cron机制的环境需要自己加一条find /var/log/sa/ -name sa* -mtime 30 -delete定时清理否则文件会无限堆积。5.2 手动采集与临时加密采样默认每5分钟一次的数据粒度对大部分历史回溯都够用。但遇到正在进行的疑难故障5分钟间隔太粗了你可能需要1秒级别的精细数据。这时候不需要改全局配置直接在前台执行一次自定义采样就行# 每秒采样一次持续60秒 sar -u -o /tmp/capture.sa 1 60 # 采样完成后用文件回放不会遗漏 sar -u -f /tmp/capture.sa-o参数会把采样结果写入指定文件之后可以随时用-f读取。这个做法在“我预感到接下来可能要出事想完整记录现场”的场景下特别管用。需要注意的是如果使用-o的同时没有指定具体选项sar会把所有可用指标都存进去文件会稍大一些但排障时信息更全。5.3 用sadf把二进制数据转成可分析格式sadf是sysstat自带的格式化输出工具它可以把sar的二进制数据转成CSV、XML、JSON等格式方便喂给脚本或Excel做二次加工。这个功能我经常用于批量统计# 输出为分号分隔的CSV格式行列含义清晰 sadf -d /var/log/sa/sa17 -- -u # 配合awk统计某天的平均CPU使用率 sadf -d /var/log/sa/sa17 -- -u | awk -F; NR2 {sum$7; cnt} END {printf avg CPU idle: %.2f\n, sum/cnt}字段顺序在不同版本间会有差异建议先不接awk直接跑一次sadf -d看下表头确认目标字段在第几列。我第一次用的时候没看表头直接把第8列当成CPU idle来算统计出来的趋势完全对不上白白浪费了不少时间。还有一种更省事的玩法直接让sar输出时排除掉大部分字段只留关心的数据列比如只看内存和Loadsar -r -q -f /var/log/sa/sa17一次输出两张报表数据量小阅读也轻松。5.4 进阶组合拳定时任务里临时加密采样如果某段时间需要更细粒度的性能数据来做专项分析又不想重启sysstat服务可以在crontab里临时加一条高频采样任务分析完再删掉# 在工作日晚高峰每30秒采样一次持续1小时 */1 20-21 * * 1-5 root /usr/lib64/sa/sa1 2 30这条命令的意思是让sa1以30秒间隔采样2次但因为cron粒度的关系实际执行频次还是受cron调度周期影响。更稳妥的做法是把加密采样的sa1任务直接加到系统的cron里或者借助watch加-o参数的临时方案。重点想提醒的是千万不要在生产长期保持每秒高频采样文件膨胀速度会非常快磁盘占用飙升不说sar读取时也会变慢。5.5 sar和Prometheus是替代关系还是互补关系被问过很多次“我们上了Prometheus加node_exporter是不是就不用装sar了”。我的观点很明确它们不是替代关系而是不同定位的工具组合。Prometheus解决的是“当前正在发生什么”和“异常时能否推送告警”它的数据按分钟级拉取适合实时监控和告警通知。sar解决的是“某一天某个秒级时间点发生了什么”它的秒级历史回溯能力非常适合事后分析。比如Prometheus通过node_load1告诉你“昨晚3点负载异常高”要细看到具体是CPU耗时、IO等待还是线程堆积还是得靠sar -f去翻历史明细。生产环境的推荐组合是Prometheus负责系统级实时告警和趋势sar负责定位历史问题和复盘细节。两个都装才能保证故障时手里有足够的数据可以查。写在最后的一点真实体会用过这么长时间sar我最大的感受是性能问题不可怕最怕的是没有数据你只能靠记忆和猜测复盘。生产服务器上的很多诡异抖动是偶发且短暂的错过现场就是错过一切。现在我的服务器初始化清单里永远有一条“安装sysstat并打开历史采集”哪怕业务还没上线、流量还很低这个习惯也从来没省过。之所以把这个工具单独拿出来写一篇文章是因为它值得。排查负载飙升、内存泄漏、磁盘饱和、网络丢包时它都能帮你快速缩小范围。掌握了它你就等于给每个Linux环境装了一台“行车记录仪”就算当时没在现场事后也能把整段路况回放出来。真希望那晚被值班电话吵醒时我已经提前把所有机器都装好了它。
返回列表