Docker中的Cpuset实现
文章目录
一、什么是Cpuset
cpuset基本功能是限制某一组进程只运行在某些cpu和内存节点上,cpuset是基于cgroup子系统实现,使用cpuset上述功能可以让系统管理员动态调整进程运行所在的cpu和内存节点。
-
内存节点:主要依据CPU访问代价的不同而划分。多CPU下环境下,本地内存和远端内存就是不同的节点。即使在单CPU环境下,访问所有内存的代价都是一样的,Linux内核依然存在内存节点的概念,只不过只有一个内存节点而已。内核以struct pg_data_t来描述内存节点。
-
cpu节点:逻辑CPU数目,shell里通过top+1即可查看
二、使用cpuset限制进程运行在指定核
1. 压力测试工具 stress
安装及使用方法
yum install -y epel-release
yum install stress -y
$ stress --help
stress imposes certain types of compute stress on your system
Usage: stress [OPTION [ARG]] ...
-?, --help show this help statement
--version 查看stress版本号
-v, --verbose 显示 stress 程序运行过程中的详细信息
-q, --quiet stress 程序运行的过程中不输出信息。
-n, --dry-run 输出程序会做什么而并不实际执行相关的操作
-t, --timeout N 在 N 秒后结束程序。
--backoff N 让新 fork 出来的进程 sleep N 微秒再开始运行。
-c, --cpu N 产生 N 个进程,每个进程都反复不停的调用sqrt()函数计算随机数的平方根
-i, --io N 产生 N 个进程,每个进程反复调用 sync() 将内存上的内容写到硬盘上
-m, --vm N 产生 N 个进程,每个进程不断分配和释放内存
--vm-bytes B 指定分配内存的大小
--vm-stride B 不断的给部分内存赋值,让 COW(Copy On Write)发生
--vm-hang N 指示每个消耗内存的进程在分配到内存后转入睡眠状态 N 秒,然后释放内存,一直重复执行这个过程
--vm-keep 一直占用内存,区别于不断的释放和重新分配(默认是不断释放并重新分配内存)
-d, --hdd N 产生 N 个不断执行 write 和 unlink 函数的进程(创建文件,写入内容,删除文件)
--hdd-bytes B 指定文件大小 (default is 1GB)
Example: stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s
2. 启动stress压力测试,记录pid
[root@myitx mydocker]# stress --vm-bytes 200m --vm-keep --vm 4
可以看到40011-40014四个进程主要在编号为1,3,4,7的cpu上运行。
3. 设置cpuset的限制组
# 进入 /sys/fs/cgroup/cpuset
[root@myitx cpuset]# mkdir test-cpuset
[root@myitx cpuset]# tree test-cpuset/
test-cpuset/
├── cgroup.clone_children
├── cgroup.event_control
├── cgroup.procs
├── cpuset.cpu_exclusive
├── cpuset.cpus
├── cpuset.effective_cpus
├── cpuset.effective_mems
├── cpuset.mem_exclusive
├── cpuset.mem_hardwall
├── cpuset.memory_migrate
├── cpuset.memory_pressure
├── cpuset.memory_spread_page
├── cpuset.memory_spread_slab
├── cpuset.mems
├── cpuset.sched_load_balance
├── cpuset.sched_relax_domain_level
├── notify_on_release
└── tasks
0 directories, 18 files
[root@myitx cpuset]# cd test-cpuset/
[root@myitx test-cpuset]# echo 0 > cpuset.mems
[root@myitx test-cpuset]# echo 0,2,4,6 > cpuset.cpus
[root@myitx test-cpuset]# cat tasks
[root@myitx test-cpuset]# for i in {40011,40012,40013,40014}; do echo $i > tasks; done
可以看到40011-40014四个进程主要在编号为0,2,4,6的cpu上运行。
总结
本文仅仅简单介绍了cpuset的使用,而docker的具体实现更加复杂,具体去看源码。