【问题标题】:ionice 'idle' not having the expected effectsionice 'idle' 没有预期的效果
【发布时间】:2018-06-30 06:34:39
【问题描述】:

我们正在使用一个相当繁忙的网络服务器。我们想使用 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.

在 Google 的帮助下,我在任何地方都没有清楚地解释这个“定义的宽限期”。一篇帖子表明这是 fifo_expire_async 的值,但我找不到任何真正的支持。

但是,在我们的系统上,fifo_expire_asyncfifo_expire_sync 都设置得足够长(250 毫秒、125 毫秒,这是默认值),因此空闲类实际上应该完全没有磁盘带宽。即使认为宽限期是由fifo_expire_async 设置的人是完全错误的,“空闲 I/O 进程对正常系统活动的影响应该为零”这句话也没有太多的回旋余地。

显然这不是我们机器上发生的事情,所以我想知道 CFQ+idle 是否只是坏了。

有没有人设法让它工作?非常感谢提示!

更新: 今天我又做了一些测试。我编写了一个小型 Python 应用程序来读取磁盘各处的随机扇区,中间有短暂的睡眠。我在没有离子的情况下运行了一个副本,并将其设置为每秒执行大约 30 次读取。然后,我运行了带有各种ionice 类的应用程序的第二个副本,以查看空闲类是否按照盒子上所说的那样做。当我使用类 1、2、3(实时、尽力而为、空闲)时,我发现结果之间根本没有区别。尽管我现在绝对确定磁盘很忙,但这一点。 因此,我现在确定 - 至少对于我们的设置 - CFQ+idle 不起作用。 [请参阅下面的更新 2 - 与其说是“不起作用”,不如说是“不起作用”预计”...]

仍然非常欢迎评论!

更新 2: 更多关于今天的戳。发现当我大幅提高 I/O 速率时,idle-class 进程实际上开始变得饥饿。在我的测试中,这发生在 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

【问题讨论】:

  • 您是否尝试过为slice_asyncslice_async 设置低值?我认为一旦空闲优先级类进程开始使用磁盘,它将继续使用slice_sync(读取)或slice_async(写入),尽管事实上另一个更高优先级的进程想要使用磁盘。有关详细信息,请参阅unix.stackexchange.com/a/41831/20336。我会尝试slice_async:40slice_sync:80fifo_expire_async:1000。根据 HDD,group_idle:0slice_idle:3(或 4-5)也可能没问题。

标签: linux io linux-kernel kernel scheduler


【解决方案1】:

向其中添加 nocache 并设置好(您可以使用 ionice 和 nice 加入它): https://github.com/Feh/nocache

在 Ubuntu 上安装: apt install nocache

它只是省略了 IO 上的缓存,并且由于刷新缓存时其他进程不会饿死。 这就像使用 O_DIRECT 调用命令,所以现在您可以限制 IO,例如:

systemd-run --scope -q --nice=19 -p BlockIOAccounting=true -p BlockIOWeight=10 -p "BlockIOWriteBandwidth=/dev/sda 10M" nocache youroperation_here

我通常将它用于:

nice -n 19 ionice -c 3 nocache youroperation_here

【讨论】:

    【解决方案2】:

    AFAIK,解决您的问题的唯一机会是使用 CGroup v2(内核 v. 4.5 或更高版本)。请参阅以下文章:

    https://andrestc.com/post/cgroups-io/

    另外请注意,您可以使用 systemd 的包装器为每个服务配置 CGroup 限制:

    http://0pointer.de/blog/projects/resources.html

    【讨论】:

    • 嗨,欢迎来到 StackOverflow。请编辑您的答案以在答案文本中包含必要的叙述,而不仅仅是通过链接,因为 StackOverflow 是一个问答知识库,链接可能是永久性的,也可能不是永久性的。谢谢。
    • 如果我理解正确的话,cgroup 解决方案只能将带宽限制在某个预定义的值。那正确吗?如果是这样,您是否同意这并不令人满意? “空闲”类的重点应该是在没有其他人需要的情况下使用所有可用带宽,而不是限制在预设值...
    猜你喜欢
    • 2014-05-06
    • 1970-01-01
    • 2012-10-14
    • 1970-01-01
    • 2021-01-13
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多