stress-ng 使用详解

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
*

源码编译安装,更为灵活(交叉编译)

  1. 源码下载(fossies.org/linux/priva...
  2. 解压 tar -zxvf stress-ng-0.17.03.tar.gz
  3. 交叉编译 修改Makefile,指定编译工具链,修改如下: CROSS_COMPILER = XXX/usr/bin/arm-linux-gnueabihf CC = $(CROSS_COMPILER)-gcc
  4. 执行make编译
  5. 将编译生成文件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 提供了一个强大而灵活的工具,用于对系统进行全面的压力测试。它的多样化负载类型和灵活的参数设置使得它成为评估系统性能和稳定性的理想选择。

相关推荐
无名指的等待71229 分钟前
SpringBoot中使用ElasticSearch
java·spring boot·后端
.生产的驴1 小时前
SpringBoot 消息队列RabbitMQ 消费者确认机制 失败重试机制
java·spring boot·分布式·后端·rabbitmq·java-rabbitmq
苹果酱05672 小时前
一文读懂SpringCLoud
java·开发语言·spring boot·后端·中间件
掐指一算乀缺钱2 小时前
SpringBoot 数据库表结构文档生成
java·数据库·spring boot·后端·spring
计算机学姐5 小时前
基于python+django+vue的影视推荐系统
开发语言·vue.js·后端·python·mysql·django·intellij-idea
JustinNeil5 小时前
简化Java对象转换:高效实现大对象的Entity、VO、DTO互转与代码优化
后端
青灯文案15 小时前
SpringBoot 项目统一 API 响应结果封装示例
java·spring boot·后端
微尘86 小时前
C语言存储类型 auto,register,static,extern
服务器·c语言·开发语言·c++·后端
计算机学姐6 小时前
基于PHP的电脑线上销售系统
开发语言·vscode·后端·mysql·编辑器·php·phpstorm
码拉松7 小时前
千万不要错过,优惠券设计与思考初探
后端·面试·架构