美文网首页
[043][译]blkio-controller.txt

[043][译]blkio-controller.txt

作者: 王小二的技术栈 | 来源:发表于2020-03-22 20:51 被阅读0次

    前言

    Linux之父曾说过read the fucking source code。在学习linux的过程中,我觉得read the fucking document也非常的重要,今天又花了几个小时的时间,翻译了一下blkio-controller.txt,对cgroup如何控制IO有了大概的一个了解,当然有些细节还需要进一步的验证,我会继续努力。

    翻译

                    Block IO 控制
                    ===================
    概述
    ========
    cgroup子系统“blkio”实现块io控制器。在存储层次结构中叶节点和中间节点,
    似乎需要各种IO控制策略(如比例BW(bandwidth)、最大BW)
    计划:为blkio控制器使用基于cgroup的相同管理接口,并基于用户选项在后台切换IO策略。               
    
    目前实现了两个IO控制策略。
    第一个是成比例的基于权重时间的磁盘分区策略。它在CFQ中实现。因此
    此策略仅在使用CFQ时对叶节点生效。
    第二个是一种是限制策略,可用于指定在设备上IO速率上限。
    此策略在通用块层中实现,可以是用于叶节点以及更高级别的逻辑设备,如设备映射器。
    
    怎么做
    =====
    1.带宽比例权分
    -----------------------------------------
    你可以做一个简单的测试,跑两个运行dd线程在不同的cgroups, 这里就是你能做的。
    
    - 开启Block IO控制
        CONFIG_BLK_CGROUP=y
    
    - 开启group scheduling在CFQ调度算法中
        CONFIG_CFQ_GROUP_IOSCHED=y
    
    - 编译启动进入kernel挂在IO controller (blkio); 参考文档cgroups.txt, 为什么cgroups是必须的?.
        mount -t tmpfs cgroup_root /sys/fs/cgroup
        mkdir /sys/fs/cgroup/blkio
        mount -t cgroup -o blkio none /sys/fs/cgroup/blkio
    
    - 创建两个cgroups
        mkdir -p /sys/fs/cgroup/blkio/test1/ /sys/fs/cgroup/blkio/test2
    
    - 设置test1和test2两个组的权重
        echo 1000 > /sys/fs/cgroup/blkio/test1/blkio.weight
        echo 500 > /sys/fs/cgroup/blkio/test2/blkio.weight
    
    - 创建两个相同文件的大小 (512MB)在同一个硬盘上(file1, file2),启动两个dd线程在不同的cgroup读取文件
        
        sync
        echo 3 > /proc/sys/vm/drop_caches
    
        dd if=/mnt/sdb/zerofile1 of=/dev/null &
        echo $! > /sys/fs/cgroup/blkio/test1/tasks
        cat /sys/fs/cgroup/blkio/test1/tasks
    
        dd if=/mnt/sdb/zerofile2 of=/dev/null &
        echo $! > /sys/fs/cgroup/blkio/test2/tasks
        cat /sys/fs/cgroup/blkio/test2/tasks
    
    在宏观层面,第一个dd应该先完成。为了获得更精确的数据,我们可以查看test1和test2组中的
    blkio.disk_time和blkio.disk_扇区文件。可以说明磁盘时间(以毫秒为单位),多少个扇区
    发送到磁盘。我们提供公平的磁盘时间,所以理想情况下,cgroup的io.disk_时间应与权重成比例。
    
    限制(throttling)/上限策略
    -----------------------------
    - 开启Block IO控制
        CONFIG_BLK_CGROUP=y
    
    - 开启限制在block layer
        CONFIG_BLK_DEV_THROTTLING=y 
    
    - 挂在IO controller (blkio); 参考文档cgroups.txt, 为什么cgroups是必须的?. 
        mount -t cgroup -o blkio none /sys/fs/cgroup/blkio
    
    - 为root group,指定特定设备上的带宽速率。
      策略格式"<major>:<minor>  <bytes_per_second>"
    
      echo "8:16  1048576" > /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device
      上面会限速1MB/s,root group在8:16设备上发生读操作
    
    - 运行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层级
    ====================
    CFQ和限制(throttling)都支持实现层次结构;但是,如果"sane_behavior"是从cgroup端启用,当前是一个开发选项,并且
    不公开。
    
    如果某人创建以下的层级:
    
                root
                /  \
                 test1 test2
                |
                 test3
    
    默认的CFQ和限制(throttling)使用"sane_behavior"将处理层次结构正确。有关CFQ层次结构支持的详细信息,
    请参阅文档/block/cfq-iosched.txt。对于限制(throttling),所有限制都适用对整个子树,而所有统计数据
    都会在cgroup中的task直接生成IO。
    
    如果不从cgroup端启用"sane_behavior",限制(throttling)实际上对待所有组一个级别
    
    
                    pivot
                     /  /   \  \
                root  test1 test2  test3
    
    各种用户可见的配置选项
    ===================================
    CONFIG_BLK_CGROUP
        - Block IO controller的总开关.
    
    CONFIG_DEBUG_BLK_CGROUP
        - 如果开启这个选项
    
    CONFIG_CFQ_GROUP_IOSCHED
        - 开启CFQ中的分组调度,目前只支持创建一级的组
    
    CONFIG_BLK_DEV_THROTTLING
        - 开启block layer中的块设备的限制(throttling)
    
    
    cgroup文件的详细信息
    =======================
    比例权重策略文件
    --------------------------------
    - blkio.weight
        - 指出每一个cgroup的权重,所有设备上用同一个权重值,除非每个设备写一个规则覆盖
          (看blkio.weight_device).
          当前允许的权重从10到1000.
    
    - blkio.weight_device
        - 指出每一个cgroup每一个设备的权重使用这个接口
          这些规则将会覆盖blkio.weight
    
          格式如下:
    
          # echo dev_maj:dev_minor weight > blkio.weight_device
          为这个cgroup在设备/dev/sdb (8:16)配置weight=300
          # echo 8:16 300 > blkio.weight_device
          # cat blkio.weight_device
          dev     weight
          8:16    300
    
          为这个cgroup在设备/dev/sdb (8:0)配置weight=500
          # echo 8:0 500 > blkio.weight_device
          # cat blkio.weight_device
          dev     weight
          8:0     500
          8:16    300
    
          移除这个cgroup在设备/dev/sdb (8:0)配置的weight
          # echo 8:0 0 > blkio.weight_device
          # cat blkio.weight_device
          dev     weight
          8:16    300     
    
    - blkio.leaf_weight[_device]
        - blkio.weight[_device]价值在于为了决定多少权重任务在给定的cgroup,并且和子cgroup有竞争关系
          关于细节,请参考文档/block/cfq-iosched.txt。
    
    - blkio.time
        - 分配给每个设备的cgroup的磁盘时间(毫秒)。
          首先两个字段指定设备的主要和次要编号,第三个字段指定分配给组的磁盘时间毫秒。
    
    - blkio.sectors
        - 当前group传输到/从磁盘的扇区数。
          首两个字段指定设备的主要和次要编号,第三个字段指定传输到/从磁盘的扇区数。
    
    - blkio.io_service_bytes
        - 当前group传输到/从磁盘传输的字节数。这些按操作类型进一步划分-读或写、同步或者异步。
          前两个字段指定设备的主要和次要编号,第三个字段指定操作类型和第四个字段指定字节数。
    
    - blkio.io_serviced
        - 当前group发给磁盘的IOs(bio)数。这些按操作类型进一步划分-读或写、同步或者异步。
          前两个字段指定设备的主要和次要编号,第三个字段指定操作类型和第四个字段指定操作的数量。
    
    - blkio.io_service_time
        - 当前group所做的IOs从请求发送到请求完成之间的总时间量。以纳秒计算对闪存设备也有意义。
          当队列深度为1的设备,此时间表示实际服务时间。当队列深度大于1时,这不再是正确的,
          因为请求可能会被无序地送达。这个时间将会包括多个IO的服务时间,当服务不正常时,可能会导致
          io_service_time大于实际运行时间。这个时间按操作类型进一步划分、同步或者异步
          前两个字段指定设备的主要和次要编号,第三个字段指定操作类型,第四个字段指定服务时间(ns)。
    
    - blkio.io_wait_time
        - 当前group的IOs在服务调度队列花费的等待时间,这可能大于总时间已用,因为它是所有io的累计io等待时间。
          它不是衡量cgroup等待的总时间,而是衡量等待其个别IOs的时间。对于队列深度大于1的设备此指标不包括
          等待服务一次所花费的时间IO被发送到设备,但直到它真正得到服务(由于设备)。这是以纳秒为单位的,
          以使它对flash有意义设备也是。这个时间是按操作类型进一步划分,读或写,同步或异步。
          前两个字段指定设备的主要和次要编号,第三个字段指定操作类型
          第四个字段以ns为单位指定io_wait_时间。
    
    - blkio.io_merged
        - 合并到属于这个cgroup的requests的bios/requests总数
          按操作类型进一步划分,读或写,同步或异步
    
    - blkio.io_queued
        - 当前cgroup,在任何给定时刻排队的请求总数。
          按操作类型进一步划分,读或写,同步或异步
    
    - blkio.avg_queue_size
        - 仅会在CONFIG_DEBUG_BLK_CGROUP=y启用调试辅助
          在此期间,此cgroup的平均队列大小。 队列大小事例被用于得到每次此cgroup的队列获取时间间隔
    
    - blkio.group_wait_time
        - 仅会在CONFIG_DEBUG_BLK_CGROUP=y启用调试辅助
          这是cgroup自忙起必须等待的时间(即,从0到排队的1个请求)获取其中一个的时间间隔
          给它的队列。这不同于io_wait_time,后者是该cgroup中每个io在调度程序队列中等待的时间的累计总和。
          以纳秒为单位。 如果在cgroup处于等待态时读取此值, 统计将只报告组等待时间累计到最后一次
          已获取时间间隔,将不包括当前增量
    
    - blkio.empty_time
        - 仅会在CONFIG_DEBUG_BLK_CGROUP=y启用调试辅助
          这是cgroup在未被服务时,在没有任何挂起的请求的情况下花费的时间量, 即, 不包括任何时间
          为cgroup的某个队列花费的空闲时间. 以纳秒为单位,如果在cgroup处于空状态时读取此值,
          统计将只报告在上次有一个挂起的请求之前累积的空时间,而不包括当前的增量
    
    - blkio.idle_time
        - 仅会在CONFIG_DEBUG_BLK_CGROUP=y启用调试辅助
          这是时间的总计,给定cgroup中,IO调度程序比现有请求更好的请求其他队列/cgroup中的而空闲的时间量。
          以纳秒为单位,如果在cgroup处于空闲状态时读取此值,统计将只报告到最后一个空闲周期为止累积的空闲时间,而不包括当前增量。
    
    - blkio.dequeue
        - 仅会在CONFIG_DEBUG_BLK_CGROUP=y启用调试辅助 This
          提供从设备的服务树有关一个组退出队列的次数的统计信息
          前两个字段指定设备的主要和次要编号,第三个字段指定退出队列的次数
    
    
    - 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
        - 按组分到的磁盘的IOs(bio)数. 这个按操作类型进一步划分、同步或者异步
          首先两个字段指定设备的主要和次要编号,
          第三个字段指定操作类型
          第四个字段指定IOs数
    
    - blkio.throttle.io_service_bytes
        - 按组传输到/从磁盘传输的字节数. 这个按操作类型进一步划分、同步或者异步
          首先两个字段指定设备的主要和次要编号,
          第三个字段指定操作类型
          第四个字段指定字节数
    
    
    各种策略之间的公共文件
    -----------------------------------
    - blkio.reset_stats
        - 将int值写入此文件将导致重置这个组的所有统计信息。
    
    CFQ sysfs 调整
    =================
    /sys/block/<disk>/queue/iosched/slice_idle
    ------------------------------------------
    在更快的硬件上,CFQ可能会很慢,特别是在连续工作负载的情况下。这是因为CFQ在单个队列上空闲,
    而单个队列可能不驱动更深的请求队列深度以保持存储繁忙。
    在这种情况下可以尝试设置slice_idle=0,这将把CFQ切换到IOPS(每秒IO操作)模式在支持NCQ的硬件。
    
    这意味着CFQ不会在CFQ组和CFQ队列之间空闲,因此能够驱动更高的队列深度,获得更好的吞吐量。
    那也意味着cfq在IOPS方面提供了组间的公平性,而不是在磁盘时间条款。
    
    对于SSD设备,可以将这个值设为 0(我自己查的资料)
    
    /sys/block/<disk>/queue/iosched/group_idle
    ------------------------------------------
    如果通过设置slice_idle=0禁用单个cfq队列和cfq服务树上的空闲
    ,group_idle启动。这意味着CFQ仍将处于闲置状态,试图在群体间提供公平。
    
    默认,group_idle和slice_idle一样,在slice_idle开启的情况下,什么都不做
    
    如果您创建了多个组,将驱动力不足的应用程序放入该组IO使磁盘保持忙碌,总吞吐量可能会下降。
    在这种情况下,设置group_idle=0,CFQ将不空闲对单个组和吞吐量应该提高。
    

    相关文章

      网友评论

          本文标题:[043][译]blkio-controller.txt

          本文链接:https://www.haomeiwen.com/subject/pxikyhtx.html