写点什么

Cgroup memory 子系统

  • 2022 年 7 月 09 日
  • 本文字数:2325 字

    阅读完需:约 8 分钟

Cgroup memory子系统

本文是一系列对 cgroup 说明的文档,已期望说明 cgroup 子系统涉及的所有子系统,本文只对 memory 进行说明,本文的目录如下


  1. 什么是 memory ?

  2. cgroup memory 是如何实现的?

  3. runc cgroup memory 是如何调用的?

1 什么是 cgroup memory ?

cgroup memory 子系统又称为 Memory Resource Controller,通过为每个 cgroup 维护一个内存管理机制,控制处于所有属于该 cgroup 的进程对内存的使用方式。cgroup mem 有以下控制内存使用的目录内容:


 tasks         # 关联的任务线程 cgroup.procs       # 关联的任务进程 cgroup.event_control     # an interface for event_fd() memory.usage_in_bytes     # 当前已使用的内存 memory.memsw.usage_in_bytes   # 当前已使用的内存,swap memory.limit_in_bytes     # 当前限制的内存使用 memory.memsw.limit_in_bytes   # 当前限制的内存、swap memory.failcnt       # 当前达到内存阈值的次数 memory.memsw.failcnt     # 当前达到内存、swap阈值的次数 memory.max_usage_in_bytes   # 查看内存使用的最大值 memory.memsw.max_usage_in_bytes # 查看内存、swap使用的最大值 memory.soft_limit_in_bytes   # 设置/查看 soft limit of memory usage memory.stat       # 查看元数据 memory.use_hierarchy     # 设置/查看 hierarchical account enabled memory.force_empty     # trigger forced page reclaim memory.pressure_level     # set memory pressure notifications memory.swappiness     # set/show swappiness parameter of vmscan memory.move_charge_at_immigrate # set/show controls of moving charges memory.oom_control     # 设置/查看 oom 控制 memory.numa_stat     # show the number of memory usage per numa node memory.kmem.limit_in_bytes      # 设置/查看内核内存的硬件限制 memory.kmem.usage_in_bytes      # 查看当前内核内存分配 memory.kmem.failcnt             # 查看内核内存达到限制次数 memory.kmem.max_usage_in_bytes  # 查看内核内存最大使用量 memory.kmem.tcp.limit_in_bytes  # 查看/设置 tcp 缓存内存硬件限制 memory.kmem.tcp.usage_in_bytes  # 查看当前tcp 使用 memory.kmem.tcp.failcnt            # 查看当前tcp达到内存限制次数 memory.kmem.tcp.max_usage_in_bytes # 查看当前tcp buf内存使用最大限制
复制代码


以使用为例,使用 linux mem 提供的文件系统方式为例

# 限制内存使用$ echo 4M > /sys/fs/cgroup/memory/test/memory.limit_in_bytes# 查看内存使用$ cat /sys/fs/cgroup/memory/test/memory.limit_in_bytes4194304# 查看已使用内存$ cat /sys/fs/cgroup/memory/test/memory.usage_in_bytes1216512
复制代码

2 cgroup memory 是如何实现的 ?

                +--------------------+                |  mem_cgroup        |                |  (page_counter)    |                +--------------------+                 /            ^      \                /             |       \           +---------------+  |        +---------------+           | mm_struct     |  |....    | mm_struct     |           |               |  |        |               |           +---------------+  |        +---------------+                              |                              + --------------+                                              |           +---------------+           +------+--------+           | page          +---------->  page_cgroup|           |               |           |               |           +---------------+           +---------------+
复制代码

内存控制器的核心在于设计的 page_counter,page_counter 追踪当前的内存使用量以及进程内存的限制量。由 mem_cgroup 对每个关联的 cgroup 进行控制。


内存控制器工作原理:

  1. 每个 cgroup 都会发生 Accounting 操作。

  2. 每个 mm_struct 归属一个 cgroup。

  3. 每个 page 有一个指向 page_cgroup 的指针。


Accounting 操作流程为:

  1. 调用 mem_cgroup_charge_common() 设置必要的数据结构来检查内存是否超出使用限制。

  2. 如果超出使用限制,reclaim 被调用。

  3. 如果没有超出使用限制,page_cgroup 被更新,page_cgroup 以 LRU 方式管理

3 runc cgroup mem 是如何调用的?

目前的常见的容器技术 docker 底层其实是 runc 的调用实现,



runc 对内存的限制正是通过 cgroup 来实现的,以容器运行时中 runc 中的设置 mem 权限逻辑为例:

  1. 查看 swap、mem 是否需要更新 0 则不用更新

  2. swap 写入 memory.memsw.limit_in_bytes 文件,mem 写入 memory.limit_in_bytes 文件

相应的,查看对应的日志以及文件

[debug] write cgroup proc, dir=/sys/fs/cgroup/memory/user.slice/user-0.slice/session-537.scope/a, CgroupProcesses=cgroup.procs, pid=105820[debug] cgroup set swap writer file path=/sys/fs/cgroup/memory/user.slice/user-0.slice/session-537.scope/a/memory.limit_in_bytes val=0[debug] cgroup set swap writer file path=/sys/fs/cgroup/memory/user.slice/user-0.slice/session-537.scope/a/memory.memsw.limit_in_bytes val=0
cat /sys/fs/cgroup/memory/user.slice/user-0.slice/session-537.scope/a/memory.limit_in_bytes 9223372036854771712cat /sys/fs/cgroup/memory/user.slice/user-0.slice/session-537.scope/a/memory.memsw.limit_in_bytes 9223372036854771712
复制代码

参考文献

https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt

https://www.slideshare.net/Docker/container-performance-analysis-brendan-gregg-netflix

发布于: 刚刚阅读数: 3
用户头像

自顶向下 2020.11.01 加入

还未添加个人简介

评论

发布
暂无评论
Cgroup memory子系统_总想做点什么_InfoQ写作社区