stress 和 stress-ng 是Linux系统下用于模拟系统负载的工具,它们可以用于模拟CPU、内存、磁盘I/O等的负载,用于测试系统的稳定性、性能和资源管理等。
-
stress:
功能: stress 是一个用于测试系统稳定性的工具,它通过在系统上产生负载来模拟高负载条件。
-
stress-ng: 功能: stress-ng 是 stress 的升级版,它提供更多的选项和能力,同时可以测试更多的系统资源。
本文以stress-ng为例,介绍一下工具的安装和使用。
安装 stress 工具
stress-ng常用的安装方式有两种:
通过系统包管理器(如 apt、yum)进行安装
sudo apt-get install stress-ng
*
源码编译安装,更为灵活(交叉编译)
- 源码下载(fossies.org/linux/priva...)
- 解压 tar -zxvf stress-ng-0.17.03.tar.gz
- 交叉编译 修改Makefile,指定编译工具链,修改如下: CROSS_COMPILER = XXX/usr/bin/arm-linux-gnueabihf CC = $(CROSS_COMPILER)-gcc
- 执行make编译
- 将编译生成文件stress-ng拷贝到执行环境使用即可
模拟系统负载
stress-ng 兼容 stress, 但在此基础上增加了大量新的参数选项。stress-ng的帮助文档巨多,有1千多条,这边就只介绍几种常用的命令。
ruby
root@miachel:/ # stress-ng -h | wc -l
root@miachel:/ # 1185
常用选项 : -c, --cpu N 产生 N 个进程,每个进程都反复不停的计算随机数的平方根 -i, --io N 产生 N 个进程,每个进程反复调用 sync() 将内存上的内容写到硬盘上 -m, --vm N 产生 N 个进程,每个进程不断分配和释放内存 --vm-bytes B 指定分配内存的大小 --vm-stride B 不断的给部分内存赋值,让 COW(Copy On Write)发生 --vm-hang N 指示每个消耗内存的进程在分配到内存后转入睡眠状态 N 秒,然后释放内存,一直重复执行这个过程 --vm-keep 一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存) -d, --hadd N 产生 N 个不断执行 write 和 unlink 函数的进程(创建文件,写入内容,删除文件) --hadd-bytes B 指定文件大小 -t, --timeout N 在 N 秒后结束程序
--backoff N 等待N微妙后开始运行 -q, --quiet 程序在运行的过程中不输出信息 -n, --dry-run 输出程序会做什么而并不实际执行相关的操作 -v, --verbose 显示详细的信息
1. 模拟CPU使用场景
stress-ng 消耗 CPU 资源是通过调用 sqrt函数计算由 rand函数产生的随机数的平方根来实现。下面的命令会产生2个进程执行计算,执行60s结束:
css
stress-ng --cpu 2 -t 60
scss
root@miachel:/ # stress-ng --cpu 2 -t 60
root@miachel:/ # top
Mem: 82984K used, 224816K free, 768K shrd, 0K buff, 7812K cached
CPU: 50% usr 0% sys 0% nic 50% idle 0% io 0% irq 0% sirq
Load average: 1.16 1.03 1.01 3/151 609
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
607 606 root R 12928 4% 24% {stress-ng-cpu} stress-ng --cpu 2 -t 6
608 606 root R 12928 4% 24% {stress-ng-cpu} stress-ng --cpu 2 -t 6
609 147 root R 1888 1% 2% top
606 147 root S 12928 4% 0% stress-ng --cpu 2 -t 60
1 0 root S 1888 1% 0% init
可以根据实际配置来模拟不同负载程度,我的开发板是4核,设置2个计算进程,CPU占用率为50%左右。
2. 模拟内存使用场景
创建10个进程,每个分配180M内存,不断释放并重新分配
css
stress-ng --vm 10 --vm-bytes 180M
创建10个进程,每个分配180M内存,并一直占用
css
stress-ng --vm 10 --vm-bytes 180M --vm-keep
创建10个进程,每个分配180M内存,内存分配后睡眠60s,然后释放
css
stress-ng --vm 10 --vm-bytes 180M --vm-hang 60
--vm-keep 选项,一直占用分配内存,并且默认会一直进行stride 操作,理论上此时应该是高CPU占用,高内存占用情况; --vm-hang 60选项,同样会一直占用分配内存,但内存分配后,进程处于睡眠状态,让出CPU。所以,此时应该是低CPU占用,高内存占用情况。
来看看实际如何:
空闲状态
yaml
root@miachel:/ # top
Mem: 78660K used, 229140K free, 28K shrd, 0K buff, 7072K cached
CPU: 0% usr 0% sys 0% nic 100% idle 0% io 0% irq 0% sirq
Load average: 1.06 1.01 1.00 1/148 611
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
1 0 root S 1888 1% 0% init
147 1 root S 1888 1% 0% -/bin/sh
611 147 root R 1888 1% 0% top
40 2 root SW 0 0% 0% [kswapd0]
3 2 root SW 0 0% 0% [ksoftirqd/0]
root@miachel:/ # free -m
total used free shared buffers cached
Mem: 300 76 223 0 0 6
-/+ buffers/cache: 69 230
Swap: 0 0 0
--vm-keep
scss
root@miachel:/ # stress-ng --vm 10 --vm-bytes 180M --vm-keep &
root@miachel:/ # top
Mem: 289792K used, 18008K free, 836K shrd, 0K buff, 7924K cached
CPU: 98% usr 1% sys 0% nic 0% idle 0% io 0% irq 0% sirq
Load average: 6.36 2.42 1.48 11/169 636
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
627 619 root R 33712 11% 14% {stress-ng-vm} stress-ng --vm 10 --vm-
625 615 root R 33712 11% 12% {stress-ng-vm} stress-ng --vm 10 --vm-
633 621 root R 33712 11% 12% {stress-ng-vm} stress-ng --vm 10 --vm-
632 622 root R 33712 11% 12% {stress-ng-vm} stress-ng --vm 10 --vm-
628 618 root R 33712 11% 10% {stress-ng-vm} stress-ng --vm 10 --vm-
624 614 root R 33712 11% 8% {stress-ng-vm} stress-ng --vm 10 --vm-
626 616 root R 33712 11% 8% {stress-ng-vm} stress-ng --vm 10 --vm-
631 623 root R 33712 11% 8% {stress-ng-vm} stress-ng --vm 10 --vm-
630 620 root R 33712 11% 8% {stress-ng-vm} stress-ng --vm 10 --vm-
629 617 root R 33712 11% 7% {stress-ng-vm} stress-ng --vm 10 --vm-
614 613 root S 12960 4% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
root@miachel:/ # free -m
total used free shared buffers cached
Mem: 300 278 22 0 0 3
-/+ buffers/cache: 275 25
Swap: 0 0 0
--vm-hang 60
scss
root@miachel:/ # stress-ng --vm 10 --vm-bytes 180M --vm-hang 60 &
root@miachel:/ # top
Mem: 262908K used, 44892K free, 836K shrd, 0K buff, 4192K cached
CPU: 0% usr 2% sys 0% nic 97% idle 0% io 0% irq 0% sirq
Load average: 1.63 5.27 4.02 1/169 678
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
678 147 root R 1888 1% 2% top
654 644 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
656 646 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
658 648 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
655 645 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
659 649 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
657 647 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
660 651 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
661 652 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
662 650 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
663 653 root S 31392 10% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
644 643 root S 12960 4% 0% {stress-ng-vm} stress-ng --vm 10 --vm-
root@miachel:/ # free -m
total used free shared buffers cached
Mem: 300 256 43 0 0 4
-/+ buffers/cache: 252 47
Swap: 0 0
跟预想的一致,--vm-keep选项,会导致CPU占用率变高,系统负载升高,而--vm-hang 60选项,只会影响内存使用。
3. 模拟IO使用场景
创建10个进程,循环调用 sync函数将内存缓冲区内容写到硬盘上
css
stress-ng -i 10
创建10个进程,不断的在磁盘上创建 10M 大小的文件并写入内容
css
stress-ng -d 10 --hdd-bytes 10M
试验一下:
css
root@miachel:/ # stress-ng -i 10 &
root@miachel:/ # top
Mem: 76336K used, 231464K free, 796K shrd, 0K buff, 3140K cached
CPU: 0% usr 92% sys 0% nic 6% idle 0% io 0% irq 0% sirq
Load average: 12.63 7.56 4.01 9/162 789
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
778 775 root R 12956 4% 7% {stress-ng-io} stress-ng -i 10
783 775 root R 12956 4% 7% {stress-ng-io} stress-ng -i 10
779 775 root R 12956 4% 7% {stress-ng-io} stress-ng -i 10
786 775 root D 12956 4% 7% {stress-ng-io} stress-ng -i 10
776 775 root R 12956 4% 7% {stress-ng-io} stress-ng -i 10
782 775 root R 12956 4% 7% {stress-ng-io} stress-ng -i 10
784 775 root R 12956 4% 7% {stress-ng-io} stress-ng -i 10
777 775 root R 12956 4% 7% {stress-ng-io} stress-ng -i 10
780 775 root R 12956 4% 7% {stress-ng-io} stress-ng -i 10
781 775 root D 12956 4% 7% {stress-ng-io} stress-ng -i 10
789 147 root R 1888 1% 0% top
775 147 root S 12956 4% 0% stress-ng -i 10
1 0 root S 1888 1% 0% init
147 1 root S 1888 1% 0% -/bin/sh
可以看到,系统负载确实很高,但 iowait 是 0%,而94%的CPU占用集中在内核空间。为什么不是消耗在IO等待上?似乎跟想要的结果不太一致。且慢,换台设备试试:
sql
root@PC:/ # stress-ng -i 10 &
root@PC:/ # top
top - 13:19:01 up 98 days, 3:08, 5 users, load average: 10.55, 9.80, 7.08
任务: 417 total, 1 running, 353 sleeping, 6 stopped, 0 zombie
%Cpu(s): 3.4 us, 11.0 sy, 0.0 ni, 47.1 id, 38.4 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem : 16274000 total, 2870140 free, 5603108 used, 7800752 buff/cache
KiB Swap: 2097148 total, 1379836 free, 717312 used. 10068624 avail Mem
进禠USER PR NI VIRT RES SHR 䞠%CPU %MEM TIME+ COMMAND
13063 deptrum 20 0 41528 284 52 D 8.0 0.0 0:32.65 stress-ng-iosyn
13069 deptrum 20 0 41528 284 52 D 7.6 0.0 0:32.40 stress-ng-iosyn
13064 deptrum 20 0 41528 284 52 D 7.3 0.0 0:32.49 stress-ng-iosyn
13066 deptrum 20 0 41528 284 52 D 7.0 0.0 0:33.00 stress-ng-iosyn
13071 deptrum 20 0 41528 284 52 D 6.0 0.0 0:32.12 stress-ng-iosyn
13068 deptrum 20 0 41528 284 52 D 5.0 0.0 0:32.30 stress-ng-iosyn
13070 deptrum 20 0 41528 284 52 D 5.0 0.0 0:32.81 stress-ng-iosyn
13065 deptrum 20 0 41528 284 52 D 4.3 0.0 0:31.30 stress-ng-iosyn
13067 deptrum 20 0 41528 284 52 D 4.3 0.0 0:31.89 stress-ng-iosyn
13072 deptrum 20 0 41528 284 52 D 2.7 0.0 0:32.51 stress-ng-iosyn
一样系统负载比较高,不同的是CPU大部分消耗在IO等待上(iowait为38.4%)。看起来这更像是我们想要的结果,但是为什么不同设备会有不同的表现呢?
让我们来系统的分析一下其中的原理:
lua
第一种情况
92% sys -- 说明进程有92%的CPU时间处于内核态,并且确确实实是在"干活的"(不是运行idle进程)
0% io -- 说明当CPU处于空闲状态时,并没有进程在等待IO请求完成
第二种情况
11.0 sy -- 说明进程有11%的CPU时间处于内核态,且CPU不是处于空想状态
38.4 wa -- 说明当CPU处于空闲状态时,进程有38.4%的CPU时间在等待IO请求完成
结合我们执行的指令[ stress-ng -i 10 创建10个进程,循环调用 sync函数将内存缓冲区内容写到硬盘上 ],第一种情况应该是因为缓存比较小,导致进程一直在执行sync动作,所以进程的消耗主要在内核态的sync上,而第二种情况,由于缓存比较大,所以,进程有很大一部分时间在等待IO完成。
后续有时间再补充实验验证结果吧。。。
总之,stress-ng 提供了一个强大而灵活的工具,用于对系统进行全面的压力测试。它的多样化负载类型和灵活的参数设置使得它成为评估系统性能和稳定性的理想选择。