AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 517132
Accepted
sourcejedi
sourcejedi
Asked: 2019-05-05 11:10:22 +0800 CST2019-05-05 11:10:22 +0800 CST 2019-05-05 11:10:22 +0800 CST

`dd` 正在全速运行,但我只看到 20% 的磁盘利用率。为什么?

  • 772
  1. sudo dd if=/dev/sda of=/dev/null bs=1M iflag=direct
  2. atopsar -d 5 # in a second terminal
  3. top # in a third terminal

结果来自atopsar:

19:18:32  disk           busy read/s KB/read  writ/s KB/writ avque avserv _dsk_
...
19:16:50  sda             18%  156.5  1024.0     0.0     0.0   5.0   1.15 ms
19:16:55  sda             18%  156.3  1024.0     0.0     0.0   4.9   1.15 ms
...

为什么报告的磁盘利用率(“忙碌”)远低于 100%?

根据top,该dd进程仅使用 3% 或更少的 CPU。 还提供了系统 CPU 的硬件和软件中断 (和) 使用情况top的总体报告,显示低于 1%。我有四个 CPU(2 个内核,每个内核有 2 个线程)。hisi

/dev/sda是SATA硬盘。它不是 SSD,甚至不是混合 SSHD 驱动器。它的读取速度不能超过每秒 150 兆字节 :-)。所以这部分结果是有意义的:156 read/s * 1024 KB/read = 156 MB/s

内核版本是5.0.9-200.fc29.x86_64(Fedora Workstation 29)。IO 调度程序是mq-deadline. 从内核版本 5.0 开始,Fedora 使用多队列块层。因为单个队列块层已被删除:-)。

我相信磁盘利用率数据是根据内核 iostat 字段之一计算得出atopsar -d的。链接的文档提到“字段 10 - 花费在 I/O 上的毫秒数”。还有一个更详细的定义,虽然我不确定它提到的功能是否仍然存在于多队列块层中。据我所知,两者都使用通用代码来读取这个字段 10. (我相信这个字段也被//使用)atopatopsar -datopsar -diostat -xmxiostat.py

附加测试

变体 2:更改为bs=512k,但保留iflag=direct。

dd if=/dev/sda of=/dev/null bs=512k iflag=direct

19:18:32  disk           busy read/s KB/read  writ/s KB/writ avque avserv _dsk_
...
19:18:00  sda             35%  314.0   512.0     0.0     0.0   2.1   1.12 ms
19:18:05  sda             35%  313.6   512.0     0.2     4.0   2.1   1.11 ms

变体 3:使用bs=1M,但删除iflag=direct. dd使用大约 10% 的 CPU 和 35% 的磁盘。

dd if=/dev/sda of=/dev/null bs=1M

19:18:32  disk           busy read/s KB/read  writ/s KB/writ avque avserv _dsk_
...
19:21:47  sda             35%  242.3   660.2     0.0     0.0   5.4   1.44 ms
19:21:52  sda             31%  232.3   667.8     0.0     0.0   9.5   1.33 ms

如何重现这些结果 - 基本细节

当心最后的测试,即在dd 没有的情况下运行 iflag=direct

这有点像猪。我看到它冻结系统(鼠标光标)十秒钟或更长时间。即使我禁用了交换。(测试用buff/cache填充你的 RAM 。它正在填充非活动 LRU 列表。我认为周转相对较快地驱逐非活动缓存页面。同时,磁盘忙于顺序读取,因此在需要时需要更长的时间将某些内容分页。这可能会变得多么糟糕,这可能取决于内核最终是否也翻转了活动 LRU 列表,或者将其缩小太多。即当前的“多种不同算法的混搭效果如何,并进行了一些修改捕捉极端情况和各种优化”适用于您的情况)。

第一次测试的确切结果很难重现。

有时,KB/read显示为512而不是1024. 在这种情况下,其他结果看起来更像bs=512k. 包括它显示大约 35% 的磁盘利用率,而不是大约 20%。无论哪种情况,我的问题都成立。

如果您想了解这种行为,请参阅此处:为什么我的 IO 请求的大小被限制为大约 512K?

linux atop
  • 1 1 个回答
  • 1904 Views

1 个回答

  • Voted
  1. Best Answer
    sourcejedi
    2019-05-06T04:34:05+08:002019-05-06T04:34:05+08:00

    这是内核版本 5.0 更改的结果:

    块:删除 part_round_stats 并切换到不太精确的计数

    我们要转换为 per-cpu in_flight 计数器。

    函数 part_round_stats 需要每隔一瞬间的 in_flight 计数器,每隔一瞬间对所有 percpu 变量求和成本太高,因此必须将其删除。part_round_stats 用于计算两个计数器 - time_in_queue 和 io_ticks。

    time_in_queue 可以在没有 part_round_stats 的情况下计算,方法是在 I/O 结束时添加 I/O 的持续时间(该值几乎与先前计算的值一样精确,除了正在进行的 I/O 的时间不计算在内)。

    io_ticks 可以通过在 I/O 开始或结束并且 jiffies 值发生变化时增加值来近似。如果 I/O 占用的时间少于一瞬间,则该值与先前计算的值一样精确。如果 I/O 占用的时间超过一瞬间,io_ticks 可能会落后于先前计算的值。

    (io_ticks在part_stat_show()中使用,为“字段 10 - # of milliseconds 花在执行 I/O 上的时间”提供内核 IO 统计信息。)

    这很好地解释了我的结果。在 Fedora 内核配置中,“ jiffy ”是 1 毫秒。我预计提交的大型读取 IOdd可能会等待超过一两个 jiffies。特别是在我的系统上,它使用老式的机械硬盘。

    当我回到之前的内核系列 4.20.x 时,它显示了正确的磁盘利用率:

    $ uname -r
    4.20.15-200.fc29.x86_64
    $ atopsar -d 5
    ...
    13:27:19  disk           busy read/s KB/read  writ/s KB/writ avque avserv _dsk_
    13:28:49  sda             98%  149.4  1024.0    13.0     5.3   2.2   6.04 ms
    13:28:54  sda             98%  146.0  1024.0     7.2     5.7   1.5   6.38 ms
    

    这个旧内核默认使用传统的单队列块层和cfqIO 调度程序。deadline使用IO 调度器的结果也是一样的。


    更新:自内核 5.7 起,此近似值已调整。问题中的命令再次显示 100% 磁盘利用率。对于一些更复杂的工作负载(尽管我还没有注意到),预计新的近似值会被分解。

    block/diskstats:对慢速磁盘更准确的 io_ticks 近似值

    如果 jiffies 计数器发生变化,当前 io_ticks 是通过在请求的每个开始和结束时添加一个来近似的。这非常适用于短于一瞬间的请求,或者如果其中一个请求在每个瞬间开始/结束。

    如果磁盘一次只执行一个请求并且它们比两个 jiffies 长,则只计算第一个和最后一个 jiffies。

    修复很简单:在请求结束时添加自上次更新以来传递的 io_ticks jiffies 而不是一个 jiffy。

    示例:普通 HDD 在 12ms 左右执行随机读取 4k 请求。

    fio --name=test --filename=/dev/sdb --rw=randread --direct=1 --runtime=30 & iostat -x 10 sdb

    注意 iostat 的 "%util" 8,43% -> 99,99% 在补丁之前/之后的变化:

    前:

    Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
    sdb               0,00     0,00   82,60    0,00   330,40     0,00     8,00     0,96   12,09   12,09    0,00   1,02   8,43
    

    后:

    Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
    sdb               0,00     0,00   82,50    0,00   330,00     0,00     8,00     1,00   12,10   12,10    0,00  12,12  99,99
    

    现在 io_ticks 不会丢失请求开始和结束之间的时间,但是对于 queue-depth > 1,相邻开始之间的一些 I/O 时间可能会丢失。

    对于负载估计,“%util”不如平均队列长度有用,但它清楚地显示了磁盘队列完全为空的频率。

    修复:5b18b5a(“阻止:删除 part_round_stats 并切换到不太精确的计数”)
    签名人:Konstantin Khlebnikov <[email protected]>
    审核人:雷明 <[email protected]>
    签名人-off-by: Jens Axboe <[email protected]>

    • 8

相关问题

  • 有没有办法让 ls 只显示某些目录的隐藏文件?

  • 使用键盘快捷键启动/停止 systemd 服务 [关闭]

  • 需要一些系统调用

  • astyle 不会更改源文件格式

  • 通过标签将根文件系统传递给linux内核

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve