尝试使用Block I/O控制器

Block I/O控制器的设置通过cgroup文件系统进行。关于Cgroup和cgroup文件系统的基本情况请参考Hack#7。

首先挂载cgroup文件。将blkio作为挂载选项,指定将Block I/O控制器作为子系统使用。


mount-t cgroup-o blkio cgroup/cgroup


然后,在CFQ中为想要控制I/O优先级的块设备设置I/O调度程序。这里使用的块设备是sdb。


echo cfq>/sys/class/block/sdb/queue/scheduler

$cat/sys/class/block/sdb/queue/scheduler

noop deadline[cfq]


这时,使用Block I/O控制器前的准备工作就完成了。为了方便讲解,在这里创建优先级较高的分组“high”和优先级较低的分组“low”,并分别向各分组分配1个进程来观察I/O的情况。首先创建分组。


mkdir/cgroup/high

mkdir/cgroup/low


对各分组设置I/O的优先级。设置优先级时,在blkio.weight中写入100~1000的“weight值”。初始值为500,值越大表示优先级越高。


echo 1000>/cgroup/high/blkio.weight

echo 100>/cgroup/low/blkio.weight


小贴士:仅根分组的weight初始值为1000。

为了进行测试,制作一个简单的脚本。这个脚本将进程添加到所指定的两个分组low和high,分别计算出读文件所需的时间。创建如下的“blkio_test.sh”脚本,并为其赋予执行权限。


!/bin/sh

blkio_test.sh

Test script for Block IO Controller

read/mnt/sdb/low.dat($flow)as cgroup$cg_low

and read/mnt/sdb/high.dat($fhigh)as cgroup$cg_high simultaneously.

#

$1:cgroup path for lower priority(—>$cg_low)

$2:cgroup path for higher priority(—>$cg_high)

function print_usage()

{

echo"usage:$0<cgroup_low><cgroup_high>"

exit 1

}

#

params and variables

flow=/mnt/sdb/low.dat

fhigh=/mnt/sdb/high.dat

cgroups to which processes will be asigned

if[$#!=2];then

print_usage

fi

cg_low=$1

cg_high=$2

for cg in$cg_low$cg_high;do

if[!-d$cg];then

echo"$cg does not exists"

print_usage

fi

done

temporary files

out_low=$(mktemp)

out_high=$(mktemp)

#

sync, drop caches and read files

echo-n"sync and drop all caches……"

sync

echo 3>/proc/sys/vm/drop_caches

echo"done"

echo-n"reading files……"

echo$$>$cg_low/tasks

(time dd if=$flow of=/dev/null)>$out_low 2>&1&

echo$$>$cg_high/tasks

(time dd if=$fhigh of=/dev/null)>$out_high 2>&1&

wait

echo"done"

#

print the results

echo"——————————"

echo"dd in$cg_low:"

cat$out_low

echo"——————————"

echo"dd in$cg_high:"

cat$out_high

rm-f$out_low$out_high


首先,在不分组的情况下进行测试。使用同属于根分组的两个进程,同时读入文件。由于脚本读入的是/mnt/sdb/low.dat、/mnt/sdb/high.dat文件,因此需要先创建两个大小适当的文件,再运行脚本。这里创建了约400MB的文件并执行相关代码。


dd if=/dev/zero of=/mnt/sdb/low.dat bs=1M count=400

dd if=/dev/zero of=/mnt/sdb/high.dat bs=1M count=400

./blkio_test.sh/cgroup/cgroup


dd in/mnt/cgroups:

819200+0 records in

819200+0 records out

419430400 bytes(419 MB)copied,14.0493 s,29.9 MB/s

real 0m14.156s

user 0m0.261s

sys 0m1.183s


dd in/mnt/cgroups:

819200+0 records in

819200+0 records out

419430400 bytes(419 MB)copied,14.2007 s,29.5 MB/s

real 0m14.292s

user 0m0.281s

sys 0m1.186s


两个进程同样使用约14秒的时间完成读入。接下来,在分组的情况下进行测试。将两个进程分别添加到low、high分组中,同时读入文件。


./blkio_test.sh/cgroup/low/cgroup/high


dd in/cgroup/low:

819200+0 records in

819200+0 records out

419430400 bytes(419 MB)copied,13.0829 s,32.1 MB/s

real 0m13.388s

user 0m0.250s

sys 0m1.208s


dd in/cgroup/high:

819200+0 records in

819200+0 records out

419430400 bytes(419 MB)copied,7.43459 s,56.4 MB/s

real 0m7.818s

user 0m0.256s

sys 0m1.209s


属于/cgroup/low的进程完成文件读入耗费约13秒,而属于/cgroup/high的进程完成读入耗费约8秒。与优先级较低,即weight设置值较小的分组相比,优先级较高,即属于weight设置值较大的分组(/cgroup/high)的进程可以优先执行I/O操作。