[原] Cgroup CPU, Blkio 測試

關於Cgroup的簡單測試


簡單介紹Cgroup

(若是對cgroup熟悉能夠忽略)
通常狀況下,cgroup掛載到一個虛擬文件目錄,而後能夠經過文件系統的API對其操做。mysql

># mount | grep cgroup 能夠查看mount pointsql

(debian) /sys/fs/cgroup/
(redhat) /cgroup/

如下非特殊說明,均以ubuntu12.04(3.5.0-23-generic) 爲準
若是沒有,安裝方式
># apt-get install cgroup-bin
># yum -y install libcgroupubuntu

能夠在 /proc/cgroups 下面看到目前有哪些子系統以及他們的使用狀況electron

root@vm-222:/sys/fs/cgroup/blkio# cat /proc/cgroups 
#subsys_name    hierarchy   num_cgroups enabled
cpuset  9   1   1
cpu 10  10  1
cpuacct 11  1   1
memory  12  1   1
devices 13  1   1
freezer 14  1   1
blkio   15  2   1
perf_event  16  1   1

在 /sys/fs/cgroup/ 目錄下能夠看到以下子系統, 這是系統默認掛載方式,也是推薦的方式。ide

zhangbo3@vm-222:/sys/fs/cgroup$ ll
total 0
drwxr-xr-x 10 root root 200 Aug 31 23:06 ./
drwxr-xr-x  6 root root   0 Aug 31 23:14 ../
drwxr-xr-x  2 root root   0 Aug 31 23:06 blkio/
drwxr-xr-x  2 root root   0 Sep  6 10:22 cpu/
drwxr-xr-x  2 root root   0 Aug 31 23:06 cpuacct/
drwxr-xr-x  2 root root   0 Sep  6 10:22 cpuset/
drwxr-xr-x  2 root root   0 Aug 31 23:00 devices/
drwxr-xr-x  2 root root   0 Au  31 23:06 freezr/
drwxr-xr-x  2 root root   0 Aug 31 23:06 memor/
drwxr-xr-x  2 root root   0 Aug 31 23:06 perf_event/

也能夠將 CPU, MEMORY 子系統都掛載到一個目錄下.
mount -t cgroup -o cpu,memory cpu_mem_cg /sys/fs/cgroup/cpu_mem_cg測試

可是當CPU子系統已經被掛載過一次以後,就不能再掛載到第二個目錄。ui

>#mount -t cgroup -o cpu,memory cpu_mem_cg /sys/fs/cgroup/cpu_mem_cg
提示錯誤以下:
>#mount: /sys/fs/cgroup/cpu_mem_cg already mounted or /sys/fs/cgroup/cpu_mem_cg busy

子系統文件介紹,以cpu子系統爲例:.net

cpu
├── cgroup.clone_children
├── cgroup.event_control
├── cgroup.procs
├── cpu.cfs_period_us
├── cpu.cfs_quota_us
├── cpu.rt_period_us
├── cpu.rt_runtime_us
├── cpu.shares
├── cpu.stat
├── notify_on_release
├── release_agent
└── tasks

tasks 裏面包含了當前進程,默認安裝cgroup後,當前全部系統進程都會歸入cgroup管理,而且被加入到cgroup 根目錄下,全部值爲cgroup默認值,調度策略也使用徹底公平調度.debug

cat tasks
能夠看到全部進程.

cgroup 採用層級管理方式,能夠在cpu子系統下面直接新建目錄。
>#mkdir test
在test/ 目錄下面,會基礎根目錄的全部屬性,可是不包括tasks.
能夠調整test/ 目錄下面的cpu.* 的值對其設置,好比設置 cpu.shares=100
>#echo 100 > cpu.shares
全部tasks裏面的pid都會在這個cgroup的管理下, 按照cpu.shares=100的值做爲系統調度.

測試及驗證

這次測試只針對CPU和blkio子系統,CPU用來限制CPU調度,blkio用來限制塊設備IO調度

測試點

- 查看cpu.shares值是否符合調度預期
- mysql進程cpu調度是否符合預期
- 磁盤IO調度是否符合預期

實際測試結果

cpu.shares值是否符合預期

cpu.shares 值做爲CPU的子系統的全局調度策略,爲某個group設置cpu.shaes值後,會按照系統當前全部shares值爲其分配必定權重,默認一個group最大值爲1024, 這是個相對值, 好比group1, group2 的shares值同爲100,他們應該獲取相同的CPU時間片, 若是group1 設置爲100,group2 設置爲200,則group2的時間片應該是group1的兩倍.

以一個會佔據單核全部CPU的進程爲例:

#include <stdlib.h>
#include <stdio.h>
int main(){
    volatile float a;
    while(1) {
        a = 88888.8 * 88888.78;
    }
    return ;
}

默認全部進程已經加入cgroup豪華午飯.
因爲是雙核機器,開兩個程,徹底佔據全部CPU.

PID  USER   PR  NI VIRT RES   SHR  S      %CPU %MEM  TIME+ COMMAND  
39707 zhangbo3  20   0  4156  348  272 R   99  0.0   0:13.88 crazy  
39863 zhangbo3  20   0  4156  352  272 R   99  0.0   0:36.14 crazy

四個進程

39863 zhangbo3  20   0  4156  352  272 R   48  0.0   1:38.10 crazy  
39707 zhangbo3  20   0  4156  348  272 R   46  0.0   3:27.95 crazy  
40124 zhangbo3  20   0  4156  352  272 R   43  0.0   0:05.55 crazy 
 4025 zhangbo3  20   0  4156  352  272 R   46  0.0   0:05.70 crazy

默認權值是1024的cgroup,進程幾乎是平分CPU.

現將39863 39707 兩個進程加入到test group, 並設置其cpu.shares=512
echo 39863 >> tasks
echo 39707 >> tasks
echo 512 >> cpu.shares

查看當前cpu利用率

40124 zhangbo3  20   0  4156  352  272 R   63  0.0   3:12.10 crazy  
40125 zhangbo3  20   0  4156  352  272 R   61  0.0   3:12.02 crazy  
39863 zhangbo3  20   0  4156  352  272 R   34  0.0   4:28.27 crazy  
39707 zhangbo3  20   0  4156  348  272 R   32  0.0   6:12.77 crazy

能夠看到, 39863 39707 兩個進程的CPU 使用率基本是前兩個的一半,徹底符合預期有木有.

mysql進程cpu調度是否符合預期

將兩個mysql實例加入到統一group下,爲其設置cpu.shares=500
利用mysqlslap 對兩個實例小小壓測一下.
ps:針對CPU的壓測,須要將CPU都壓滿才能體現cpu.shares的值的分配,若是是空載狀況下,全部group都會最大限度的利用CPU.

User time 6.66, System time 13.08
Maximum resident set size 9548, Integral resident set size 0
Non-physical pagefaults 26115, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 253951, Involuntary context switches 5412
User time 6.57, System time 13.20
Maximum resident set size 9536, Integral resident set size 0
Non-physical pagefaults 26080, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 255336, Involuntary context switches 4518

能夠觀察到二者的Involuntary context switches值相差不大


將兩個mysql 實例加入到不一樣的group下,分別爲其設置cpu.shares=500, 1000

User time 12.07, System time 17.12
Maximum resident set size 150872, Integral resident set size 0
Non-physical pagefaults 938774, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 227545, Involuntary context switches 10615
User time 12.01, System time 18.79
Maximum resident set size 134212, Integral resident set size 0
Non-physical pagefaults 1087038, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 227556, Involuntary context switches 6800

能夠觀察到Involuntary context switches值基本符合預期

磁盤IO調度是否符合預期

分別將磁盤blkio.weight 設置爲 500
dd if=/dev/zero of=/data2/dd.test bs=8k count=1024000
產生兩個8.4G的文件
產生以下IO調度分配結果

1024000+0 records in
1024000+0 records out
8388608000 bytes (8.4 GB) copied, 84.7144 s, 99.0 MB/s
1024000+0 records in
1024000+0 records out
8388608000 bytes (8.4 GB) copied, 81.2984 s, 103 MB/s

看似符合預期,因而進行下一步
將進程1的IO權值設置爲1000, 進程2的權值設置爲100
能夠看到二者並沒有差異,不符合咱們的預期,是我打開的方式不對麼?

4000+0 records in
4000+0 records out
4194304000 bytes (4.2 GB) copied, 5.292 s, 70.7 MB/s
4000+0 records in
4000+0 records out
4194304000 bytes (4.2 GB) copied, 60.3834 s, 69.5 MB/s

由於須要使用徹底公平調度,因而設置io調度方式爲cfq

echo cfq > /sys/block/<divice-name>/queue/scheduler

在cgroup文檔裏面有這麼一個提示:

blkio子系統只針對非buffered IO或者read IO起做用.
使用直接IO方式啓動DD

dd if=/dev/zero of=/data/dd.test oflag=direct,nonblock bs=1M count=4000

將buffer刷到磁盤,並清掉cache

sync
echo 3 > /proc/sys/vm/drop_caches

觀察到IO調度符合預期.

8192000+0 records in
8192000+0 records out
4194304000 bytes (4.2 GB) copied, 35.9584 s, 117 MB/s

root@ip-172-17-6-225:/tmp# cat cgroup2.log 
4000+0 records in
4000+0 records out
4194304000 bytes (4.2 GB) copied, 97.82 s, 42.9 MB/s

由於進程1提早結束,因此會讓出一部分時間片給進程2,可是從iotop來看,同時運行的狀況下IO調度是負荷預期的.

總結使用BLKIO子系統必須知足如下幾個條件:

1. 默認系統調度方式爲CFQ, 徹底公平調度
2. 內核編譯宏 CONFIG_BLK_CGROUP=y CONFIG_CFQ_GROUP_IOSCHED=y
3. 必須是非buffered 寫 IO

總結

測試過程當中使用到的命令:

mysql 壓力測試
mysqlslap -uxxx -pxxx -P 6810 -h127.0.0.1 --concurrency=200 --iterations=1 --auto-generate-sql --number-of-queries=20000 --debug-info  --create-schema='test2' --auto-generate-sql-load-type=mixed

dd 磁盤壓測
dd if=/dev/zero of=/data/dd.test oflag=direct,nonblock bs=1M count=4000

iotop 查看IO狀況

本次測試針對CPU和IO調度都作了相應的測試,調度參數符合預期.

針對cgroup對MySQL的管理方案:

  1. 限制 CPU 使用,每一個MySQL實例一個group, 併爲其設置合適的cpu.shares值
  2. 限制 blkio 使用,並打開 Innodb_flush_method=O_DIRECT
  3. 使用 device 子系統限制,若是佔用空間過大,能夠設置group對特定塊設備不可寫

參考文獻

RedHat Cgroup Documents
Blkio 子系統內核參數
Mysql InnoDB IO configuration and flushing
Linux資源管理-IO優先級
A expanded CFQ scheduler for cgroups

相關文章
相關標籤/搜索