Red Hat Training
A Red Hat training course is available for Red Hat Enterprise Linux
附录 A. 子系统和可调参数
“子系统” 是识别 cgroup 的 kernel 模块。通常,它们被看做资源管控器,为不同 cgroup 分配不同级别的系统资源。但是当不同的进程组需要被区别对待时,可以改写子系统与 kernel 间的互动。用于开发新子系统的 “应用程序编程界面”(API)记载于 kernel 文档的
cgroups.txt
中,该文件安装在您系统的 /usr/share/doc/kernel-doc-kernel-version/Documentation/cgroups/
中(由 kernel-doc 软件包提供)。cgroup 文档的最新版本可在 http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt 中找到。请注意:最新文档所述功能可能不与您系统中已安装的 kernel 功能匹配。
包含 cgroup 子系统参数的“状态对象”在 cgroup 的虚拟文件系统中,被描述为 “伪文件”。这些伪文件可由 shell 命令或者与其对等的系统呼叫来操作。例如:
cpuset.cpus
是一份指定 cgroup可以存取哪个 CPU 的伪文件。如果 /cgroup/cpuset/webserver
是系统中运行的网页服务器的 cgroup,那么以下命令会被执行:
~]# echo 0,2 > /cgroup/cpuset/webserver/cpuset.cpus
因为
cpuset.cpus
伪文件中写入了 0,2
值,所以任何任务的 PID 一旦被列入 /cgroup/cpuset/webserver/tasks/
,那么此任务将仅能在系统中使用 CPU 0 和 CPU 2。
A.1. blkio
块 I/O(
blkio
)子系统可以控制并监控 cgroup 中的任务对块设备 I/O 的存取。对一些伪文件写入值可以限制存取次数或带宽,从伪文件中读取值可以获得关于 I/O 操作的信息。
blkio
子系统给出两种方式来控制对 I/O 的存取:
- “权重分配” — 用于完全公平列队 I/O 调度程序 (Completely Fair Queuing I/O scheduler),用此方法,让您可以给指定的 cgroup 设定权重。这意味着每个 cgroup 都有一个预留的 I/O 操作设定比例(根据 cgroup 的权重)。详情请参阅〈第 A.1.1 节 “权重分配的可调参数”〉。
- “I/O 节流(上限)” — 当一个指定设备执行 I/O 操作时,此方法可为其操作次数设定上限。这意味着一个设备的 “读” 或者 “写” 的操作次数是可以限定的。详情请参阅第 A.1.2 节 “I/O 节流可调参数”。
重要
目前,block I/O 子系统不支持已缓冲的 “写” 操作。虽然可以支持已缓冲的 “读” 操作,但它主要针对直接 I/O。
A.1.1. 权重分配的可调参数
- blkio.weight
- 此参数用于指定一个 cgroup 在默认情况下可存取块 I/O 的相对比例(加权),范围是
100
到1000
。该值可被指定设备的blkio.weight_device
参数覆盖。例如:如要将 cgroup 存取块设备的默认权重设定为500
,请运行:echo 500 > blkio.weight
- blkio.weight_device
- 此参数用于设定 cgroup 中指定设备 I/O 存取的相对比例(加权),范围是
100
到1000
。对于指定的设备,此参数值可覆盖blkio.weight
参数值。值的格式为 major:minor weight。其中 major 和 minor 是〈Linux 分配的设备〉所指定的设备类型和节点数,我们也称之为〈Linux 设备列表〉,可从 http://www.kernel.org/doc/Documentation/devices.txt 中找到。例如:如果设定 cgroup 访问/dev/sda
的权重为500
,请运行:echo 8:0 500 > blkio.weight_device
在〈Linux 分配的设备〉标记法中,8:0
代表/dev/sda
。
A.1.2. I/O 节流可调参数
- blkio.throttle.read_bps_device
- 此参数用于设定设备执行“读”操作字节的上限。“读”的操作率以每秒的字节数来限定。条目有三种字段:major、minor 和 bytes_per_second。major 和 minor 是〈Linux 分配的设备〉所指定的设备类型和节点数。bytes_per_second 是“读”操作可被执行的上限率。例如,让
/dev/sda
设备运行“读”操作的最大速率是 10 MBps,请运行:~]#
echo "8:0 10485760" > /cgroup/blkio/test/blkio.throttle.read_bps_device
- blkio.throttle.read_iops_device
- 此参数用于设定设备执行“读”操作次数的上限。“读”的操作率以每秒的操作次数来表示。条目有三个字段:major、minor 和 operations_per_second。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数。operations_per_second 是“读”可被执行的上限率。例如:如要设定
/dev/sda
设备执行“读”的最大比率为 10 次/秒,请运行:~]#
echo "8:0 10" > /cgroup/blkio/test/blkio.throttle.read_iops_device
- blkio.throttle.write_bps_device
- 此参数用于设定设备执行“写”操作次数的上限。“写”的操作率用“字节/秒”来表示。条目有三个字段:major、minor 和 bytes_per_second。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数。bytes_per_second 是“写”操作可被执行的上限率。例如,让
/dev/sda
设备执行“写”操作的最大比率为 10 MBps,请运行:~]#
echo "8:0 10485760" > /cgroup/blkio/test/blkio.throttle.write_bps_device
- blkio.throttle.write_iops_device
- 此参数用于设定设备执行 “写” 操作次数的上限。“写”的操作率以每秒的操作次数来表示。条目有三个字段:major、minor 和 operations_per_second。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数。operations_per_second 是“写” 操作可被执行的上限率。例如:如要让
/dev/sda
设备执行“写”操作的最大比率为 10 次/秒,请运行:~]#
echo "8:0 10" > /cgroup/blkio/test/blkio.throttle.write_iops_device
- blkio.throttle.io_serviced
- 此参数用于报告 cgroup 根据节流方式在具体设备中执行的 I/O 操作数。条目有四个字段:major、minor、operation 和 number。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数,operation 代表操作类型(
read
、write
、sync
或者async
),number 代表操作数。 - blkio.throttle.io_service_bytes
- 此参数用于报告 cgroup 传送到具体设备或者由具体设备中传送出的字节数。
blkio.io_service_bytes
和blkio.throttle.io_service_bytes
之间的唯一区别是:CFQ 调度程序在请求队列中操作时,前者不会被更新。条目有四个字段:major、minor、operation 和 bytes。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数。operation 代表操作类型(read
、write
、sync
或者async
)。bytes 是被传送的字节数。
A.1.3. blkio 的通用可调参数
以下参数可用于〈第 A.1 节 “blkio”〉所列方法的任意一个。
- blkio.reset_stats
- 此参数用于重设其它伪文件记录的统计数据。请在此文件中写入整数来为 cgroup 重设统计数据。
- blkio.time
- 此参数用于报告 cgroup 对具体设备的 I/O 访问时间。条目有三个字段:major、minor 和 time。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数,time 表示时间长度,单位为毫秒(ms)。
- blkio.sectors
- 此参数用于报告 cgroup 转换到具体设备或者由具体设备转换出的扇区数。条目有三个字段:major、minor 和 sectors。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数,sectors 是磁盘扇区数。
- blkio.avg_queue_size
- 此参数用于报告:群组存在的整个过程中,cgroup I/O 操作的平均队列大小。每当此 cgroup 队列获得一个 timeslice 时,该队列大小都将被采样。请注意,只有系统设定了
CONFIG_DEBUG_BLK_CGROUP=y
后,此报告才可用。 - blkio.group_wait_time
- 此参数用于报告 cgroup 中每一个队列等待 timeslice 的总时间(单位为纳秒:ns)。每当 cgroup 队列获得一个 timeslice 时,此报告就会被更新,因此如果您在 cgroup 等待 timeslice 时读取伪文件,该报告将不会包含当前队列等待操作的时间。请注意,只有系统设定了
CONFIG_DEBUG_BLK_CGROUP=y
后,此报告才可用。 - blkio.empty_time
- 此参数用于报告:没有任何等待处理的请求时,cgroup 花费的总时间(单位为纳秒:ns)。每当 cgroup 的列队有等待处理的请求时,报告都会被更新,因此如果您在 cgroup 没有任何等待处理的请求时读取此伪文件,该报告将不会包含消耗在当前空状态中的时间。请注意,只有系统设定了
CONFIG_DEBUG_BLK_CGROUP=y
后,此报告才可用。 - blkio.idle_time
- 此参数用于报告:当一个请求比其它队列或者其它群组的请求更好时,调度程序让 cgroup 闲置所消耗的总时间(单位为纳秒:ns)。每当该群组不处于闲置状态时,该报告就会被更新。因此如果您在 cgroup 闲置时读取该伪文件,该报告将不会包含消耗在当前闲置状态的时间。请注意,只有系统设定了
CONFIG_DEBUG_BLK_CGROUP=y
后,此报告才可用。 - blkio.dequeue
- 此参数用于报告 cgroup 的 I/O 操作请求被具体设备从队列中移除的次数。条目有三个字段:major、minor 和 number。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数,number 是该群组的请求被移除的次数。请注意,只有系统设定了
CONFIG_DEBUG_BLK_CGROUP=y
后,此报告才可用。 - blkio.io_serviced
- 此参数用于报告 cgroup 根据 CFQ 调度程序在具体设备中执行的 I/O 操作数。条目有四个字段:major、minor、operation 和 number。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数,operation 代表操作类型(
read
、write
、sync
或者async
),number 代表操作次数。 - blkio.io_service_bytes
- 此参数用于报告 cgroup 根据 CFQ 调度程序转换到具体设备或者由具体设备中转出的字节数。条目有四个字段:major、minor、operation 和 bytes。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数,operation 代表操作类型(
read
、write
、sync
或者async
),bytes 表示转换的字节数。 - blkio.io_service_time
- 此参数用于报告 cgroup 根据 CFQ 调度程序在具体设备中执行 I/O 操作时,发送请求到完成请求的时间。条目有四个字段:major、minor、operation 和 time。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数。operation 表示操作类型(
read
、write
、sync
或者async
),time 表示时间长度,单位为纳秒(ns)。此处使用纳秒而不是较大的单位,是为了对固态设备报告也有意义。 - blkio.io_wait_time
- 此参数用于报告 cgroup 在指定设备中执行 I/O 操作时,在调度程序队列中等待服务的总时间。当您解读该报告时,请注意:
- 报告的时间可能比消耗的时间长,因为报告的时间是该 cgroup 所有 I/O 操作的总和,而不是该 cgroup 本身等待 I/O 操作的时间。要查找该群组作为整体的等待时间,请使用
blkio.group_wait_time
参数。 - 如果设备包含
queue_depth
> 1,则报告只包括向该设备发送请求之前的时间,而不包括该设备将请求重新排序时等待服务的时间。
条目有四个字段:major、minor、operation 和 time。major 和 minor 是〈Linux 分配的设备〉指定的设备类型和节点数,operation 表示操作类型(read
、write
、sync
或者async
),time 表示时间长度,单位为纳秒(ns)。此处使用纳秒而不是较大的单位,是为了对固态设备报告也有意义。 - blkio.io_merged
- 此参数用于报告 cgroup 将 BIOS 请求合并到 I/O 操作请求的次数。条目有两个字段:number 和 operation。number 是请求次数,operation 表示操作类型(
read
、write
、sync
或者async
)。 - blkio.io_queued
- 此参数用于报告 cgroup 排队请求 I/O 操作的次数。条目有两个字段:number 和 operation。number 是请求次数,operation 表示操作类型(
read
、write
、sync
或者async
)。
A.1.4. 示例应用
例 A.1. blkio 权重分配
- 挂载
blkio
子系统:~]#
mount -t cgroup -o blkio blkio /cgroup/blkio/
- 为
blkio
子系统创建两个 cgroup:~]#
mkdir /cgroup/blkio/test1/
~]#mkdir /cgroup/blkio/test2/
- 在之前创建的 cgroup 设定不同
blkio
权重:~]#
echo 1000 > /cgroup/blkio/test1/blkio.weight
~]#echo 500 > /cgroup/blkio/test2/blkio.weight
- 创建两个大文件:
~]#
dd if=/dev/zero of=file_1 bs=1M count=4000
~]#dd if=/dev/zero of=file_2 bs=1M count=4000
以上指令所建的文件大小是 4 GB(file_1
和file_2
)。 - 对每个测试 cgroup ,在一个大文件中执行
dd
指令(该指令可以读取文件内容,并将其输出到空设备):~]#
cgexec -g blkio:test1 time dd if=file_1 of=/dev/null
~]#cgexec -g blkio:test2 time dd if=file_2 of=/dev/null
两个指令在结束后都会输出完成时间。 - 您可以使用 iotop 实用工具实时监控两个同时运行的
dd
线程。要安装 iotop 实用工具,请以 root 身份执行yum install iotop
指令。运行之前启动的dd
线程时,您可以在 iotop 实用工具中看到以下结果示例:Total DISK READ: 83.16 M/s | Total DISK WRITE: 0.00 B/s TIME TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND 15:18:04 15071 be/4 root 27.64 M/s 0.00 B/s 0.00 % 92.30 % dd if=file_2 of=/dev/null 15:18:04 15069 be/4 root 55.52 M/s 0.00 B/s 0.00 % 88.48 % dd if=file_1 of=/dev/null
为获得例 A.1 “blkio 权重分配”最准确的结果,请优先执行
dd
指令、清除所有文件系统缓存并使用下列指令释放缓存页、目录项和索引节点:
~]#sync
~]#echo 3 > /proc/sys/vm/drop_caches
您可以启用“群组隔离”,它能使用吞吐量来提供更稳定的群组隔离。当群组隔离被禁用,只有工作量是顺序时,公平才能实现。默认情况下,群组隔离是启用状态,这样即便 I/O 工作量随机也可以保证公平。如要启用群组隔离,请执行下列指令:
~]# echo 1 > /sys/block/<disk_device>/queue/iosched/group_isolation
其中,<disk_device> 代表所需设备名称,例如:
sda
。