前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Cgroup CPU Quota技术的不足

Cgroup CPU Quota技术的不足

作者头像
皮振伟
发布2019-03-07 16:15:19
3K0
发布2019-03-07 16:15:19
举报

前言 cgroup作为Linux上广泛应用的一个功能,用来限制、控制与分离一个进程组群的资源。在内核Linux-4.14上,支持了如下类型(源代码参考https://github.com/torvalds/linux/blob/v4.14/include/linux/cgroup_subsys.h): SUBSYS(cpuset) SUBSYS(cpu) SUBSYS(cpuacct) SUBSYS(io) SUBSYS(memory) SUBSYS(devices) SUBSYS(freezer) SUBSYS(net_cls) SUBSYS(perf_event) SUBSYS(net_prio) SUBSYS(hugetlb) SUBSYS(pids) SUBSYS(rdma) SUBSYS(debug) 查看目前实际打开了其中的一部分: # cat /boot/config-`uname -r` | grep CONFIG_CGROUP_ CONFIG_CGROUP_WRITEBACK=y CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_PIDS=y # CONFIG_CGROUP_RDMA is not set CONFIG_CGROUP_FREEZER=y # CONFIG_CGROUP_HUGETLB is not set CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CGROUP_NET_PRIO=y CONFIG_CGROUP_NET_CLASSID=y 尤其是其中的CPU的Quota控制,在以docker为代表的PaaS中大显身手。然而,这并不意味着cgroup的CPU Quota控制就是完美的。例如,希望一个进程占用的CPU不超过200%,那么它的真实的CPU占用是怎样的呢?接下来,作者会构造一段代码,可以算是一种极端场景,来证实这个问题确实存在。

测试用例

1,测试代码 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <errno.h> #include <sys/syscall.h> #include <sys/time.h> #include <sys/types.h> #define print_err_and_exit(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) static int bench_loops = 1; static long onoff; int on = 0; int off = 0; void *__routine(void *arg) { unsigned int m, n; long l = 0; while (1) { for (m = 0; m < bench_loops; m++) { for (n = 0; n < 0x1000000; n++) { __sync_fetch_and_add(&l, 1); } } while (1) { if (__sync_fetch_and_add(&onoff, 0)) { on++; break; } else off++; usleep(1000); } } return NULL; } void show_help() { printf("Usage :\n"); printf("\t-l NUM : bench loops\n"); printf("\t-n THREADs : bench threads\n"); printf("\t-q quota : cgroup cpu quota\n"); } int main(int argc, char *argv[]) { int opt; int num_threads = 8; int cpu_quota = 1; pthread_t thread; char cmd[128]; while ((opt = getopt(argc, argv, "hl:n:q:")) != -1) { switch (opt) { case 'l': bench_loops = atoi(optarg); break; case 'n': num_threads = atoi(optarg); break; case 'q': cpu_quota = atoi(optarg); break; case 'h': default: show_help(); return 0; } } system("mkdir -p /sys/fs/cgroup/cpu/loading-bench"); printf("Cgroup : /sys/fs/cgroup/cpu/loading-bench\n"); system("echo 1 > /sys/fs/cgroup/cpu/loading-bench/cgroup.clone_children"); sprintf(cmd, "echo %d > /sys/fs/cgroup/cpu/loading-bench/tasks", getpid()); system(cmd); sprintf(cmd, "echo %d > /sys/fs/cgroup/cpu/loading-bench/cpu.cfs_quota_us", cpu_quota*1000*100); system(cmd); printf("Test %d threads\n", num_threads); int tnum; for (tnum = 0; tnum < num_threads; tnum++) { const int create_result = pthread_create(&thread, NULL, __routine, NULL); if (create_result != 0) { print_err_and_exit(create_result, "pthread_create"); } } while (1) { __sync_fetch_and_and(&onoff, 0); printf("set onoff 0, on = %d, off = %d\n", on, off); sleep(1); __sync_fetch_and_or(&onoff, 1); printf("set onoff 1, on = %d, off = %d\n", on, off); sleep(1); } pthread_join(thread, NULL); return 0; } 代码逻辑就是初始化cgroup,并启动多个线程,线程周期性的使用CPU。 编译后,我们启动进程,参数是8个线程,CPU Quota 200%。 #./loading-bench -n 8 -l 1 -q 2 我们使用top命令来监控,发现进程最高CPU在200%左右。符合我们的预期。

2,短时间间隔的情况 另外,使用shell脚本来收集进程的实际CPU的使用情况: PID=`ps -ef | grep -w loading-bench | grep -w -v grep | awk '{print $2}'` rm -rf data.log date for ((c=1;c<=1000;c++)) do cat /proc/$PID/stat >> data.log sleep 0.01 done date cat data.log | awk '{print $14}' > tmp.log rm -rf data.log mv tmp.log data.log 在shell脚本中,我们把收集的频率提高到了每秒100次,收集更加微观的数据。对收集到的数据进行分析:

我们在选取其中的一部分来观察:

我们可以看到,实际的CPU并非是均匀的,按照不超过200%的约定,我们理应看到的数据在纵轴上不超过2(实际是3左右,因为shell脚本的执行也需要时间)。 从长时间来看,以1s为粒度,基本平均到200%左右。但是在0.01s为粒度来看,就已经是非常抖动的状态了。

3,影响 1s并不算长,似乎影响不大。然而,真的是这样吗? 如上图,在0.01s内,CPU可能会突然到达一个峰值,那么,就会导致其他CPU的调度受到影响。 典型场景如:多个MySql部署在一个OS上,突然一个实例来了一个慢查询,其他的实例调度受到了影响,而造成了请求抖动。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AlwaysGeek 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档