块 I/O 控制器¶
概述¶
cgroup 子系统 “blkio” 实现了块 I/O 控制器。存储层次结构中的叶节点和中间节点似乎都需要各种 I/O 控制策略(如比例带宽、最大带宽)。计划使用相同的基于 cgroup 的管理界面来管理 blkio 控制器,并根据用户选项在后台切换 I/O 策略。
一种 I/O 控制策略是节流策略,可用于指定设备上的 I/O 速率上限。此策略在通用块层中实现,可用于叶节点以及更高级别的逻辑设备(如设备映射器)。
HOWTO¶
节流/上限策略¶
启用块 I/O 控制器
CONFIG_BLK_CGROUP=y
在块层中启用节流
CONFIG_BLK_DEV_THROTTLING=y
挂载 blkio 控制器(参见 控制组,为什么需要 cgroup?)
mount -t cgroup -o blkio none /sys/fs/cgroup/blkio
为根组指定特定设备上的带宽速率。策略的格式为“<major>:<minor> <bytes_per_second>”
echo "8:16 1048576" > /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device
这将限制主/次设备号为 8:16 的根组的读取速度为 1MB/秒。
运行 dd 来读取文件,看看速率是否被限制为 1MB/s
# dd iflag=direct if=/mnt/common/zerofile of=/dev/null bs=4K count=1024
1024+0 records in
1024+0 records out
4194304 bytes (4.2 MB) copied, 4.0001 s, 1.0 MB/s
可以使用 blkio.throttle.write_bps_device 文件来限制写入。
分层 Cgroups¶
节流实现层次结构支持;但是,只有在 cgroup 端启用 “sane_behavior” 时,才会启用节流的层次结构支持,这目前是一个开发选项,尚未公开提供。
如果有人创建如下层次结构
root
/ \
test1 test2
|
test3
带有 “sane_behavior” 的节流将正确处理层次结构。对于节流,所有限制都适用于整个子树,而所有统计信息都特定于该 cgroup 中任务直接生成的 I/O。
如果 cgroup 端未启用 “sane_behavior” 的节流实际上会将同一级别的所有组视为如下所示
pivot
/ / \ \
root test1 test2 test3
各种用户可见的配置选项¶
- CONFIG_BLK_CGROUP
块 I/O 控制器。
- CONFIG_BFQ_CGROUP_DEBUG
调试帮助。如果启用此选项,则一些额外的统计文件会显示在 cgroup 中。
- CONFIG_BLK_DEV_THROTTLING
在块层中启用块设备节流支持。
cgroup 文件的详细信息¶
比例权重策略文件¶
- blkio.bfq.weight
指定每个 cgroup 的权重。这是该组在所有设备上的默认权重,直到被每个设备的规则覆盖(参见下面的 blkio.bfq.weight_device)。
目前允许的权重范围为 1 到 1000。有关更多详细信息,请参见 BFQ(预算公平排队)。
- blkio.bfq.weight_device
指定每个 cgroup 每个设备的权重,从而覆盖默认的组权重。有关更多详细信息,请参见 BFQ(预算公平排队)。
以下是格式
# echo dev_maj:dev_minor weight > blkio.bfq.weight_device在此 cgroup 中配置 /dev/sdb (8:16) 上的 weight=300
# echo 8:16 300 > blkio.bfq.weight_device # cat blkio.bfq.weight_device dev weight 8:16 300在此 cgroup 中配置 /dev/sda (8:0) 上的 weight=500
# echo 8:0 500 > blkio.bfq.weight_device # cat blkio.bfq.weight_device dev weight 8:0 500 8:16 300删除此 cgroup 中 /dev/sda 的特定权重
# echo 8:0 0 > blkio.bfq.weight_device # cat blkio.bfq.weight_device dev weight 8:16 300- blkio.time
每个设备分配给 cgroup 的磁盘时间,以毫秒为单位。前两个字段指定设备的主设备号和次设备号,第三个字段指定分配给组的磁盘时间,以毫秒为单位。
- blkio.sectors
该组传输到/从磁盘的扇区数。前两个字段指定设备的主设备号和次设备号,第三个字段指定该组传输到/从设备的扇区数。
- blkio.io_service_bytes
该组传输到/从磁盘的字节数。这些字节数按操作类型进一步划分 - 读取或写入、同步或异步。前两个字段指定设备的主设备号和次设备号,第三个字段指定操作类型,第四个字段指定字节数。
- blkio.io_serviced
该组发往磁盘的 IO(bio)数量。这些 IO 按操作类型进一步划分 - 读取或写入、同步或异步。前两个字段指定设备的主设备号和次设备号,第三个字段指定操作类型,第四个字段指定 IO 数量。
- blkio.io_service_time
此 cgroup 完成的 IO 请求分发和请求完成之间的总时间。单位为纳秒,使其对闪存设备也有意义。对于队列深度为 1 的设备,此时间表示实际的服务时间。当 queue_depth > 1 时,情况不再如此,因为请求可能会乱序处理。这可能会导致给定 IO 的服务时间包括多个 IO 的服务时间(乱序处理时),这可能会导致总 io_service_time > 实际经过的时间。此时间按操作类型进一步划分 - 读取或写入、同步或异步。前两个字段指定设备的主设备号和次设备号,第三个字段指定操作类型,第四个字段指定 io_service_time,单位为纳秒。
- blkio.io_wait_time
此 cgroup 的 IO 在调度程序队列中等待服务的总时间。这可能大于经过的总时间,因为这是所有 IO 的累积 io_wait_time。它不是衡量 cgroup 总等待时间的指标,而是衡量其各个 IO 的 wait_time 的指标。对于 queue_depth > 1 的设备,此指标不包括将 IO 分派到设备后直到实际被服务的时间(由于设备对请求的重新排序,这里可能存在时间延迟)。单位为纳秒,使其对闪存设备也有意义。此时间按操作类型进一步划分 - 读取或写入、同步或异步。前两个字段指定设备的主设备号和次设备号,第三个字段指定操作类型,第四个字段指定 io_wait_time,单位为纳秒。
- blkio.io_merged
合并到属于此 cgroup 的请求中的 bios/请求总数。按操作类型进一步划分 - 读取或写入、同步或异步。
- blkio.io_queued
在任何给定时刻为此 cgroup 排队的请求总数。按操作类型进一步划分 - 读取或写入、同步或异步。
- blkio.avg_queue_size
仅在 CONFIG_BFQ_CGROUP_DEBUG=y 时启用调试辅助。此 cgroup 的整个生存期内的平均队列大小。每次此 cgroup 的队列之一获得时间片时,都会采集队列大小样本。
- blkio.group_wait_time
仅在 CONFIG_BFQ_CGROUP_DEBUG=y 时启用调试辅助。这是 cgroup 从繁忙状态(即,从 0 到 1 个请求排队)到为其队列之一获取时间片所必须等待的时间量。这与 io_wait_time 不同,后者是该 cgroup 中每个 IO 在调度程序队列中等待所花费的时间的累积总数。单位为纳秒。如果在 cgroup 处于等待(时间片)状态时读取此数据,则该统计信息将仅报告累积到上次获取时间片为止的 group_wait_time,并且不包括当前增量。
- blkio.empty_time
仅在 CONFIG_BFQ_CGROUP_DEBUG=y 时启用调试辅助。这是 cgroup 在没有挂起请求时未被服务所花费的时间量,即,它不包括为 cgroup 的队列之一空闲所花费的任何时间。单位为纳秒。如果在 cgroup 处于空闲状态时读取此数据,则该统计信息将仅报告累积到上次有挂起请求为止的 empty_time,并且不包括当前增量。
- blkio.idle_time
仅在 CONFIG_BFQ_CGROUP_DEBUG=y 时启用调试辅助。这是 IO 调度程序在给定 cgroup 上空闲所花费的时间量,以等待比来自其他队列/cgroup 的现有请求更好的请求。单位为纳秒。如果在 cgroup 处于空闲状态时读取此数据,则该统计信息将仅报告累积到上次空闲期间为止的 idle_time,并且不包括当前增量。
- blkio.dequeue
仅在 CONFIG_BFQ_CGROUP_DEBUG=y 时启用调试辅助。这给出了有关组从设备的服务器树中出列的次数的统计信息。前两个字段指定设备的主设备号和次设备号,第三个字段指定组从特定设备出列的次数。
- blkio.*_recursive
各种统计信息的递归版本。这些文件显示的信息与其非递归对应文件相同,但包括来自所有后代 cgroup 的统计信息。
节流/上限策略文件¶
- blkio.throttle.read_bps_device
指定从设备读取速率的上限。IO 速率以每秒字节数为单位指定。规则是每个设备的。以下是格式
echo "<major>:<minor> <rate_bytes_per_second>" > /cgrp/blkio.throttle.read_bps_device- blkio.throttle.write_bps_device
指定写入设备的速率上限。IO 速率以每秒字节数为单位指定。规则是每个设备的。以下是格式
echo "<major>:<minor> <rate_bytes_per_second>" > /cgrp/blkio.throttle.write_bps_device- blkio.throttle.read_iops_device
指定从设备读取速率的上限。IO 速率以每秒 IO 数为单位指定。规则是每个设备的。以下是格式
echo "<major>:<minor> <rate_io_per_second>" > /cgrp/blkio.throttle.read_iops_device- blkio.throttle.write_iops_device
指定写入设备的速率上限。IO 速率以每秒 IO 数为单位指定。规则是每个设备的。以下是格式
echo "<major>:<minor> <rate_io_per_second>" > /cgrp/blkio.throttle.write_iops_device注意:如果为设备同时指定了 BW 和 IOPS 规则,则 IO 将受到这两个约束。
- blkio.throttle.io_serviced
该组发往磁盘的 IO(bio)数量。这些 IO 按操作类型进一步划分 - 读取或写入、同步或异步。前两个字段指定设备的主设备号和次设备号,第三个字段指定操作类型,第四个字段指定 IO 数量。
- blkio.throttle.io_service_bytes
该组传输到/从磁盘的字节数。这些字节数按操作类型进一步划分 - 读取或写入、同步或异步。前两个字段指定设备的主设备号和次设备号,第三个字段指定操作类型,第四个字段指定字节数。
各种策略之间的通用文件¶
- blkio.reset_stats
将 int 写入此文件将导致重置该 cgroup 的所有统计信息。