我们正在使用相当繁忙的网络服务器。我们想使用rsync来做一些显然会破坏磁盘的数据移动,所以我们使用ionice
将rsync进程放在空闲类中。系统上的两个磁盘(SSD + HDD)的队列都设置为使用CFQ调度程序。
结果......是磁盘绝对受到重创,网站性能令人震惊。
我已经做了一些挖掘,看看是否有任何调整可能对此有所帮助。
ionice
的手册页说:
Idle: A program running with idle I/O priority will only get disk time
when no other program has asked for disk I/O for a defined grace period.
The impact of an idle I/O process on normal system activity should be zero.
这个"定义的宽限期"我无法在谷歌的帮助下找到任何地方。一篇帖子表明它是fifo_expire_async
的价值,但我无法找到真正的支持。
但是,在我们的系统上,fifo_expire_async
和fifo_expire_sync
都设置得足够长(250毫秒,125毫秒,这是默认值),空闲类实际上应该完全没有磁盘带宽。即使认为宽限期由fifo_expire_async
设置的人是明白错误的,但在声明中并没有太多的摆动空间"空闲I / O过程的影响正常系统活动应为零"。
显然,这不是我们机器上发生的事情,所以我想知道CFQ +闲置是否会被打破。
有没有人设法让它上班?提示非常感谢!
更新
我今天做了一些测试。我写了一个小的Python应用程序来读取来自整个磁盘的随机扇区,其间有短暂的睡眠。我在没有电离的情况下运行了这个副本,并将其设置为每秒执行大约30次读取。然后,我用各种ionice
类运行了应用程序的第二个副本,以查看空闲类是否按照它在框中所说的那样执行。当我使用类1,2,3(实时,尽力而为,空闲)时,我看到在结果之间没有任何区别。尽管事实上我现在绝对确定磁盘很忙。
因此,我现在肯定 - 至少在我们的设置中 - CFQ +闲置不起作用。 [见下面的更新2 - 它不是那么多"确实如此不工作" as"没有按预期工作" ...]
评论仍然非常受欢迎!
更新2: 今天更加讨价还价。发现当我大幅提高I / O速率时,空闲级进程DO实际上开始变得饥饿。在我的测试中,这发生在I / O速率远高于我的预期 - 基本上每秒数百个I / O.我还在尝试弄清楚调整参数的作用......
我还发现了一个相当重要的事实,即在I / O优先级系统中根本不包含异步磁盘写入!我上面引用的ionice
联机帮助页没有引用该事实,但系统调用ioprio_set()
的联机帮助页有用说明:
读取和同步支持I / O优先级(O_DIRECT, O_SYNC)写道。异步不支持I / O优先级 写,因为它们是在程序的上下文之外发出的 弄脏内存,因此特定于程序的优先级不会 应用
这极大地改变了我处理性能问题的方式,我将提出ionice
联机帮助页的更新。
有关内核和iosched设置的更多信息(sdb是HDD):
Linux 4.9.0-4-amd64 #1 SMP Debian 4.9.65-3+deb9u1 (2017-12-23) x86_64 GNU/Linux
/etc/debian_version = 9.3
(cd /sys/block/sdb/queue/iosched; grep . *)
back_seek_max:16384
back_seek_penalty:2
fifo_expire_async:250
fifo_expire_sync:125
group_idle:8
group_idle_us:8000
low_latency:1
quantum:8
slice_async:40
slice_async_rq:2
slice_async_us:40000
slice_idle:8
slice_idle_us:8000
slice_sync:100
slice_sync_us:100000
target_latency:300
target_latency_us:300000
答案 0 :(得分:2)
AFAIK,解决问题的唯一机会是使用CGroup v2(内核v。4.5或更高版本)。请参阅以下文章:
https://andrestc.com/post/cgroups-io/
还请注意,您可以使用systemd的包装器基于每个服务配置CGroup限制:
答案 1 :(得分:1)
在其中添加nocache并设置好(可以与ionice和nice一起加入): https://github.com/Feh/nocache
在Ubuntu上安装: apt安装nocache
它只是忽略了IO上的缓存,这要感谢刷新缓存时其他进程不会饿死。 就像使用O_DIRECT调用命令一样,因此现在您可以使用以下方式限制IO:
BUS_FRAMES_sum[BID] = ([Payload, PLP])
# BUS_FRAMES_sum = is the name of the dictionary
# BID = is the name of the key in the dictionary
# [packet.GetPayloadBytes(), packet.PLPBytes] = are the values that I will sum every cycle (sum to Payload, and the other value sum to PLP.
我通常将其用于:
systemd-run --scope -q --nice=19 -p BlockIOAccounting=true -p BlockIOWeight=10 -p "BlockIOWriteBandwidth=/dev/sda 10M" nocache youroperation_here