我们将与数据存储子系统的管理者打交道,看看它们在块I / O的意义上允许您做什么。

这里特别有趣的是,我们正在进入一个领域,在启动系统后进行的设置更改要比甚至在部署之前进行的决策重要得多。
看看下面的图片。
它提供了现代计算机正常运行所需的四个主要资源。 性能调整是在应用程序进程之间最佳分配这些资源的技术。 而且,所有这些资源并不是无限的,并且对生产力的影响也不尽相同。
存储子系统的性能会降低到其所使用的存储技术的性能:硬盘驱动器,SSD,SAN,NAS-它们在访问速度和吞吐量方面可能会有很大差异。 如果存储设备不满足要解决的任务的要求,那么功能强大的处理器和大量内存将无法保存情况。
如果您作为Linux专家可以影响硬件决策,请尝试确保您的组织具有足够的(或高级的)存储平台。 这将在将来节省许多问题。
现在,让我们看看在输入/输出(I / O)控件的帮助下可以做什么。
全部关于存储设备
I / O控制器正式称为blkio,但心情愉快时,它会响应Blocky。 像CPU控制器一样,Blocky具有两种操作模式:
- 使用相对I / O球(份额)进行调整,它允许您通过将值设置在10到1000之间来控制所有或选定块存储设备级别的性能。默认情况下,使用1000,因此任何更改只会减少I / O球选定的用户或服务。 为什么使用1000,而不是1024(如CPU)? 好问题。 显然,当Linux的开放性对他不利时就是这种情况。
- 绝对带宽调整以限制给定用户或服务的读取和/或写入速度。 默认情况下,此模式为禁用状态。
下面的屏幕快照显示了可以使用systemctl命令调整的参数。 在这里,我们使用了Tab键上的自动提示魔术来显示选项列表。 这称为bash-completion,如果您仍未使用此功能,那么该安装适当的PRM了。
相对的I / O球由BlockIODeviceWeight和BlockIOWeight参数控制。 在使用这些控制器之前,您需要了解这一点:它们仅在为存储设备启用CFQ调度程序时才起作用。
什么是I / O调度程序? 让我们从头开始,记住Linux内核负责确保计算机的所有硬件组件之间都能正确通信。 而且由于所有这些组件同时需要不同的东西,因此如果不订购就无法做到。 好吧,例如,我们如何组织我们的生活,为工作,休息,睡眠等安排生活。
如果我们谈论存储设备,则I / O调度程序负责在内核中组织其工作。 这只是程序代码,它定义了一种控制块设备数据流的方法,范围从USB闪存驱动器,硬盘驱动器到虚拟磁盘,而虚拟磁盘实际上是SAN中ISCI设备上某处的文件。
除了可以在Linux上使用的所有这些设备之外,计算机还必须执行各种任务。 另外,在现实生活中,我们在Red Hat称之为“用例”。 这就是为什么有不同的计划者专注于不同的场景的原因。 这些调度程序称为noop,deadline和cfq。 简而言之,它们每个都可以描述如下:
- Noop-非常适合没有旋转部件(闪存,ssd等)的块存储设备。
- 截止日期是一种轻量级的调度程序,致力于减少延迟。 默认情况下,由于大多数应用程序在读取时会遇到问题,因此优先考虑读取而以写入为代价。
- Cfq-专注于在系统范围内公平分配I / O带宽。 就像我们上面说的,这是唯一支持cgroup相对I / O选项的调度程序。
有关调度程序的更多信息 ,请参见《 Red Hat Enterprise Linux 7性能调整指南》。
关于计划者的所有讨论是什么? 此外,在大多数计算机上,如果没有SATA驱动器,则默认情况下不使用cfq。 在不知道这一点的情况下,您可以更改BlockIOWeight,直到变为蓝色为止没有任何效果。 不幸的是,systemd不会告诉您:“对不起,您正在徒劳地更改此参数。 这将无法正常工作,因为设备使用了错误的调度程序。”
那么,您如何找到这个“有趣的”功能呢? 像往常一样,从cgroups文档中我们在上一篇文章中写到。 在使用这些或那些调节器之前熟悉一下它总是有用的。
我们转到用例

再次,我们从一般用语到具体内容:让我向您介绍Kryakin先生。
他从事餐饮业,并且在应用程序服务器上有两个数据库来跟踪订单。 Kryakin先生坚持认为,鸭肉的订购数据库比鹅肉的订购数据库重要得多,因为鹅是水禽宝座上的冒名顶替者。
这两个数据库均配置为服务,其单位文件如下所示:
实际上,其中调用的脚本(duck.sh和goose.sh)在数据库中没有任何实际工作,而仅使用dd命令循环来模拟读写。 这两个脚本都使用/数据库文件系统,该文件系统位于其虚拟磁盘上。
让我们运行鸭子和鹅,看看它们在cgroup层次结构中的位置:
现在,由于我们知道了dd进程的PID,所以我们转到iotop命令来查看存储子系统中发生了什么:
好吧,12-14 MB / s ...不太快。 似乎Kryakin先生没有在数据存储系统上投入太多。 尽管我们已经对它的适当性有疑问,所以没有什么可惊讶的。
现在我们来看两个任务:PID 3301(鹅)和PID 3300(鸭)。 每个使用大约6 MB / s的I / O。 上面的屏幕截图的数字略有不同,但实际上它们一直在跳跃,平均而言,这两个任务平均共享存储设备的带宽。
Kryakin先生希望鸭子的I / O带宽至少是鹅的5倍,因此总是先处理鸭子订单。 让我们尝试通过以下命令使用BlockIOWeight参数:
我们看一下iotop,发现它不起作用:
让我们检查设备/ dev / vdb的I / O调度程序:
有趣的是...我们正在尝试将调度程序更改为cfq,但一无所获。 怎么了
事实是,我们的系统在KVM虚拟机上运行,事实证明,从7.1版开始,不再
可以在Red Hat Enterprise Linux中
更改调度程序。 这不是错误,而是与改进使用虚拟I / O设备的机制有关的功能。
但是,我们不要绝望。 我们还有两个可以更改的参数:BlockIOReadBandwidth和BlockIOWriteBandwidth在块设备级别运行,并忽略I / O调度程序。 由于我们知道设备/ dev / vdb的带宽(用于接收和输出的带宽大约为14 MB / s),将鹅限制为2 MB / s,因此我们似乎能够实现Kryakin先生的愿望。 让我们尝试:
我们看一下:PID 3426,又名鹅,现在在大约2 MB / s的地方使用I / O,而PID 3425(即鸭子)几乎用于所有14个!
Hooray,我们做了客户想要的事情,这意味着我们不仅节省了一些鹅,而且还节省了我们作为Linux专家的声誉。