Cgroup blkio简介和测试(使用fio测试)

因需要对docker镜像内的进程对磁盘读写的速度进行限制,研究了下Cgroup blkio,并使用fio对其iops/bps限速进行测试。

Cgroup blkio简介

Linux Cgroup(Control Groups)是Linux内核提供的用于限制、记录、隔离进程组可以使用的资源(cpu、memory、IO等)的一种机制。

在/boot下面的对应config文件里查看Cgroup内核选项:

CONFIG_BLK_CGROUP=y
CONFIG_BLK_DEV_THROTTLING=y

blkio子系统

Cgroup里每个子系统(SubSystem)对应一种资源,Cgroup blkio子系统用于限制块设备I/O速率。

挂载Cgroup root目录以及blkio子系统如下所示:

mount -t tmpfs cgroup_root /sys/fs/cgroup
mkdir /sys/fs/cgroup/blkio
mount -t cgroup -o blkio none /sys/fs/cgroup/blkio

在对应的子系统目录下通过mkdir创建资源组,rmdir可将对应资源组删除。通过将进程pid加入到资源组目录下的tasks文件的方式把某个进程加入到对应资源组。如下所示:

mkdir /sys/fs/cgroup/blkio/test
echo 9527 > /sys/fs/cgroup/blkio/test/tasks

blkio资源限制策略

blkio支持两种IO资源限制策略:IO调度权重和iops/bps限制

  1. IO调度权重

通过设置资源组IO的权重比例实现IO限制,该策略基于CFQ调度算法(Linux内核磁盘IO电梯算法)通过分配其IO处理的时间片来实现,因此需要确认磁盘对应的电梯算法为CFQ(Linux默认值)。

单个资源组权重取值范围100-1000。设置方法如下:

echo 500 > blkio.weight
echo "8:0 500" > blkio.weight_device

其中8:0为磁盘设备号(major:minor)。具体设备的weight_device权重的优先级高于weight默认权重。

IO调度权重使用CFQ调度算法,显得比较公平,其保障资源组最低的IO比例(对应iops有最低保证)。在设备空闲的时候,还能超限使用。因此不适用于需要严格限制资源组IO资源上限的场景。

  1. iops和bps限制

支持设置资源组读和写的iops、bps上限。这样在该资源组内的进程读写IO的iops和bps不会超出设置值。设置方法如下:

echo "8:0 102400" > blkio.throttle.read_bps_device
echo "8:0 10" > blkio.throttle.read_iops_device
echo "8:0 204800" > blkio.throttle.write_bps_device
echo "8:0 20" > blkio.throttle.write_iops_device

其中读bps限定在100KB,读iops限定在10。可以只设置读或者写的iops,或者bps,也可以都设置。

相比IO调度权重,iops和bps限制更加直接和量化,更适合用于限制docker容器磁盘IO上限。

使用fio测试blkio

当前3.3版本的fio支持配置cgroup进行测试,但只支持配置cgroup的weight值。

为了测试blkio iops/bps限制,在该版本fio基础上,添加了支持配置iops/bps的代码。可从github上直接下载编译修改后的fio

blkio iops/bps功能测试

使用fio启动两个进程分属两个Cgroup进行blkio功能测试,fio配置文件如下:

[root@A03-R14-I156-1 jimbo]# cat test.fio
[global]
bs=4K
ioengine=libaio
iodepth=32
direct=1
rw=randrw
rwmixread=50
time_based
runtime=60
cgroup_nodelete=0 [test1]
filename=/export/kubelet/pods/802b34b1-eac7-11e7-bc92-246e9665d1b0/volumes/kubernetes.io~lvm/export/fio/test1.img
size=512M
cgroup_read_iops=8:16 100
cgroup_write_iops=8:16 100
cgroup_read_bps=8:16 1024000
cgroup_write_bps=8:16 1024000
cgroup=test1 [test2]
filename=/export/kubelet/pods/802b34b1-eac7-11e7-bc92-246e9665d1b0/volumes/kubernetes.io~lvm/export/fio/test2.img
size=512M
cgroup_read_iops=8:16 1000
cgroup_write_iops=8:16 1000
cgroup_read_bps=8:16 102400
cgroup_write_bps=8:16 102400
cgroup=test2

其中Cgroup设备号需要设置为物理磁盘(如sdb)或者lvm卷(如dm-5)的设备号,设置为磁盘分区(如sdb1)设备号或者loop设备号时是无效的。

对于docker镜像使用lvm磁盘时,测试结果显示设置设备号为lvm盘和物理磁盘的限速效果是一样的。

如果将bs设置过大,会导致buffered read/write时大量的IO在缓存命中,并没有实际提交给磁盘,此时fio的统计的iops/bps是不准的。

所以本次测试设置bs=4K,尽量避免缓存命中的情况发生。

启动fio测试:

[root@A03-R14-I156-1 jimbo]# ./fio ./test.fio

可直接查看fio输出读写IOPS和BW统计,需要注意有些场景(如buffered write)fio的输出并不准确,还需要结合iostat等磁盘统计工具进一步确认磁盘iops/bps的真实情况。

fio的输出如下:

test1: (groupid=0, jobs=1): err= 0: pid=619842: Fri Dec 29 16:28:41 2017
read: IOPS=98, BW=392KiB/s (402kB/s)(23.0MiB/60109msec)
...
write: IOPS=99, BW=396KiB/s (406kB/s)(23.3MiB/60109msec)
...
test2: (groupid=0, jobs=1): err= 0: pid=619843: Fri Dec 29 16:28:41 2017
read: IOPS=23, BW=94.7KiB/s (96.0kB/s)(5768KiB/60917msec)
...
write: IOPS=25, BW=100KiB/s (103kB/s)(6100KiB/60917msec)
...

可以看到test1被IOPS限制在了100,test2被bps限制在了100KiB/s。

使用该方法测试了randread、randwrite、randrw结果如下:

  • DIO read、DIO write、buffered read都被成功限制住了iops/bps;
  • buffered write却并没有被限制住;

Buffered write没有被限制住,是因为本次测试基于CentOS 7.2内核版本号为3.10.0,该版本内核blkio有如下描述:

Currently only sync IO queues are support. All the buffered writes are still system wide and not per group. Hence we will not see service differentiation between buffered writes between groups.

从YY哥分析的Buffer IO的throttle问题可以看到buffered写IO在内核异步线程提交时无法获取到用户进程信息,因此blkio无法支持buffered write的统计。该问题在4.2版本的Cgroup V2上得到了解决,该版本Cgroup相比V1做了很大改进并支持了writeback。详情可参看博客Cgroup V2 and writeback support

blkio压力测试

通过如下脚本测试在同一个资源组上启动N个fio进程进行blkio压力测试:

#!/bin/bash

for ((N=0; N<100; N++))
do
./fio -filename=/export/kubelet/pods/802b34b1-eac7-11e7-bc92-246e9665d1b0/volumes/kubernetes.io~lvm/export/fio/test$N.img -size=256M -rw=randrw -ioengine=libaio -iodepth=32 -bs=4K -direct=1 -rwmixread=50 -time_based -runtime=60 -cgroup_nodelete=0 -cgroup=test -cgroup_read_iops="8:16 10000" -cgroup_write_iops="8:16 10000" -cgroup_read_bps="8:16 10240000" -cgroup_write_bps="8:16 10240000" -name=test$N -output=./output$N &
done sleep 60

测试结果显示,N=100个进程测试时,所有IO总和都被限定在了test资源组设置的iops和bps下。

修改上述脚本中-cgroup=test-cgroup=test$N,即可进行在N个资源组上启动N个fio进程进行blkio压力测试。

测试结果显示,当IO超出物理磁盘的能力时,每个资源组上的进程都无法达到iops和bps的限制,基本上比较平均的占用磁盘带宽。

Cgroup blkio简介和测试(使用fio测试)的更多相关文章

  1. 硬盘测试工具fio用法总结

    一  fio介绍 linux下的一种常用的磁盘测试工具,支持裸盘和文件形式进行测试   二  硬盘测试常用名词 延迟:io的发起到返回写入成功的时间成为延迟,fio中延迟分为lat,slat,clat ...

  2. 云计算&存储测试:FIO工具入门与实战

    一.关于FIO 1.1 简介 FIO是一个开源的I/O压力测试工具,主要是用来测试磁盘的IO性能,也可测试cpu,nic的IO性能.它可以支持13种不同的I/O引擎,包括:sync,mmap, lib ...

  3. linux使用FIO测试磁盘的iops 【转载】

     linux使用FIO测试磁盘的iops 2013-09-23 10:59:21 分类: LINUX FIO是测试IOPS的非常好的工具,用来对硬件进行压力测试和验证,支持13种不同的I/O引擎,包括 ...

  4. IdentityServer4 中文文档 -6- (简介)示例服务器和测试

    IdentityServer4 中文文档 -6- (简介)示例服务器和测试 原文:http://docs.identityserver.io/en/release/intro/test.html 目 ...

  5. 使用FIO测试磁盘iops

    我们如何衡量一个存储的性能呢?IOPS(Input/Output OperationsPer Second),即每秒进行读写(I/O)操作的次数是国际上通用的存储性能衡量标准,IOPS越高意味着在同一 ...

  6. fio 测试磁盘

    root@rook-test:/# ceph osd status+----+-----------------------------+-------+-------+--------+------ ...

  7. [记录]FIO测试磁盘iops性能

    FIO测试磁盘iops性能 1.SATA和SAS盘原生IOPS如下: 2.RAID磁盘阵列对应的写惩罚级别: 3.计算功能性IOPS公式如下: 功能性 IOPS=(((总原生 IOPS×写 %))/( ...

  8. CentOS中使用FIO测试磁盘IO性能

    $ yum install fio 0x02 命令 随机读: $ fio -filename=/dev/sda1 -direct=1 -iodepth 1 -thread -rw=randread - ...

  9. fio测试ceph的filestore

    前言 fio是一个适应性非常强的软件,基本上能够模拟所有的IO请求,是目前最全面的一款测试软件,之前在看德国电信的一篇分享的时候,里面就提到了,如果需要测试存储性能,尽量只用一款软件,这样从上层测试到 ...

随机推荐

  1. 通过pip3安装virtualenvwrapper

    pip3 install virtualenvwrapper 配置virtualenvwrapper创建虚拟环境的目录和指定python3版本 环境编辑当前用户配置变量 mkdir ~/.virtua ...

  2. help手册使用

    属性的方法名的一般规律: 设置的属性名: set+属性名 获取属性值: 1.如果是bool类型,可能是 is+属性名 或者 属性名 2.不是bool类型,就是属性名

  3. CHNS类

    NS类集合介绍 1.常用部分 NSDictionary NSString NSArray 数组 NSTimer 定时器 NSRange 范围 NSNotification 2.网络相关 NSURLCo ...

  4. java volatile 关键字(转)

    volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...

  5. c++编码规范(摘录)

    在同一项目组应明确规定对接口函数参数的合法性检查应由函数的调用者负责还是由接口函数本身负责,缺省是由函数调用者负责. 函数的规模尽量限制在200行以内.说明:不包括注释和空格行. 一个函数仅完成一件功 ...

  6. 查看ip常见命令...

    1.获取ip Unix用户可以在命令提示符中输入ifconfig来获取. 使用Windows的用户,请尝试使用 ipconfig 命令.

  7. C++基础学习10:继承

    继承是类与类之间的关系,是一个很简单很直观的概念,与现实世界中的继承(例如儿子继承父亲财产)类似. 继承可以理解为一个类从另一个类获取方法(函数)和属性(成员变量)的过程.如果类B继承于类A,那么B就 ...

  8. appium键盘处理

    最近对appium感兴趣,就从网上找了些资料,搭建了环境,下载了appium测试代码和测试apk,这方面的东西晚上再写 appium最新版(v1.4.0.0)已经没有sendKeyEvent了,所以现 ...

  9. Codeforces-D-Diverse Garland(思维)

    You have a garland consisting of nn lamps. Each lamp is colored red, green or blue. The color of the ...

  10. appium ios 真机自动化环境搭建

    近期由于工作需要,本小菜在弄appium+ios+iphone真机的移动自动化,在网上找寻各种资料,发现针对IOS方面的资料少之又少,公司其它部门的弄过的同事也寥寥无几,即使有,也是安卓方面的.本次书 ...