Linux性能优化实战
倪朋飞
微软资深工程师,Kubernetes项目维护者
立即订阅
23395 人已学习
课程目录
已完结 64 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (2讲)
开篇词 | 别再让Linux性能问题成为你的绊脚石
免费
01 | 如何学习Linux性能优化?
CPU 性能篇 (13讲)
02 | 基础篇:到底应该怎么理解“平均负载”?
03 | 基础篇:经常说的 CPU 上下文切换是什么意思?(上)
04 | 基础篇:经常说的 CPU 上下文切换是什么意思?(下)
05 | 基础篇:某个应用的CPU使用率居然达到100%,我该怎么办?
06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
07 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(上)
08 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(下)
09 | 基础篇:怎么理解Linux软中断?
10 | 案例篇:系统的软中断CPU使用率升高,我该怎么办?
11 | 套路篇:如何迅速分析出系统CPU的瓶颈在哪里?
12 | 套路篇:CPU 性能优化的几个思路
13 | 答疑(一):无法模拟出 RES 中断的问题,怎么办?
14 | 答疑(二):如何用perf工具分析Java程序?
内存性能篇 (8讲)
15 | 基础篇:Linux内存是怎么工作的?
16 | 基础篇:怎么理解内存中的Buffer和Cache?
17 | 案例篇:如何利用系统缓存优化程序的运行效率?
18 | 案例篇:内存泄漏了,我该如何定位和处理?
19 | 案例篇:为什么系统的Swap变高了(上)
20 | 案例篇:为什么系统的Swap变高了?(下)
21 | 套路篇:如何“快准狠”找到系统内存的问题?
22 | 答疑(三):文件系统与磁盘的区别是什么?
I/O 性能篇 (10讲)
23 | 基础篇:Linux 文件系统是怎么工作的?
24 | 基础篇:Linux 磁盘I/O是怎么工作的(上)
25 | 基础篇:Linux 磁盘I/O是怎么工作的(下)
26 | 案例篇:如何找出狂打日志的“内鬼”?
27 | 案例篇:为什么我的磁盘I/O延迟很高?
28 | 案例篇:一个SQL查询要15秒,这是怎么回事?
29 | 案例篇:Redis响应严重延迟,如何解决?
30 | 套路篇:如何迅速分析出系统I/O的瓶颈在哪里?
31 | 套路篇:磁盘 I/O 性能优化的几个思路
32 | 答疑(四):阻塞、非阻塞 I/O 与同步、异步 I/O 的区别和联系
网络性能篇 (13讲)
33 | 关于 Linux 网络,你必须知道这些(上)
34 | 关于 Linux 网络,你必须知道这些(下)
35 | 基础篇:C10K 和 C1000K 回顾
36 | 套路篇:怎么评估系统的网络性能?
37 | 案例篇:DNS 解析时快时慢,我该怎么办?
38 | 案例篇:怎么使用 tcpdump 和 Wireshark 分析网络流量?
39 | 案例篇:怎么缓解 DDoS 攻击带来的性能下降问题?
40 | 案例篇:网络请求延迟变大了,我该怎么办?
41 | 案例篇:如何优化 NAT 性能?(上)
42 | 案例篇:如何优化 NAT 性能?(下)
43 | 套路篇:网络性能优化的几个思路(上)
44 | 套路篇:网络性能优化的几个思路(下)
45 | 答疑(五):网络收发过程中,缓冲区位置在哪里?
综合实战篇 (13讲)
46 | 案例篇:为什么应用容器化后,启动慢了很多?
47 | 案例篇:服务器总是时不时丢包,我该怎么办?(上)
48 | 案例篇:服务器总是时不时丢包,我该怎么办?(下)
49 | 案例篇:内核线程 CPU 利用率太高,我该怎么办?
50 | 案例篇:动态追踪怎么用?(上)
51 | 案例篇:动态追踪怎么用?(下)
52 | 案例篇:服务吞吐量下降很厉害,怎么分析?
53 | 套路篇:系统监控的综合思路
54 | 套路篇:应用监控的一般思路
55 | 套路篇:分析性能问题的一般步骤
56 | 套路篇:优化性能问题的一般方法
57 | 套路篇:Linux 性能工具速查
58 | 答疑(六):容器冷启动如何性能分析?
加餐篇 (4讲)
加餐(一) | 书单推荐:性能优化和Linux 系统原理
加餐(二) | 书单推荐:网络原理和 Linux 内核实现
用户故事 | “半路出家 ”,也要顺利拿下性能优化!
用户故事 | 运维和开发工程师们怎么说?
结束语 (1讲)
结束语 | 愿你攻克性能难关
Linux性能优化实战
登录|注册

08 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(下)

倪朋飞 2018-12-07
你好,我是倪朋飞。
上一节,我给你讲了 Linux 进程状态的含义,以及不可中断进程和僵尸进程产生的原因,我们先来简单复习下。
使用 ps 或者 top 可以查看进程的状态,这些状态包括运行、空闲、不可中断睡眠、可中断睡眠、僵尸以及暂停等。其中,我们重点学习了不可中断状态和僵尸进程:
不可中断状态,一般表示进程正在跟硬件交互,为了保护进程数据与硬件一致,系统不允许其他进程或中断打断该进程。
僵尸进程表示进程已经退出,但它的父进程没有回收该进程所占用的资源。
上一节的最后,我用一个案例展示了处于这两种状态的进程。通过分析 top 命令的输出,我们发现了两个问题:
第一,iowait 太高了,导致系统平均负载升高,并且已经达到了系统 CPU 的个数。
第二,僵尸进程在不断增多,看起来是应用程序没有正确清理子进程的资源。
相信你一定认真思考过这两个问题,那么,真相到底是什么呢?接下来,我们一起顺着这两个问题继续分析,找出根源。
首先,请你打开一个终端,登录到上次的机器中。然后执行下面的命令,重新运行这个案例:
# 先删除上次启动的案例
$ docker rm -f app
# 重新运行案例
$ docker run --privileged --name=app -itd feisky/app:iowait

iowait 分析

我们先来看一下 iowait 升高的问题。
我相信,一提到 iowait 升高,你首先会想要查询系统的 I/O 情况。我一般也是这种思路,那么什么工具可以查询系统的 I/O 情况呢?
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Linux性能优化实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(79)

  • Zecho
    提一个建议,案例的讲解过于简单,与预期有些差距,很多时候我们实际遇到的要比这个复杂,这会带来不是简单的几个命令就可以,特别需要更深入的工具,比如brendan中火焰图,perf-tools,或者systemtab等等;希望能找些实际的案例,谢谢。

    作者回复: 嗯嗯,实际上这里的案例是我故意设计的比较简单,这样初学者可以把重点放到理解当前讲的原理和指标上,而不是看着一堆的新工具和内核函数而感到害怕。当然了,火焰图、perf-tools、systemtap这些工具以后也会讲到,只是还是让我们先把基础的东西铺垫好。

    如果你已经对这些比较熟悉了,推荐去把这些思路应用到实际的系统中去分析,然后在这里跟大家分享你的所得。我相信,你有可能会发现不同的理解,甚至是更好的分析思路。

    2018-12-07
    36
  • 王涛
    d8打卡。看完这部分,作为一名运维人员就尴尬了,当开发跟你说机器性能有问题时,这个问题就变成了甩锅问题。开发说代码没问题,你又看不懂开发的代码。。。

    作者回复: 找出进程就可以甩锅了😊

    从磁盘IO的角度来说,其实很容易找出那些进程在消耗IO资源。因为这里侧重的是CPU使用的分析,所以IO讲的不是特别深入。后续的IO部分还会有更细致的拆解。

    2018-12-07
    19
  • 每天晒白牙
    【D8打卡】
    今天主要学习的是系统中出现了大量不可中断进程和僵尸进程的处理方法
    现象:
    ①iowait太高,导致平均负载升高,并且达到了系统CPU的个数
    ②僵尸进程不断增多
    分析过程:
    1.先分析iowait升高的原因
    一般iowait升高,可能的原因是i/o问题
    ①用dstat 命令同时查看cpu和i/o对比情况(如 dstat 1 10 间隔1秒输出10组数据),通过结果可以发现iowait升高时,磁盘读请求(read)升高
    所以推断iowait升高是磁盘读导致
    ②定位磁盘读的进程,使用top命令查看处于不可中断状态(D)的进程PID
    ③查看对应进程的磁盘读写情况,使用pidstat命令,加上-d参数,可以看到i/o使用情况(如 pidstat -d -p <pid> 1 3),发现处于不可中断状态的进程都没有进行磁盘读写
    ④继续使用pidstat命令,但是去掉进程号,查看所有进程的i/o情况(pidstat -d 1 20),可以定位到进行磁盘读写的进程。我们知道进程访问磁盘,需要使用系统调用,
    下面的重点就是找到该进程的系统调用
    ⑤使用strace查看进程的系统调用 strace -p <pid>
    发现报了 strace:attach :ptrace(PTRACE_SIZE,6028):Operation not peritted,说没有权限,我是使用的root权限,所以这个时候就要查看进程的状态是否正常
    ⑥ps aux | grep <pid> 发现进程处于Z状态,已经变成了僵尸进程,所以不能进行系统调用分析了
    ⑦既然top和pidstat都不能找出问题,使用基于事件记录的动态追踪工具
    如果是centos系统,可以使用下面的方法
    在容器外面把分析记录保存,到容器里面查看结果
    操作:
    (1)在centos系统上运行 perf record -g ,执行一会儿按ctrl+c停止
    (2)把生成的perf.data(通常文件生成在命令执行的当前目录下,当然可以通过find | grep perf.data或 find / -name perf.data查看路径)文件拷贝到容器里面分析:
    docker cp perf.data app:/tpm
    docker exec -i -t app bash
    cd /tmp/
    apt-get update && apt-get install -y linux-perf linux-tools procps
    perf_4.9 report
    然后观察调用栈信息,检查是否有磁盘读操作,这个案例是定位到了进行磁盘的直接读,当然也可以查看源码进行验证。因为我的centos系统用老师的 iowait镜像iowait升高不明显,所以使用的是iowait-new2镜像,可以得到想要的结果,但是这个镜像把我的系统能搞崩溃,所以我只能执行到cd /tmp/这步,下面那部就执行不下去了。但是整个分析过程还是理解了。

    2.僵尸进程
    僵尸进程出现的原因是父进程没有回收子进程的资源出现的。解决办法是找到父进程,在父进程中处理,使用pstree查父进程,然后查看父进程的源码检查wait()/waitpid()的调用或SIGCHLD信号处理函数的注册
    2018-12-07
    19
  • walker
    有时候直接杀死僵尸进程的时候会导致服务不可用,或是崩溃。在线上运行的服务出现僵尸进程时,怎样处理比较好呢?
    2018-12-07
    8
  • ninuxer
    打卡day9
    在用perf展开的分析详情中,有个children和self都90%多的swapper进程,如果我看到这个,我肯定会先去围绕这个进程展开,而会忽略占用才0.6%得app进程,关于这个情况,是我理解上有什么偏差么?
    2018-12-07
    8
  • 柯锦玲(侠客行)
    dock镜像等资料在哪里下载?
    2018-12-07
    7
  • 白华
    今天进行实验看来还是不会成功的,上次在你的docker hub仓库中看到了iowait镜像,试了最新的几个,在centos7虚拟机中还是不行
    2018-12-07
    5
  • 姜小鱼
    老师:iowait%生高并不能得出存在io性能的结论,还要继续看io量(dstat)和io并发等情况.那么这个io量到底达到多少才能说明存在性能瓶颈?有一个量化指标吗?期待回复,谢谢

    作者回复: IO部分会讲的

    2018-12-07
    4
  • Andy Huang
    不大理解iowait的线程并没有使用CPU的,也不在就绪队列。为什么却要算作是CPU的负载
    2019-04-03
    1
    2
  • 我来也
    [D8打卡]
    今天又学了两个乖, dstat可以同时看cpu和io. (上篇文章安装后只看了下效果,没想到这一层).strace可以追踪系统调用.
    虽然我之前也写过linux c程序,但是看到sys_read/new_sync_read/blkdev_direct_IO确实不知道是正在对磁盘进行直接读, 即使看了代码 也不知道 O_DIRECT 这个参数就是直接读.
    还是功力太浅,线索摆在前面也抓不住,哈哈😁.
    ----
    有些同学问"服务出现僵尸进程时,怎样处理".
    其实我也不知道怎么处理,但是我把那个父进程杀掉, 僵尸进程就几乎没有了.
    上一篇文章中,老师也提到过[通常,僵尸进程持续的时间都比较短,在父进程回收它的资源后就会消亡;或者在父进程退出后,由 init 进程回收后也会消亡]

    作者回复: 嗯嗯 可以再思考一点,比如假如父进程已经是init了又该怎么办?注意init进程是不会退出的

    2018-12-07
    2
  • 进击的菜鸟运维
    后面那两个镜像,我不知道是不是我系统的问题,我运行iowait直接飚满了,系统直接卡死。
    2018-12-07
    2
  • 风一样的男子
    老师,我在阿里云上购买的服务器Ubuntu18.04.1,运行命令docker run --privileged --name=app -itd feisky/app:iowait后,app就退出了,是什么原因呢?

    作者回复: 执行 docker logs app看看什么错误?

    2019-01-28
    1
    1
  • 发条橙子 。
    老师 , 我这边使用 stress 来模拟 io 的请求 , 发现 stress 的进程时而 D 时而 R 。 但是用 pidstat 、 iostat 以及 dstat 都没有看到对 磁盘有 读数据请求 和 写数据请求 。 所以这个是 stress 工具本身的问题么 ??

    作者回复: 可能跟stress的选项有关,你的命令是什么?

    2018-12-16
    1
  • 赵强强
    倪老师.公司一个服务调用量很大,top命令输出显示php-fpm worker进程cpu使用率很高,但是pidstat输出确找不到该进程,进程确实一直存在的,是什么原因呢

    作者回复: 试试分析下线程

    2018-12-08
    1
  • 路过
    听课程,还会需要有点编程的功底,否则这个问题排查起来只能粗暴简单处理了。把锅丢给开发了。:)

    作者回复: 嗯嗯 了解一些编程的基本功很有帮助,特别是复杂问题的最后很可能要去分析函数调用栈等,更需要一定的编程功底。

    2018-12-07
    1
  • 破晓
    老师想问下关于cpu使用率这块的概念,sytem的cpu使用率,包不包含iowait的?他们之间是什么关系?

    作者回复: 不包括,这是两个不同的指标

    2018-12-07
    1
  • 帆帆帆帆帆帆帆帆
    @jeff,数据库一般都有自己的数据缓冲池bufferpool,在合适的时间,数据库会从磁盘读入数据到bufferpool,或者从bufferpool写出数据到磁盘。在这种情况下,再使用文件系统缓存,反而不会有性能的提升,而且数据库写出数据到磁盘的时候,必须写到了磁盘才算真的完成了数据的持久化。

    作者回复: 嗯嗯,谢谢分享

    2018-12-07
    1
  • hsggj
    老师,请问一下,perf除了可以检测C++之外,其他的代码如java,php的问题可以检测吗?

    作者回复: 可以的,我们案例里面已经有一个PHP的示例,我还会在答疑中介绍Java的使用方法。

    2018-12-07
    1
  • york
    案例中的app源码,怎么能看得到?

    作者回复: 点击文中的链接进入github

    2018-12-07
    1
  • 路过
    用ubuntu 做实验很顺利。请问老师,曾经发生僵尸进程的父进程是1,服务器又不方便重启,如何清理这样的僵尸进程?谢谢老师!
    2018-12-07
    1
收起评论
79
返回
顶部