Linux资源管理-IO优先级

前一篇博客介绍了利用 cgroup 来控制进程的 CPU和内存使用情况, 这次补上使用 cgroup 来控制进程的IO优先级的方法.

前提条件

如果想控制进程的IO优先级, 需要内核的支持, 内核编译时需要打开下面2个参数.

CONFIG_BLK_CGROUP=y
CONFIG_CFQ_GROUP_IOSCHED=y

查看是否开启这2个内核编译选项的方法很简单:

[email protected]113:~# grep -i ‘blk_cgroup‘ /boot/config-`uname -r`
[email protected]-113:~# grep -i ‘cfq_group‘ /boot/config-`uname -r`

如果这2个内核选项没有打开, 只能重新编译内核后再来实验下面的实例了.

再次通过 /proc/cgroups 来查看 blkio 是否已经启用.

[email protected]113:~# cat /proc/cgroups
#subsys_name    hierarchy    num_cgroups    enabled
cpuset    0    1    1
cpu    0    1    1
cpuacct    0    1    1
memory    0    1    1
devices    0    1    1
freezer    0    1    1
net_cls    0    1    1
blkio    0    1    1    <-- enabled = 1, 说明已经启用
perf_event    0    1    1

如果 blkio 没有启用, 可以通过grub设置启动参数来启用它.

类似的可以参考: Linux资源控制-CPU和内存  中 实例4 - cgroup 对使用的内存的控制 中启用memory的方法。

除此之外, 还得查看是否能够将 CFQ 作为IO调度程序来使用.

[email protected]113:~# cat /sys/class/block/sda/queue/scheduler
noop deadline [cfq]

上述结果表示支持cfq调度, []括住cfq 表示当前使用的就是 cfq调度.

如果 cat 的结果中没有 cfq, 需要重新编译内核, 使之能够支持 cfq调度.

如果 cat 的结果中有 cfq, 但是 cfq 不是当前正在使用的调度程序, 即 [] 没有括在 cfq上, 那么

cat cfq /sys/class/block/sda/queue/scheduler     <-- 将当前的IO调度程序设置成 cfq

注: 上面的 sda 是我的测试的硬盘, 如果你的是 sdb 或者其它, 请对应修改.

实例 - 控制IO优先级

  1. 挂载 cgroup文件系统, 挂载参数 -o blkio
  2. 建立2个group, 分别为 A 和 B
  3. 默认情况, 2个 group中的dd进程同时进行文件操作
  4. 查看默认情况下, 2个dd进程完成的时间
  5. 设置 A 的优先级为 100, B 的优先级为 1000
  6. 同时在2个group A 和 B 中运行 dd进程
  7. 查看group A 和 B 中的 dd进程完成的时间

实验之前, 先制作测试脚本. (简单写了一个如下)

#!/bin/bash

####################################################################
# 1. 创造2个测试文件, 大小都是1G
# 2. 将当前进程加入到指定 cgroup
# 3. 执行 dd 操作
# 4. 删除 测试文件
# 5. 显示log
####################################################################

function usage()
{
    echo "./blkio-test.sh <group1> <group2>"
    exit 1
}

if [ $# != 2 ]; then
    usage
fi

group1_src=~/group1.src
group2_src=~/group2.src

group1_log=/tmp/group1.log
group2_log=/tmp/group2.log

group1=$1
group2=$2

echo "生成测试数据 $group1_src 和 $group2_src (大小都是1G)"
dd if=/dev/zero of=$group1_src count=1024 bs=1M
dd if=/dev/zero of=$group2_src count=1024 bs=1M

echo "同时在 $group1 和 $group2 中开始 dd 测试"
echo 3 > /proc/sys/vm/drop_caches
echo $$ >> $group1/tasks
(date; dd if=$group1_src of=/dev/null; date;) > $group1_log 2>&1 &

echo $$ >> $group2/tasks
(date; dd if=$group2_src of=/dev/null; date;) > $group2_log 2>&1 &

wait
echo "测试完成!"

echo "开始清除测试文件"
rm -rf $group1_src $group2_src
echo "测试文件清除完成"

echo "------------------------------------------"
echo "显示group1 的log"
cat $group1_log

echo "------------------------------------------"
echo "显示group2 的log"
cat $group2_log

echo "------------------------------------------"

开始实验:

# 挂载 cgroup 文件系统
[email protected]-113:~# mount -t cgroup -o blkio cgroup /mnt/cgroup/

[email protected]-113:~# mkdir /mnt/cgroup/{A,B}
[email protected]-113:~# ll /mnt/cgroup/
total 0
drwxr-xr-x 2 root root 0 Sep  5 13:23 A
drwxr-xr-x 2 root root 0 Sep  5 13:23 B
-r--r--r-- 1 root root 0 Sep  5 13:23 blkio.io_merged
-r--r--r-- 1 root root 0 Sep  5 13:23 blkio.io_queued
-r--r--r-- 1 root root 0 Sep  5 13:23 blkio.io_service_bytes
-r--r--r-- 1 root root 0 Sep  5 13:23 blkio.io_serviced
-r--r--r-- 1 root root 0 Sep  5 13:23 blkio.io_service_time
-r--r--r-- 1 root root 0 Sep  5 13:23 blkio.io_wait_time
--w------- 1 root root 0 Sep  5 13:23 blkio.reset_stats
-r--r--r-- 1 root root 0 Sep  5 13:23 blkio.sectors
-r--r--r-- 1 root root 0 Sep  5 13:23 blkio.time
-rw-r--r-- 1 root root 0 Sep  5 13:23 blkio.weight   <-- 这个就是设置IO优先级的文件
-rw-r--r-- 1 root root 0 Sep  5 13:23 blkio.weight_device
-rw-r--r-- 1 root root 0 Sep  5 13:23 cgroup.clone_children
--w--w--w- 1 root root 0 Sep  5 13:23 cgroup.event_control
-rw-r--r-- 1 root root 0 Sep  5 13:23 cgroup.procs
-rw-r--r-- 1 root root 0 Sep  5 13:23 notify_on_release
-rw-r--r-- 1 root root 0 Sep  5 13:23 release_agent
-rw-r--r-- 1 root root 0 Sep  5 13:23 tasks

# 默认2个组内的IO优先级都是500
[email protected]-113:~# cat /mnt/cgroup/A/blkio.weight
500  <-- 这个值的范围是 100 ~ 1000, 值越大优先级越高
[email protected]-113:~# cat /mnt/cgroup/B/blkio.weight
500

# 默认情况下的测试结果如下: A和B耗时都是 20秒
[email protected]-113:~# ./blkio-test.sh /mnt/cgroup/A /mnt/cgroup/B
生成测试数据 /root/group1.src 和 /root/group2.src (大小都是1G)
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 6.01188 s, 179 MB/s
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 9.4272 s, 114 MB/s
同时在 /mnt/cgroup/A 和 /mnt/cgroup/B 中开始 dd 测试
测试完成!
开始清除测试文件
测试文件清除完成
------------------------------------------
显示group1 的log
Fri Sep  5 13:26:31 CST 2014
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 20.0504 s, 53.6 MB/s
Fri Sep  5 13:26:51 CST 2014
------------------------------------------
显示group2 的log
Fri Sep  5 13:26:31 CST 2014
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 18.8583 s, 56.9 MB/s
Fri Sep  5 13:26:51 CST 2014
------------------------------------------

# 修改A的优先级为100, B的优先级为1000
[email protected]-113:~# echo 100 > /mnt/cgroup/A/blkio.weight
[email protected]-113:~# echo 1000 > /mnt/cgroup/B/blkio.weight
[email protected]-113:~# cat /mnt/cgroup/A/blkio.weight
100
[email protected]-113:~# cat /mnt/cgroup/B/blkio.weight
1000

# 不同优先级下的测试结果如下: A耗时 19秒; B耗时 11秒
[email protected]-113:~# ./blkio-test.sh /mnt/cgroup/A /mnt/cgroup/B
生成测试数据 /root/group1.src 和 /root/group2.src (大小都是1G)
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 6.52967 s, 164 MB/s
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 8.01311 s, 134 MB/s
同时在 /mnt/cgroup/A 和 /mnt/cgroup/B 中开始 dd 测试
测试完成!
开始清除测试文件
测试文件清除完成
------------------------------------------
显示group1 的log
Fri Sep  5 13:30:06 CST 2014
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 18.5598 s, 57.9 MB/s
Fri Sep  5 13:30:25 CST 2014
------------------------------------------
显示group2 的log
Fri Sep  5 13:30:06 CST 2014
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 10.6127 s, 101 MB/s
Fri Sep  5 13:30:17 CST 2014
------------------------------------------

可以看出, IO优先级调整之后, 确实优先级高的cgroup中的进程能更快完成IO操作.

总结

其实 cgroup 除了能够IO优先级之外, 还可以控制进程的其它IO属性, 具体参见挂载在 cgroup 的IO相关设置文件.

各个文件的具体含义, 请参考更详细的 cgroup 相关文档.

时间: 2024-10-12 19:27:29

Linux资源管理-IO优先级的相关文章

linux的cpu和磁盘io优先级设置

通常linux下限制cpu使用有三种方法: nice/renice:调整进程使用cpu的优先级 cpulimit:不修改进程的nice值,通过暂停进程一段时间,来限制cpu使用 cgroups:内核提供的机制,可以限制.记录.隔离一组进程所使用的cpu.内存.磁盘.网络等资源,是docker等容器的基础技术之一 限制磁盘io : ionice : 调整io调度的优先级 cgroups 这里只说nice和ionice,实际上nice和ionice只是改变优先级,并没有真正的限制 一.nice 1.

Linux系统IO分析工具之iotop参数详解(查看IO占用)

这篇文章主要介绍了Linux系统IO分析工具之iotop参数详解(查看IO占用),本文着重注解了iotop工具的参数,以及可操作命令,需要的朋友可以参考下 简介: iotop – simple top-like I/O monitoriotop是一个用来监视磁盘I/O使用状况的 top 类工具,可监测到哪一个程序使用的磁盘IO的信息(requires 2.6.20 or later) 安装: 复制代码 代码如下: yum -y install iotop 用法: 复制代码 代码如下: iotop

Linux串口IO模式的一些心得

众所周知,在Linux系统下所有设备都是以文件的形式存在,串口也一样. 通常I/O操作都是有阻塞与非阻塞的两种方式. 其中"超时"这个概念其实是阻塞中的一种处理手段,本质还是属于阻塞的I/O模式. 在Linux中串口的IO操作 本文将它分为三种状态: 阻塞状态 超时状态 非阻塞状态 这三种状态的转换组合有这么几种: 阻塞 --> 超时 阻塞 --> 非阻塞 超时 --> 阻塞 超时 --> 非阻塞 非阻塞 --> 阻塞 我们一个一个来分析 首先在一个串口的

linux 同步IO: sync、fsync与fdatasync

[linux 同步IO: sync.fsync与fdatasync] 传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓冲进行.当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待其写满或者当内核需要重用该缓冲区以便存放其他磁盘块数据时,再将该缓冲排入输出队列,然后待其到达队首时,才进行实际的I/O操作.这种输出方式被称为延迟写(delayed write) 延迟写减少了磁盘读写次数,但是却降低了文

Linux noop io 调度算法分析

定义了一个elevator_noop的调度器类型: static struct elevator_type elevator_noop = { .ops = { .elevator_merge_req_fn = noop_merged_requests,//查询一个request,用于将bio并入 .elevator_dispatch_fn = noop_dispatch,//将noop调度器链表中最前面的请求取出,分派给块设备的请求队列 .elevator_add_req_fn = noop_

Linux deadline io 调度算法

deadline算法的核心就是在传统的电梯算法中加入了请求超时的机制,该机制主要体现在两点: 1.请求超时时,对超时请求的选择. 2.没有请求超时时,当扫描完电梯最后一个request后,准备返回时,对第一个request的选择.基于以上两点,平衡了系统i/o吞吐量和响应时间. 此外,该算法还考虑到了读操作对写操作造成的饥饿. 定义了elevator_deadline调度器类型: static struct elevator_type iosched_deadline = { .ops = {

linux 同步IO: sync msync、fsync、fdatasync与 fflush

最近阅读leveldb源码,作为一个保证可靠性的kv数据库其数据与磁盘的交互可谓是极其关键,其中涉及到了不少内存和磁盘同步的操作和策略.为了加深理解,从网上整理了linux池畔同步IO相关的函数,这里做一个罗列和对比.大部分为copy,仅为记录,请各位看官勿喷. 传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓冲进行.当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待其写满或者当内核需要重用该缓

[Linux 005]——IO重定向

通常在 Shell 中执行命令的时候,我们会在输入命令的下方看到执行结果,操作系统默认将命令的执行结果输出到显示器上.当然,我们也可以手动的指定输出路径,或者输入路径,这就是 I/O 重定向. 1.标准输出重定向 使用 cat 命令,命令的执行结果将会打印在屏幕中. 我们使用 > 来进行输出重定向,此时屏幕上不再打印命令执行结果了,而是将执行结果保存到了 ./target.xxx 文件中. 来看一下 ./target.xxx 文件中的内容: 2.标准输入重定向 tr 命令可以从键盘上读取标准输入

linux网络io

linux的网络io有5种 (1)阻塞IO-(对应Java-Bio): 银行有一个业务员,她负责收集单业务,第一个办理业务的人单子没填好,她就一直等着他填好,后面其他的人都不给办理,她自己也不休息干等着,也不去通知同事,直到这个人的业务单填好. (2)非阻塞I/O: 银行有一个业务员,她负责收集单业务,第一个办理业务的人单子没填好,她就告诉他填好,然后就立刻告诉同事还没人填好,然后再去等着,看第一个人是否填好了或者后面的某个人是否填好了,再立刻告诉她的同事. (3)I/O复用(jdk1.4对应J