- 总结
大家好,上一期给大家介绍了如何使用lttng以及log可以更好地分析ceph的运作模式,今天再给大家介绍一下如何使用性能分析工具观察cpu性能指标~
平均负载
前言:为了更好配置分布式储存集群的运行参数,使用性能分析工具观察业务环境是一种必要的手段。
top或者uptime
02:34:03//当前时间
up 2 days,20:14//系统运行时间
1 user //正在登录用户数
load average:0.63,0.83,0.88
依次则是过去1分钟、5分钟、15分钟的平均负载(LoadAverage)
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和CPU使用率并没有直接关系,所以,它不仅包括了正在使用CPU的进程,还包括等待CPU和等待I/O的进程。
可运行状态
可运行状态的进程,是指正在使用CPU或者正在等待CPU的进程,也就是我们常用ps命令看到的,处于R状态(Running或Runnable)的进程。
可中断的睡眠状态的进程会睡眠直到某个条件变为真,如产生一个硬件中断、释放进程正在等待的系统资源或是传递一个信号都可以是唤醒进程的条件。
不可中断状态
不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的。
那就是把信号传递到这种睡眠状态的进程不能改变它的状态,也就是说它不响应信号的唤醒。
比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制。
既然平均的是活跃进程数,那么最理想的,就是每个CPU上都刚好运行着一个进程,这样每个 CPU 都得到了充分利用。
比如当平均负载为2时,意味着什么呢?
- 在只有2个CPU的系统上,意味着所有的CPU都刚好被完全占用。
- 在4个CPU的系统上,意味着CPU有50%的空闲。
- 而在只有1个CPU的系统中,则意味着有一半的进程竞争不到CPU。====》 (平均负载比cpu个数大,过载)
所以,平均负载最理想的情况是等于CPU个数。
grep 'model name'/proc/cpuinfo | wc -l //可查看cpu数目
12//12核
如何观察数值
//假设单核情况
root@xxxx:~# uptime
09:28:31 up 1 day, 10:31, 2 users, load average: 1.96, 1.29, 1.59
假设是单核情况下,1分钟下来有96%超载,5分钟下来有29%超载,15分钟下来有59%超载。
- 当三者相差不大,说明系统的平均负载稳定。
- 当前1分钟比后两者小的时候,说明系统趋于降低。
- 如果1分钟的值远大于15分钟的值,就说明最近1分钟的负载在增加。
经验值之谈,一旦平均负载达到CPU数量的前后75%左右,需要排查负载高的问题。
平均负载与 CPU 使用率区别
CPU使用率,是单位时间内CPU繁忙情况的统计,跟平均负载并不一定完全对应;
CPU使用率:单位时间内cpu繁忙情况的统计。
- 情况1:CPU密集型进程,CPU使用率和平均负载基本一致。
- 情况2:IO密集型进程,平均负载升高,CPU使用率不一定升高。
- 情况3:大量等待CPU的进程调度,平均负载升高,CPU使用率也升高。
场景模拟
借用iostat mpstat pidstat可以分析出平均负载升高的原因。
模拟一下使用场景:
root@xxxx:~# apt install sysstat //常用的 Linux 性能工具,用来监控和分析系统的性能,包含两个命令 mpstat 和 pidsta
root@xxxx:~# apt install stress //一个 Linux 系统压力测试工具
前提环境:
机器配置:4 CPU,8GB 内存。
root@xxxx:~# uptime
11:36:37 up 13 days,29 min,3 users, load average:0.06,0.06,0.01
- CPU 的用户层(%usr)使用率;
- CPU 的系统层(%sys)使用率;
- CPU 的 I/0 – 等待(%iowait);
- CPU 的空闲率(%idle);
首先,我们在第一个终端运行stress命令,模拟一个CPU使用率100%的CPU密集型进程场景:
//一终端执行
root@xxxx:~# stress --cpu 4 --timeout 555
stress: info: [4563] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
//另一终端
root@xxxx:~# watch -d uptime
Every 2.0s: uptime xxxx: Tue Dec 22 11:43:36 2020
11:43:36 up 13 days, 36 min, 3 users, load average: 4.13, 1.28, 0.46
// 另一终端2
//-P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
root@xxxx:~# mpstat -P ALL 5
11:45:26 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:45:31 AM all 99.65 0.00 0.25 0.00 0.00 0.10 0.00 0.00 0.00 0.00
11:45:31 AM 0 99.40 0.00 0.40 0.00 0.00 0.20 0.00 0.00 0.00 0.00
11:45:31 AM 1 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
11:45:31 AM 2 99.80 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
11:45:31 AM 3 99.80 0.00 0.00 0.00 0.00 0.20 0.00 0.00 0.00 0.00
//从这里可以明显看到,stress 进程的 CPU 使用率接近 100%。
root@xxxx:~# pidstat -u 5 1
Linux 4.15.0-66-generic (xxxx) 12/22/2020 _x86_64_ (4 CPU)
11:48:58 AM UID PID %usr %system %guest %wait %CPU CPU Command
11:49:03 AM 0 2049 0.00 0.20 0.00 0.00 0.20 2 kworker/2:0
11:49:03 AM 64045 3358 0.60 0.20 0.00 0.00 0.80 3 ceph-mon
11:49:03 AM 0 4564 98.41 0.20 0.00 1.39 98.61 0 stress
11:49:03 AM 0 4565 98.81 0.00 0.00 0.99 98.81 1 stress
11:49:03 AM 0 4566 98.21 0.00 0.00 1.39 98.21 0 stress
11:49:03 AM 0 4567 99.20 0.00 0.00 0.60 99.20 2 stress
11:49:03 AM 0 5131 0.20 0.20 0.00 0.40 0.40 0 watch
11:49:03 AM 0 7419 0.20 0.40 0.00 0.00 0.60 3 pidstat
11:49:03 AM 0 26649 0.00 0.20 0.00 0.00 0.20 0 kworker/0:1
11:49:03 AM 0 26658 0.20 0.20 0.00 0.20 0.40 1 sshd
11:49:03 AM 64045 30555 0.60 0.00 0.00 0.00 0.60 1 ceph-osd
//
可以从load average: 4.13以及mpstat 的usr看得出负载场景基本符合CPU密集型进程,pidstat可以看得出是stress导致占用率过高。
然后模拟一个I/O密集型进程:
//一终端执行
//root@xxxx:~# stress -i 1 --timeout 600 // 因为 stress 使用的sync系统调用,刷新缓冲区到磁盘。有可能因缓冲区数据量小无法看到io_wait明显变化
root@xxxx:~# stress-ng -i 1 --hdd 1 --timeout 555
stress-ng: info: [9211] dispatching hogs: 1 io, 1 hdd
//另一终端
root@xxxx:~# watch -d uptime
16:46:09 up 13 days, 5:38, 3 users, load average: 2.91, 2.56, 1.10
// 另一终端2
//-P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
root@xxxx:~# mpstat -P ALL 5
Linux 4.15.0-66-generic (ECSab169d) 12/22/2020 _x86_64_ (4 CPU)
04:44:02 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
04:44:07 PM all 1.35 0.00 29.50 26.74 0.00 0.21 0.52 0.00 0.00 41.68
04:44:07 PM 0 2.05 0.00 30.12 26.23 0.00 0.20 0.61 0.00 0.00 40.78
04:44:07 PM 1 0.40 0.00 30.51 51.72 0.00 0.00 0.81 0.00 0.00 16.57
04:44:07 PM 2 0.84 0.00 19.29 19.08 0.00 0.00 0.42 0.00 0.00 60.38
04:44:07 PM 3 1.96 0.00 38.26 8.48 0.00 0.65 0.22 0.00 0.00 50.43
root@xxxx:~# pidstat -u 5 1
04:43:15 PM UID PID %usr %system %guest %wait %CPU CPU Command
04:43:20 PM 0 388 0.00 0.20 0.00 0.00 0.20 0 kworker/0:1H
04:43:20 PM 0 11841 0.00 2.00 0.00 0.00 2.00 1 kworker/1:2
04:43:20 PM 0 12449 0.00 5.40 0.00 0.40 5.40 1 stress-ng-io
04:43:20 PM 0 12450 2.60 60.20 0.00 0.80 62.80 0 stress-ng-hdd
04:43:20 PM 0 22527 0.20 0.20 0.00 0.00 0.40 1 sshd
04:43:20 PM 64045 30555 0.20 0.40 0.00 0.00 0.60 1 ceph-osd
从这里可以看到,1分钟的平均负载会慢慢增加到2.91,其中一个CPU的系统CPU使用率升高到了30.51,而iowait高达51.72%。这说明,平均负载的升高是由于iowait的升高,pidstat定位到stress进程。
模拟一个大量进程场景:
//一终端执行
root@xxxx:~# stress -c 8 --timeout 555
17:00:26 up 13 days, 5:53, 3 users, load average: 7.90, 4.95, 3.04
//另一终端
root@xxxx:~# watch -d uptime
17:00:49 up 13 days, 5:53, 3 users, load average: 7.94, 5.20, 3.17
root@xxxx:~# pidstat -u 5 1
04:43:15 PM UID PID %usr %system %guest %wait %CPU CPU Command
04:43:20 PM 0 388 0.00 0.20 0.00 0.00 0.20 0 kworker/0:1H
04:43:20 PM 0 11841 0.00 2.00 0.00 0.00 2.00 1 kworker/1:2
04:43:20 PM 0 12449 0.00 5.40 0.00 0.40 5.40 1 stress-ng-io
04:43:20 PM 0 12450 2.60 60.20 0.00 0.80 62.80 0 stress-ng-hdd
04:43:20 PM 0 22527 0.20 0.20 0.00 0.00 0.40 1 sshd
04:43:20 PM 64045 30555 0.20 0.40 0.00 0.00 0.60 1 ceph-osd
05:01:33 PM UID PID %usr %system %guest %wait %CPU CPU Command
05:01:38 PM 64045 3358 0.40 0.20 0.00 0.00 0.60 3 ceph-mon
05:01:38 PM 0 5131 0.60 0.20 0.00 0.60 0.80 1 watch
05:01:38 PM 0 9303 0.00 0.20 0.00 0.00 0.20 2 kworker/u8:3
05:01:38 PM 0 13169 0.00 0.20 0.00 0.00 0.20 0 kworker/0:2
05:01:38 PM 0 18138 48.91 0.00 0.00 51.09 48.91 1 stress
05:01:38 PM 0 18139 49.11 0.00 0.00 50.70 49.11 2 stress
05:01:38 PM 0 18140 48.71 0.00 0.00 50.89 48.71 0 stress
05:01:38 PM 0 18141 50.10 0.00 0.00 49.50 50.10 3 stress
05:01:38 PM 0 18142 47.91 0.00 0.00 51.89 47.91 3 stress
05:01:38 PM 0 18143 49.11 0.00 0.00 51.09 49.11 1 stress
05:01:38 PM 0 18144 52.29 0.00 0.00 47.71 52.29 0 stress
05:01:38 PM 0 18145 49.30 0.00 0.00 50.70 49.30 2 stress
05:01:38 PM 0 20608 0.00 0.20 0.00 0.20 0.20 0 pidstat
05:01:38 PM 0 22527 0.00 0.20 0.00 0.00 0.20 2 sshd
05:01:38 PM 64045 30555 0.40 0.00 0.00 0.00 0.40 1 ceph-osd
可以看出,8个进程在争抢4个CPU,每个进程等待CPU的时间(也就是代码块中的 %wait 列)高达50%。这些超出CPU计算能力的进程,最终导致CPU过载。
总结
- CPU密集型进程: 查看mpstat是否存在某个CPU %usr 很高但是iowait很低 , pidstat 定位具体进程(瓶颈不在io);
- IO密集型进程:mpstat 观察是否有某个cpu的%iowait很高,同时%usr也较高, pidstat 定位具体进程;
- 大量进程 :观察mpstat有可能iowait 很低, 但是从pidstat看出%wait很高,侧面表现出进程出现竞争cpu。
用到命令
- lscpu、grep ‘model name’ /proc/cpuinfo | wc -l :cpu核数;
- watch -d uptime:持续观察平均负载;
- pidstat -u 5 1:监测进程对应负载状态,进程性能分析工具;
- mpstat -P ALL 5:cpu总体状态 多核cpu性能分析工具,-P ALL监视所有cpu;
- strees : -c 产生多个worker进程;—cpu-method 使用哪种算法来运行压力测试,包括pi, crc16, fft等等,all选择全部;—sock 调用socket相关函数产生压力; -t, —timeout 等待xx微秒后才开始运行;-i, —io N spawn N workers spinning on sync()。
以上就是本期使用lttng以及log可以更好地分析ceph的运作模式的全部内容,下一期将带大家了解如何使用Vscode结合docker进行开发,敬请期待~