zoukankan      html  css  js  c++  java
  • cpu load过高问题排查

    load average的概念

    top命令中load average显示的是最近1分钟、5分钟和15分钟的系统平均负载。

    系统平均负载被定义为在特定时间间隔内运行队列中(在CPU上运行或者等待运行多少进程)的平均进程数。如果一个进程满足以下条件则其就会位于运行队列中:

    • 它没有在等待I/O操作的结果
    • 它没有主动进入等待状态(也就是没有调用’wait’)
    • 没有被停止(例如:等待终止)

    在Linux中,进程分为三种状态,一种是阻塞的进程blocked process,一种是可运行的进程runnable process,另外就是正在运行的进程running process。

    进程可运行状态时,它处在一个运行队列run queue中,与其他可运行进程争夺CPU时间。 系统的load是指正在运行和准备好运行的进程的总数。比如现在系统有2个正在运行的进程,3个可运行进程,那么系统的load就是5。load average就是一定时间内的load数量。

    一般来说只要每个CPU的当前活动进程数不大于3那么系统的性能就是良好的,如果每个CPU的任务数大于5,那么就表示这台机器的性能有严重问题。

    CPU使用率高并不总是意味着CPU工作繁忙,它有可能是正在等待其他子系统。在进行性能分析时,将所有子系统当做一个整体来看是非常重要的,因为在子系统中可能会出现瀑布效应。衡量CPU 系统负载的指标是load,load 就是对计算机系统能够承担的多少负载的度量,简单的说是进程队列的长度。简单的例子比如食堂有五个窗口,当有小于五个学生来打饭,五个窗口都能及时处理,但是当学生个数超过5个,必然会出现等待的学生。请求大于当前的处理能力,会出现等待,引起load升高。
    Load Average 就是一段时间(1min,5min,15min)内平均Load。平均负载的最佳值是1,这意味着每个进程都可以在一个完整的CPU 周期内完成。

    cpu load高的排查思路

    1. 首先排查哪些进程cpu占用率高。 通过命令 ps ux

    image

    2.  查看对应java进程的每个线程的CPU占用率。通过命令:ps -Lp 15047  cu

    image

    3.  追踪线程内部,查看load过高原因。通过命令:jstack 15047。

    或者打印线程 jstack pidof java > stack.out

    查找到对应的threadid, 再反查代码。

    一般经验

    cpu load的飙升,一方面可能和full gc的次数增大有关,一方面可能和死循环有关系

    数据库系统load高的一般原因

        1 业务并发调用全表扫描/带有order by 排序的SQL语句.
        2 SQL语句没有合适索引/执行计划出错/update/delete where扫描全表,阻塞其他访问相同表的sql执行.
        3 存在秒杀类似的业务比如聚划算10点开团或者双十一秒杀,瞬时海量访问给数据库带来冲击。
        4 数据库做逻辑备份(需要全表扫描)或者多实例的压缩备份(压缩时需要大量的cpu计算,会导致系统服务器load飙高)
        5 磁盘写入方式改变 比如有writeback 变为 write through
           RAID卡都有写cache(Battery Backed Write Cache),写cache对IO性能的提升非常明显,因为掉电会丢失数据,所以必须由电池提供支持。
           电池会定期充放电,一般为90天左右,当发现电量低于某个阀值时,会将写cache策略从writeback置为writethrough,相当于写cache会失效,这时如果系统有大量的IO操作,可能会明显感觉到IO响应速度变慢,cpu 队列堆积系统load 飙高。

    判别和处理load高问题

    一般根据cpu数量去判断,也就是Load平均要小于CPU的数量,负载的正常值在不同的系统中有着很大的差别。在单核处理器的工作站中,1或2都是可以接受的。多核处理器的服务器(比如24核)上,load 会到达20 ,甚至更高。

    a) 数据库层面
         1 top -u mysql -c 检查当前占用cpu资源最多的进程命令。-c 是为了显示出进程对应的执行命令语句,方便查看是什么操作导致系统load飙高。
         2 根据不同的情况获取pid 或者MySQL的端口号
         3 如果是MySQL 数据库服务导致laod 飙高,则可以使用如下命令
             show processlist;
             SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND <> 'sleep' AND TIME>100;
            或
             orzdba 工具检查逻辑读/thread active的值。用法orzdba --help
             orztop 工具检查当前正在执行的慢sql,用法orztop -P $port 
         4 获取异常的sql之后,剩下的比较好解决了。结合第一部分中的几条原因
            a 选择合适的索引
            b 调整sql 语句 比如对应order by 分页采用延迟关联
            c 业务层面增加缓存,减少对数据库的直接访问等
    b) OS 系统层面 检查系统IO

        使用iostat 命令查看r/s(读请求),w/s(写请求),avgrq-sz(平均请求大小),await(IO等待), svctm(IO响应时间)

        r/s ,w/s是每秒读/写请求的次数。

       util是设备的利用率。如果它接近100%,通常说明设备能力趋于饱和(并不绝对,比如设备有写缓存)。有时候可能会出现大于100%的情况,这多半是计算时四舍五入引起的。
        svctm是平均每次请求的服务时间。这里有一个公式:(r/s+w/s)*(svctm/1000)=util。举例子:如果util达到100%,那么此时  svctm=1000/(r/s+w/s),假设IOPS是1000,则svctm大概在1毫秒左右,如果长时间大于这个数值,说明系统出了问题。
       await是平均每次请求的等待时间。这个时间包括了队列时间和服务时间,也就是说,一般情况下,await大于svctm,它们的差值越小,队列时间越短,反之差值越大,队列时间越长,说明系统出了问题。
    avgqu-sz是平均请求队列的长度。毫无疑问,队列长度越短越好。

  • 相关阅读:
    Codeforces 1485C Floor and Mod (枚举)
    CodeForces 1195D Submarine in the Rybinsk Sea (算贡献)
    CodeForces 1195C Basketball Exercise (线性DP)
    2021年初寒假训练第24场 B. 庆功会(搜索)
    任务分配(dp)
    开发工具的异常现象
    Telink MESH SDK 如何使用PWM
    Telink BLE MESH PWM波的小结
    [LeetCode] 1586. Binary Search Tree Iterator II
    [LeetCode] 1288. Remove Covered Intervals
  • 原文地址:https://www.cnblogs.com/jifeng/p/11115923.html
Copyright © 2011-2022 走看看