前一篇博客介紹了利用 cgroup 來控制進程的 CPU和內存使用情況, 這次補上使用 cgroup 來控制進程的IO優先級的方法.
前提條件
如果想控制進程的IO優先級, 需要內核的支持, 內核編譯時需要打開下面2個參數.
CONFIG_BLK_CGROUP=y
CONFIG_CFQ_GROUP_IOSCHED=y
查看是否開啟這2個內核編譯選項的方法很簡單:
root@debian-113:~# grep -i 'blk_cgroup' /boot/config-`uname -r` root@debian-113:~# grep -i 'cfq_group' /boot/config-`uname -r`
如果這2個內核選項沒有打開, 只能重新編譯內核后再來實驗下面的實例了.
再次通過 /proc/cgroups 來查看 blkio 是否已經啟用.
root@debian-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調度程序來使用.
root@debian-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優先級
- 掛載 cgroup文件系統, 掛載參數 -o blkio
- 建立2個group, 分別為 A 和 B
- 默認情況, 2個 group中的dd進程同時進行文件操作
- 查看默認情況下, 2個dd進程完成的時間
- 設置 A 的優先級為 100, B 的優先級為 1000
- 同時在2個group A 和 B 中運行 dd進程
- 查看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 文件系統 root@debian-113:~# mount -t cgroup -o blkio cgroup /mnt/cgroup/ root@debian-113:~# mkdir /mnt/cgroup/{A,B} root@debian-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 root@debian-113:~# cat /mnt/cgroup/A/blkio.weight 500 <-- 這個值的范圍是 100 ~ 1000, 值越大優先級越高 root@debian-113:~# cat /mnt/cgroup/B/blkio.weight 500 # 默認情況下的測試結果如下: A和B耗時都是 20秒 root@debian-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 root@debian-113:~# echo 100 > /mnt/cgroup/A/blkio.weight root@debian-113:~# echo 1000 > /mnt/cgroup/B/blkio.weight root@debian-113:~# cat /mnt/cgroup/A/blkio.weight 100 root@debian-113:~# cat /mnt/cgroup/B/blkio.weight 1000 # 不同優先級下的測試結果如下: A耗時 19秒; B耗時 11秒 root@debian-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 相關文檔.