zoukankan      html  css  js  c++  java
  • Cgroup学习笔记

    1.什么是Cgroup
    Cgroups 是 control groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:cpu,memory,IO 等等)的机制。最初由 google 的工程师提出,后来被整合进 Linux 内核。Cgroups 也是 LXC 为实现虚拟化所使用的资源管理手段,可以说没有 cgroups 就没有 LXC。

    2.Cgroup可以做什么
    1.限制进程组可以使用的资源数量,限制进程最大使用的内存等。
    2.进程组的优先级控制,比如为某个进程组分配特定的cpu share。
    3.记录进程组使用的资源数量,比如记录某个进程CPU的使用时间。
    4.进程组隔离,比如通过namespace以达到隔离的目的。
    5.进程组控制,比如可以将进程组挂起或恢复。

    3.Cgroup的模型
    (1) 进程模型
    在说Cgroup的模型之前,先回顾下进程模型,在linux系统上,所有的进程都有一个共同的父进程,叫做init进程,这个进程在内核启动的时候开始执行,然后通过init进程启动其他的进程,这些进程都是init的子进程。因为所有的进程都有一个共同的父进程。那么linux的进程模型就是一个单继承层次的模型,或者称之为树状模型。除此之外每一个linux进程但是除了init进程,都继承了一些环境变量(例如PATH环境变量)。
    (2) Cgroup模型
    Cgroup其实和进程类似,Cgroup也是继承体系,并且子Cgroup继承其父Cgroup的某些属性,两者最基本的差别在于,进程是单继承体系。而Cgroup可以存在多个不同的继承体系(就是可以有多个单继承体系,每个单继承体系互不影响)。

    4.Cgroup的一些概念
    在Cgroup中有这样四个概念,可以说理解了这四个概念,那么对于如何使用Cgroup:

    Subsystems: 称之为子系统,一个子系统就是一个资源控制器,比如cpu子系统就是控制cpu时间分配的一个控制器。
    Hierarchies: 可以称之为层次体系,也可以称之为继承体系,指的是Control Groups是按照层次体系的关系进行组织的。
    Control Groups: 一组按照某种标准划分的进程。进程可以从一个Control Groups迁移到另外一个Control Groups中,同时Control Groups中的进程也会受到这个组的资源限制。
    Tasks: 在Cgroups中,Tasks就是系统的一个进程。

    5.Subsystems
    在Red_Hat_Enterprise_Linux-6系列的linux中,默认提供了如下子系统。

    blkio: 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等) 。
    cpu: 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。
    cpuacct: 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。
    cpuset: 这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。
    devices: 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。
    freezer: 这个子系统挂起或者恢复 cgroup 中的任务。
    memory: 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
    net_cls:这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。
    ns: 名称空间子系统。

    Ubuntu中的目录是/sys/fs/cgroup, 但是高通的Android手机中这个目录下是空的,存在于/dev目录下,cgroup.rc指定了各个文件的路径。

    /dev/cgroup_info # strings cgroup.rc
    blkio:/dev/blkio
    cgroup2:/dev/cg2_bpf /dev/cpuctl
    cpuacct:/acct
    cpuset:/dev/cpuset //system-background、top-app也在这里面。
    freezer:/dev/freezer
    memory:/dev/memcg
    schedtune:/dev/stune

    也可以# mount | grep cgroup 来查看都挂载在哪里了。

    6.Tasks文件不仅可以读,还可以写,你将一个进程的进程号写入到某个cgroup目录下的tasks里面,你就将这个进程加入了相应的cgroup。

    7.cgroup文件系统和VFS文件系统类似,cgroups的定义如下

    struct file_system_type cgroup_fs_type = {
        .name = "cgroup",
        .mount = cgroup_mount,
        .kill_sb = cgroup_kill_sb, //kill_sb释放超级块。
        .fs_flags = FS_USERNS_MOUNT,
    };

    8.Cgroup在kernel中的入口是:subsys_initcall(cgroup_sysfs_init); //msm-4.19kernelcgroupcgroup.c

    9.在cgroup文件系统中,对目录下的文件进行操作时,会调用struct kernfs_ops cgroup_kf_ops 结构体中指向的函数。比如:对文件进行读操作时,会调用 cgroup_file_read,在 cgroup_file_read 中,会根据需要调用该文件对应的 cftype 结构体定义的对应读函数。

    cgroups通过实现cgroup文件系统来为用户提供管理cgroup的工具,而cgroup文件系统是基于Linux VFS实现的。相应地,cgroups为控制文件定义了相应的数据结构cftype,对其操作由cgroup文件系统定义的通过操作捕获,再调用cftype定义的具体实现。

    cgroup中的每一个文件的后台动作都是 使用以空结尾的struct cftype数组来定义对cgroup文件进行操作时的后台动作,如 static struct cftype swap_files[] 通过模块初始化时执行cgroup_add_legacy_cftypes()添加到cgroup系统中,如 cgroup_add_legacy_cftypes(&memory_cgrp_subsys, memsw_cgroup_files)

    10.Cgroup是将任意进程进行分组化管理的Linux内核功能。cgroup本身提供将进程进行分组化管理的功能和接口的基础结构。而后的Android操作系统也就凭借着这个技术,为每个应用程序分配不同的cgroup,将每个程序进行隔离,达到了一个应用程序不会影响其他应用程序环境的目的。

    11.概念

    task:一个进程。
    control group:控制族群,按照某种标准划分的进程组。
    hierarchy:层级,control group可以形成树形的结构,有父节点,子节点,每个节点都是一个control group,子节点继承父节点的特定属性。
    subsystem:子系统。子系统就是资源控制器,每种子系统就是一个资源的分配器,比如cpu子系统是控制cpu时间分配的。

    可以使用lssubsys -al来列出系统支持多少种子系统,和使用ls /sys/fs/cgroup/(ubuntu)来显示已经挂载的子系统.

    12.# mount | grep cgroup可以看挂载目录,到对应的挂载目录下,创建一个文件夹,就创建了一个control group了。
    实验1:

    /dev/freezer # mkdir mytest
    /dev/freezer # ls mytest/
    cgroup.clone_children  cgroup.procs  freezer.parent_freezing  freezer.self_freezing  freezer.state  notify_on_release  tasks  yourtest
    /dev/freezer/mytest/ # echo $$ > tasks //当前shell进程就被设置进去了,之后更改属性文件的值可以对其进行设置。

    实验2:

    /dev/cpuset # mkdir mytest
    /dev/cpuset/mytest # echo "3" > cpus //使用CPU3
    /dev/cpuset/mytest # ps -A | grep system_server
    1772
    /dev/cpuset/mytest # echo 1772 > tasks

    上面操作就将system_server线程绑定到CPU3上了。

    实验3:

    /dev/memcg # mkdir my_mem_ctl
    /dev/memcg/my_mem_ctl # ls
    cgroup.clone_children  memory.kmem.failcnt             memory.kmem.tcp.limit_in_bytes      memory.max_usage_in_bytes        memory.move_charge_at_immigrate  memory.swappiness
    cgroup.event_control   memory.kmem.limit_in_bytes      memory.kmem.tcp.max_usage_in_bytes  memory.memsw.failcnt             memory.oom_control               memory.usage_in_bytes
    cgroup.procs           memory.kmem.max_usage_in_bytes  memory.kmem.tcp.usage_in_bytes      memory.memsw.limit_in_bytes      memory.pressure_level            memory.use_hierarchy
    memory.failcnt         memory.kmem.slabinfo            memory.kmem.usage_in_bytes          memory.memsw.max_usage_in_bytes  memory.soft_limit_in_bytes       notify_on_release
    memory.force_empty     memory.kmem.tcp.failcnt         memory.limit_in_bytes               memory.memsw.usage_in_bytes      memory.stat                      tasks
    /dev/memcg/my_mem_ctl # echo $$ > tasks
    /dev/memcg/my_mem_ctl # echo 10M > memory.limit_in_bytes
    /dev/memcg/my_mem_ctl # cat memory.limit_in_bytes
    10485760

    上面是限制当前shell进程最大使用10M内存。

    相关文件解释:

    memory.limit_in_bytes  显示当前内存(进程内存+页面内存)的使用量
    memory.memsw.usage_in_bytes  显示当前内存(进程内存+页面内存)+交换区的使用量
    memory.limit_in_bytes  设置、显示内存(进程内存+页面内存)使用量的限制值
    memory.memsw.limit_in_bytes  设置、显示内存(进程内存+页面内存)+交换区使用量的限制值
    memory.failcnt  显示当前内存(进程内存+页面内存)达到限制值的次数
    memory.memsw.failcnt 显示当前内存(进程内存+页面内存)+交换区达到限制值的次数
    memory.max_usage_in_bytes 显示记录的内存(进程内存+页面内存)使用量的最大值
    memory.memsw.max_usage_in_bytes 显示记录的内存(进程内存+页面内存)+交换区使用量的最大值
    memory.stat 输出统计信息
    memory.force_empty 强制释放分配给分组的内存
    memory.use_hierarchy  设置、显示层次结构的使用
    memory.swappiness  设置、显示针对分组的swappiness(相当于sysctl的vm.swappiness)

    参考:
    Linux Cgroups详解(三): https://www.cnblogs.com/lisperl/archive/2012/04/23/2466151.html?utm_medium=referral
    003_Linux的Cgroup<实例详解>: https://www.cnblogs.com/itcomputer/p/4634942.html

    TODO:
    Linux Cgroups详解(一):https://www.cnblogs.com/lisperl/archive/2012/04/17/2453838.html
    Linux Cgroups详解(二):https://www.cnblogs.com/lisperl/archive/2012/04/18/2455027.html
    LXC(Linux containers)快速入门:https://www.cnblogs.com/lisperl/archive/2012/04/15/2450183.html
    Linux Cgroup 入门教程:cpuset:https://zhuanlan.zhihu.com/p/121588317

  • 相关阅读:
    环境变量的配置
    java语言概述
    快捷键,功能键及常用的DOS命令
    html介绍
    Java web学习框架
    线程的使用
    Task类(任务)
    Parallel类(简化Task 操作)
    文件及数据流技术
    泛型的使用
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/13775811.html
Copyright © 2011-2022 走看看