前言 我们经常使用cgroup做一些资源隔离,比如内存、CPU、磁盘空间以及磁盘IO。对应的子系统是cpuset、memory、blkio。具体cgroup相关详细介绍,请查看redhat官方文档 ,不再详述,这里只是记录下我在使用cgroup限制diskio时遇到的一个问题。
问题 我们要对自己的一组agent做iops限制,agent是安装在/data目录下,磁盘信息如下图:
可以看到/data目录挂载的设备为/dev/sda4,根据设备查找设备编号为(8:4),如下图:
现在,我们开始使用cgroup限制agent的diskio,具体操作脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 # 定义校验函数function verify_cg_val_iops() { metric_name="$1" expected_val_dev_num="$2" expected_val_dev_iops="$3" #获取已配置的设备号 val_get_res_dev_num=`cgget -n -r ${metric_name} agents | awk '{print $2}'` test_exitcode "cgget ${metric_name} failed for ${port}, cgget_result=${val_get_res_dev_num}" #获取已配置的iops值 val_get_res_dev_iops=`cgget -n -r ${metric_name} agents | awk '{print $3}'` test_exitcode "cgget ${metric_name} failed for ${port}, cgget_result=${val_get_res_dev_iops}" #校验设备号 if [ "${expected_val_dev_num}" != "${val_get_res_dev_num}" ]; then echo "${metric_name} expected dev_num val=${expected_val_dev_num} not equal to from cgget=${val_get_res_dev_num}" exit 1 fi #校验iops值 if [ "${expected_val_dev_iops}" != "${val_get_res_dev_iops}" ]; then echo "${metric_name} expected dev_iops val=${expected_val_dev_iops} not equal to from cgget=${val_get_res_dev_iops}" exit 1 fi } # 创建一个隔离组agentscgcreate -g blkio:/agents # 限制agent组对指定设备号的disk的读iops为3000cgset -r blkio.throttle.read_iops_device="8:4 3000" agents test_exitcode "io read set for 8:4 failed" # 检查读iops是否配置正确verify_cg_val_iops "blkio.throttle.read_iops_device" "8:4" "3000" # 限制agent组对指定设备号的disk的写iops为3000cgset -r blkio.throttle.write_iops_device="8:4 3000" agents test_exitcode "io write set for 8:4 failed" # 检查写iops是否配置正确verify_cg_val_iops "blkio.throttle.write_iops_device" "8:4" "3000"
执行时报错,错误信息为:
blkio.throttle.read_iops_device expected dev_num val=8:4 not equal to from cgget=
读iops配置失败,校验的设备号(为空)与预期设备号(8:4)不一致。
设备号写错了吗?/dev/sda4的设备号确实是8:4,没错啊,什么原因呢?
手动配置呢?
1 2 3 4 5 cd /sys/fs/cgroup/blkio/agents echo "8:4 3000" > blkio.throttle.read_iops_device -bash: echo: write error: Invalid argument
显示参数错误,再尝试直接vim打开写入,保存退出时报错:
“blkio.throttle.read_iops_device” E667: Fsync failed
解决 无奈之下,寻求谷歌大神,最终在stackoverflow上找到问题原因和解决方法。
原帖回答如下:
The problem was that I used /dev/sda5 as the device name, while in fact the physical device name (as opposed to the partitioned, logical device) must be use. It now works when I specify the : id of /dev/sda – user1734905
意思就是:在使用blkio做iops隔离时,应该指定的是物理磁盘的编号,而不是物理盘的某个分区的编号 。
回到上面的问题,我们使用的是/dev/sda4的编号,实际上我们的机器只有一块物理盘,做了4个分区,/dev/sda4只是物理盘/dev/sda的一个分区,应该使用/dev/sda的编号(8:0)。
修改脚本中的设备编号8:4为8:0,再执行脚本,问题解决。
参考链接