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 提供了一个强大而灵活的工具,用于对系统进行全面的压力测试。它的多样化负载类型和灵活的参数设置使得它成为评估系统性能和稳定性的理想选择。

相关推荐
monkey_meng8 分钟前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee23 分钟前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
新知图书1 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放1 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
Ares-Wang2 小时前
Asp.net Core Hosted Service(托管服务) Timer (定时任务)
后端·asp.net
Rverdoser3 小时前
RabbitMQ的基本概念和入门
开发语言·后端·ruby
Tech Synapse4 小时前
Java根据前端返回的字段名进行查询数据的方法
java·开发语言·后端
.生产的驴4 小时前
SpringCloud OpenFeign用户转发在请求头中添加用户信息 微服务内部调用
spring boot·后端·spring·spring cloud·微服务·架构
微信-since811924 小时前
[ruby on rails] 安装docker
后端·docker·ruby on rails
代码吐槽菌6 小时前
基于SSM的毕业论文管理系统【附源码】
java·开发语言·数据库·后端·ssm