zoukankan      html  css  js  c++  java
  • Cgroup内核文档翻译(2)——Documentation/cgroup-v1/blkio-controller.txt

    Block IO Controller
    ===================

    总览
    ========
    cgroup子系统 "blkio" 实现了块io控制器。 在存储层次结构中的叶节点以及中间节点处似乎都需要各种类型的IO控制策略(如比例BW,最大BW)。 计划是将相同的基于cgroup的管理界面用于blkio控制器,并根据用户选项在后台切换IO策略。

    当前,已实施两种IO控制策略。 第一个是基于比例权重时间的磁盘策略划分。 它在CFQ中实现。 因此,当使用CFQ时,此策略仅对叶节点有效。 第二个是限制策略,可用于指定设备上的IO速率上限。 该策略在通用块层中实现,可以在叶节点以及更高级别的逻辑设备(例如设备映射器)上使用。


    如何做
    =====
    带宽比例权重划分
    -----------------------------------------
    您可以对在两个不同的cgroup中运行两个dd线程进行非常简单的测试。 这是您可以做的。

    -启用块IO控制器
        CONFIG_BLK_CGROUP = y
    
    -在CFQ中启用组调度
        CONFIG_CFQ_GROUP_IOSCHED = y
    
    -编译并在内核中启动,并挂载IO控制器(blkio); 请参阅cgroups.txt,为什么需要cgroup ?。
        mount -t tmpfs cgroup_root /sys/fs/cgroup
        mkdir /sys/fs/cgroup/blkio
        mount -t cgroup -o blkio none /sys/fs/cgroup/blkio
    
    -创建两个cgroup
        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
    
    -在同一磁盘上创建两个大小相同的文件(文件1,文件2,每个文件512 MB),并在不同的cgroup中启动两个dd线程去读取这些文件。
    
        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_sectors 文件。 这将告诉每个组获得了多少磁盘时间(以毫秒为单位),每个组向磁盘派发了多少个扇区。 我们提供磁盘时间方面的公平性,因此理想情况下 cgroups 的 io.disk_time 应该与权重成比例。

    节流/上限策略
    -----------------------------

    -启用块IO控制器
        CONFIG_BLK_CGROUP=y
    
    -在块层启用节流
        CONFIG_BLK_DEV_THROTTLING=y
    
    -挂载blkio控制器(请参阅cgroups.txt,为什么需要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
    
    上面将对 major/minor设备号为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 文件对写入速率进行限制。

    分层Cgroup
    ====================

    CFQ和节流策略都实现了对层次结构的支持; 但是,如果从 cgroup 端启用了“sane_behavior”,则启用了节流的层次结构支持,
    当前这是开发选项,并且不公开。

    如果有人创建了如下的层次结构。

            root
            /  
          test1 test2
            |
          test3

    默认情况下,CFQ并使用“sane_behavior”进行限制将正确处理层次结构。 有关CFQ层次结构支持的详细信息,请参阅 Documentation/block/cfq-iosched.txt。 对于节流,所有限制都适用于整个子树,而所有统计信息对于该cgroup中的任务直接生成的IO都是本地的。

    在没有从cgroup端启用“sane_behavior”的情况下,进行节流实际上会将所有组视为相同级别,就像以下所示。

               pivot
           /   /      
        root test1 test2 test3

    各种用户可见的配置选项
    ==================================

    CONFIG_BLK_CGROUP
        -块IO控制器。
    
    CONFIG_DEBUG_BLK_CGROUP
        -调试帮助信息。现在,如果启用了此选项,则cgroup中会显示一些其他统计信息文件。
    
    CONFIG_CFQ_GROUP_IOSCHED
        -在CFQ中启用组调度。 当前仅允许创建1级group。
    
    CONFIG_BLK_DEV_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
          Configure weight=300 on /dev/sdb (8:16) in this cgroup
          # echo 8:16 300 > blkio.weight_device
          # cat blkio.weight_device
          dev     weight
          8:16    300
    
          Configure weight=500 on /dev/sda (8:0) in this cgroup
          # echo 8:0 500 > blkio.weight_device
          # cat blkio.weight_device
          dev     weight
          8:0     500
          8:16    300
    
          Remove specific weight for /dev/sda in this cgroup
          # 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竞争时给定cgroup中任务的权重。 有关详细信息,请参阅 Documentation/block/cfq-iosched.txt.。

    -blkio.time
      -每个设备分配给cgroup的磁盘时间(以毫秒为单位)。 前两个字段指定设备的主设备号和次设备号,第三个字段指定分配给组的磁盘时间(以毫秒为单位)。

    -blkio.sectors
      -此组从磁盘传输或接收的扇区数。前两个字段指定设备的主设备号和次设备号,第三个字段指定组向设备/从设备传输的扇区数。

    -blkio.io_service_bytes
      -组从磁盘传输的或接收的字节数。这些操作按操作类型进一步划分-读取或写入,同步或异步。 前两个字段指定设备的主要和次要设备号,第三个字段指定操作类型,第四个字段指定字节数。

    -blkio.io_serviced
      -该组向磁盘发出的IO(bio)数量。 这些操作按操作类型进一步划分-读取或写入,同步或异步。 前两个字段指定设备的主次设备号,第三个字段指定操作类型,第四个字段指定IO的数量。

    -blkio.io_service_time
      -此cgroup完成的IO的请求分发和请求完成之间的总时间。 这在1ns内对闪存设备也很有意义。 对于队列深度为1的设备,此时间表示实际服务时间。 当 queue_depth > 1时,这不再是正确的,因为可能会无序地处理请求。 这可能会导致给定IO的服务时间在无序提供时包括多个IO的服务时间,这可能导
    致总 io_service_time > 实际时间。 该时间还可以通过操作类型进一步划分-读或写,同步或异步。 前两个字段指定设备的主设备号和次设备号,第三个字段指定操作类型,第四个字段指定以ns为单位的io_service_time。

    -blkio.io_wait_time
      -此cgroup的IO在调度程序队列中等待服务的总时间。这可以大于所花费的总时间,因为它是所有IO的累积 io_wait_time。 它不是衡量 cgroup 等待总时间的方法,而是衡量各个IO的 wait_time 的方法。对于 queue_depth> 1的设备,此指标不包括将IO分配给设备后等待服务所花费的时间,但直到它得到实际服务为止(由于设备对请求的重新排序,因此可能会有时间滞后)。 这在1ns内对闪存设备也很有意义。 该时间还可以通过操作类型进一步划分-读或写,同步或异步。 前两个字段指定设备的主设备号和次设备号,第三个字段指定操作类型,第四个字段指定以ns为单位的 io_wait_time。

    -blkio.io_merged
      -合并到属于此cgroup的请求的bios/requests总数。 这可以通过操作类型进一步划分-读或写,同步或异步。

    -blkio.io_queued
      -在任何给定时刻为此cgroup排队的请求总数。 这可以通过操作类型进一步划分-读或写,同步或异步。

    -blkio.avg_queue_size
      -仅在 CONFIG_DEBUG_BLK_CGROUP = y 时启用的调试辅助。 在此cgroup存在的整个时间内,此cgroup的平均队列大小。 每当此cgroup的队列之一获得时间片时,就对队列大小进行采样。

    -blkio.group_wait_time
      -仅在 CONFIG_DEBUG_BLK_CGROUP = y 时启用的调试帮助信息。 这是自从cgroup变得繁忙(即请求从0到1进入队列)以来为其队列之一获取时间片所必须等待的时间。 这不同于 io_wait_time,它是该cgroup中每个IO在调度程序队列中等待的时间的累积总数。以纳秒为单位。 如果在cgroup处于等待(用于时间片)状态时读取此内容,则该统计信息将仅报告直到其最后获得时间片为止所累积的 group_wait_time,并且不包括当前增量。

    -blkio.empty_time
      -仅在 CONFIG_DEBUG_BLK_CGROUP = y 时启用调试辅助信息。 这是cgroup在没有被服务时花费在没有任何未决请求的情况下的时间,即,它不包括花费在cgroup队列之一空闲上的任何时间。 以纳秒为单位。 如果在cgroup处于空状态时读取了此内容,则该统计信息将仅报告直到上一次有待处理请求为止所累积的empty_time,并且将不包括当前增量。

    -blkio.idle_time
      -仅在 CONFIG_DEBUG_BLK_CGROUP = y 时启用的调试辅助信息。 这是IO调度程序闲置给定cgroup所花费的时间,以期望比来自其他队列/cgroup的现有请求更好的请求。 以纳秒为单位。 如果在cgroup处于空闲状态时读取了此信息,则该统计信息将仅报告直到最后一个空闲时间段为止累积的idle_time,并且将不包括当前增量。

    -blkio.dequeue
      -仅在 CONFIG_DEBUG_BLK_CGROUP = 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的数量。

    -blkio.throttle.io_service_bytes
      -组从磁盘传输到磁盘或从磁盘传输的字节数。 这些操作按操作类型进一步划分-读取或写入,同步或异步。 前两个字段指定设备的主要和次要编号,第三个字段指定操作类型,第四个字段指定字节数。

    各种政策中的通用文件
    -----------------------------------
    -blkio.reset_stats
      -将int写入此文件将导致重置该cgroup的所有统计信息。

    CFQ sysfs可调部分
    =================
    /sys/block/<disk>/queue/iosched/slice_idle
    ------------------------------------------
    在速度更快的硬件上,CFQ可能会是慢的,尤其是在顺序工作负载下。 发生这种情况是因为CFQ在单个队列上处于空闲状态,并且单个队列可能不会驱动更深的请求队列深度来保持存储繁忙。 在这种情况下,可以尝试设置 slice_idle = 0,然后在支持NCQ的硬件上将CFQ切换为IOPS(每秒IO操作)模式。

    这意味着CFQ不会在cfq组的cfq队列之间闲置,因此能够驱动更高的队列深度并获得更好的吞吐量。 这也意味着cfq根据IOPS而不是磁盘时间来提供组之间的公平性。

    /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不会在单个组上空闲,并且吞吐量应该会提高。

  • 相关阅读:
    java开发中的常见类和对象-建议阅读时间3分钟
    周末学习-泛型-就是传入什么类型就是什么类型-花了一个半小时
    实习第二天-String对象的不可变性-未解决
    实习第二天-java参数传递-精华在文章最后2句话
    实习第二天-对象-对象引用-引用变量-精-精-精-下雨天
    实习第一天:try和catch的使用
    实习第二天-今年第一场雨-方法的重载(马上想到println()函数和abs(函数))
    实习第一周第一天:接口 extends是继承类,implement是实现接口,原接口里面的方法填充,方法名也是不变,重写override是父类的方法名不变,把方法体给改了
    实习第一天:static 声明的 变量和 方法
    JavaWeb学习总结(二)-修改Tomcat服务器的端口(半年之后再总结)
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/14226290.html
Copyright © 2011-2022 走看看