zoukankan      html  css  js  c++  java
  • Cgroups概述

    1. Cgroups是什么?

    从 2.6.24 版本开始,linux 内核提供了一个叫做 Cgroups的特性。Cgroups是control groups的缩写,是一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如cpu,memory,IO等)的机制。

     
    2. Cgroups可以做什么?
    Cgroups最初的目标是为资源管理提供的一个统一的框架,既整合现有的cpuset等子系统,也为未来开发新的子系统提供接口。现在的cgroups适用于多种应用场景,从单个进程的资源控制,到实现操作系统层次的虚拟化(OS Level Virtualization)。Cgroups提供了一下功能:
    1.限制进程组可以使用的资源数量(Resource limiting )。比如:memory子系统可以为进程组设定一个memory使用上限,一旦进程组使用的内存达到限额再申请内存,就会出发OOM(out of memory)。
    2.进程组的优先级控制(Prioritization )。比如:可以使用cpu子系统为某个进程组分配特定cpu share。
    3.记录进程组使用的资源数量(Accounting )。比如:可以使用cpuacct子系统记录某个进程组使用的cpu时间
    4.进程组隔离(isolation)。比如:使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间。
    5.进程组控制(control)。比如:使用freezer子系统可以将进程组挂起和恢复。
     
    3. Cgroups相关概念及其关系
    相关概念
    1.任务(task):在cgroups中,任务就是系统的一个进程。 
    2.控制族群(control group):控制族群就是一组按照某种标准划分的进程。Cgroups中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用cgroups以控制族群为单位分配的资源,同时受到cgroups以控制族群为单位设定的限制。 
    3.层级(hierarchy):控制族群可以组织成hierarchical的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性。 
    4.子系统(subsytem):一个子系统就是一个资源控制器,比如cpu子系统就是控制cpu时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。
     
    相互关系
    1.每次在系统中创建新层级时,该系统中的所有任务都是那个层级的默认 cgroup(我们称之为 root cgroup ,此cgroup在创建层级时自动创建,后面在该层级中创建的cgroup都是此cgroup的后代)的初始成员。
    2.一个子系统最多只能附加到一个层级。
    3.一个层级可以附加多个子系统。
    4.一个任务可以是多个cgroup的成员,但是这些cgroup必须在不同的层级。
    5.系统中的进程(任务)创建子进程(任务)时,该子任务自动成为其父进程所在 cgroup 的成员。然后可根据需要将该子任务移动到不同的 cgroup 中,但开始时它总是继承其父任务 的cgroup。
     
    4. Cgroups 子系统介绍
    blkio -- 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等)。
    cpu -- 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。
    cpuacct -- 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。
    cpuset -- 这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。
    devices -- 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。
    freezer -- 这个子系统挂起或者恢复 cgroup 中的任务。
    memory -- 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
    net_cls -- 这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。
    ns -- 名称空间子系统。
     
    5. Cgroups用户空间管理
    Cgroups用户空间的管理是通过cgroup文件系统实现的。
    比如要创建一个层级:
    mount -t cgroup -o cpu,cpuset,memory cpu_and_mem /cgroup/cpu_and_mem 
    这个命令就创建一个名为cpu_and_mem的层级,这个层级上附加了cpu,cpuset,memory三个子系统,并把层级挂载到了/cgroup/cpu_and_mem. 
    创建一个cgroup: 
    cd /cgroup/cpu_and_mem 
    mkdir foo 
    通过以上两个命令,我们就在刚才创建的层级下创建了一个叫foo的cgroup。 
    你再cd foo,然后ls 你会发现一些文件,这是cgroups相关子系统的控制文件,你可以读取这些控制文件,这些控制文件存储的值就是对相应的cgrouop的控制信息,你也可以写控制文件来更改控制信息。 在这些文件中,有一个叫tasks的文件,里面的包含了所有属于这个cgroup的进程的进程号。
    在刚才创建的foo下,你cat tasks,应该是空的,因为此时这个cgroup里面还没有进程。你cd /cgroup/cpu_and_mem 再cat tasks,你可以看到系统中所有进程的进程号,这是因为每创建一个层级的时候,系统的所有进程都会自动被加到该层级的根cgroup里面。Tasks文件不仅可以读,还可以写,你将一个进程的进程号写入到某个cgroup目录下的tasks里面,你就将这个进程加入了相应的cgroup。
     
    6. 用 cgroups 管理 cpu 资源

    tasks 和 cgroups.procs 是用来管理控制组中的进程的。要把一个进程加入到某个控制组,把 pid 写入到相应目录的 tasks 文件即可。如
    # echo 5678 >/cgroup/cpu/rule3001/tasks
    就把 5678 进程加入到了 rule3001控制组。那么 tasks 和 cgroups.procs 有什么区别呢?前面说的对“进程”的管理限制其实不够准确。系统对任务调度的单位是线程。在这里,tasks 中看到的就是线程 id。而 cgroups.procs 中是线程组 id,也就是一般所说的进程 id 。将一个一般的 pid 写入到 tasks 中,只有这个 pid 对应的线程,以及由它产生的其他进程、线程会属于这个控制组,原有的其他线程则不会。而写入 cgroups.procs 会把当前所有的线程都加入进去。如果写入 cgroups.procs 的不是一个线程组 id,而是一个一般的线程 id,那会自动找到所对应的线程组 id 加入进去。进程在加入一个控制组后,控制组所对应的限制会即时生效。想知道一个进程属于哪些控制组,可以通过 cat /proc/<pid>/cgroup 查看。
    cpu.cfs_period_us 时间周期
    cpu.cfs_quota_us 在时间周期内可使用的 cpu 时间
    cpu.cfs_quota_us 也是可以大于 cpu.cfs_period_us 的,这主要是对于多核情况。有 n 个核时,一个控制组中的进程自然最多就能用到 n 倍的 cpu 时间。

    cpu.rt_period_us
    cpu.rt_runtime_us
    这两个对应的是实时进程的限制,平时可能不会有机会用到。

    cpu.shares 不是限制进程能使用的绝对的 cpu 时间,而是控制各个组之间的配额。
    比如
    /cpu/cpu.shares : 1024
    /cpu/foo/cpu.shares : 2048
    那么当两个组中的进程都满负荷运行时,/foo 中的进程所能占用的 cpu 就是 / 中的进程的两倍。如果再建一个 /foo/bar 的 cpu.shares 也是 1024,且也有满负荷运行的进程,那 /、/foo、/foo/bar 的 cpu 占用比就是 1:2:1 。前面说的是各自都跑满的情况。如果其他控制组中的进程闲着,那某一个组的进程完全可以用满全部 cpu。可见通常情况下,这种方式在保证公平的情况下能更充分利用资源。

    cpu.stat
    nr_periods 219736029
    nr_throttled 0
    throttled_time 0
    nr_periods、nr_throttled 就是总共经过的周期,和其中受限制的周期。throttled_time 就是总共被控制组掐掉的 cpu 使用时间。

    7. 用 cgroups 管理IO资源

     

    blkio 子系统里大部分都是只读的状态报告,可写的参数就只有下面这几个:
    blkio.throttle.read_bps_device
    blkio.throttle.read_iops_device
    blkio.throttle.write_bps_device
    blkio.throttle.write_iops_device
    blkio.weight
    blkio.weight_device
    这些都是用来控制进程的磁盘 io 的。

    blkio子模块有2种限制模式:
    1. throttle,限制每个进程能使用的IOPS或者吞吐量。
    2. weight,限制每个进程能使用的IOPS的能力的比例,必须通过CFQ调度器来实现。

    blkio子系统里有很多统计项,通过这些统计项更好地统计、监控进程的 io 情况。
    blkio.io_merged 各设​​​备​​​中各类型​​​ io 请求合并的次数​​​
    blkio.io_queued 各设​​​备​​​中各类型​​​ io 请求当前在队列中的数量​​​
    blkio.io_service_bytes 各类型​​​ io ​​​换入​​​者​​​或​​​出​​​各​​​设​​​备​​​​​​的​​​字​​​节​​​数​​​
    blkio.io_serviced 各设​​​备​​​中​​​执​​​行​​​的各类型​​​ io 操​​​作​​​数,分read、​​​write、​​​sync、async 和 total​​​
    blkio.io_service_time 各设​​​备​​​中​​​执​​​行​​​的各类型​​​ io 时间,单位微秒​​​
    blkio.io_wait_time 各设​​​备​​​中各类型​​​ io 在队列中的 等待时间​​​
    blkio.sectors 换入​​​或者换​​​出​​​各​​​设​​​备​​​的​​​扇​​​区​​​数
    blkio.time 各​​​设​​​备​​​的​​​ io 访​​​问​​​时​​​间,单位毫秒

     

    参考:

    http://www.cnblogs.com/lisperl/archive/2013/01/14/2860353.html#2761494

    http://xiezhenye.com/2013/10/linux-cgroups-%E6%A6%82%E8%BF%B0.html

  • 相关阅读:
    [CLK Framework] CLK.Settings
    [Architecture Design] CLK Architecture
    记一次 bug 修复 , 未将对象引用实例化
    Invoke 与 BeginInvoke 应用场景
    一次发布生产版程序异常排查总结
    C# 使用 SmtpClient 发送邮件注意项
    MSSql Server 批量插入数据优化
    Window Server 布署 WCF 服务 , 权限配置问题
    C++ 值类型和引用类型传递示例
    VS2015 C#调用C++ 托管代码无法调试问题排查
  • 原文地址:https://www.cnblogs.com/yuyue2014/p/3750963.html
Copyright © 2011-2022 走看看