如何设置docker 容器 内存分配容器中Java应用的内存限制

Docker(4)
Docker 运行时资源限制
Docker 基于 Linux 内核提供的 cgroups 功能,可以限制容器在运行时使用到的资源,比如内存、CPU、块 I/O、网络等。
Docker 提供的内存限制功能有以下几点:
容器能使用的内存和交换分区大小。
容器的核心内存大小。
容器虚拟内存的交换行为。
容器内存的软性限制。
是否杀死占用过多内存的容器。
容器被杀死的优先级
一般情况下,达到内存限制的容器过段时间后就会被系统杀死。
内存限制相关的参数
执行docker run命令时能使用的和内存限制相关的所有选项如下。
-m,--memory
内存限制,格式是数字加单位,单位可以为 b,k,m,g。最小为 4M
--memory-swap
内存+交换分区大小总限制。格式同上。必须必-m设置的大
--memory-reservation
内存的软性限制。格式同上
--oom-kill-disable
是否阻止 OOM killer 杀死容器,默认没设置
--oom-score-adj
容器被 OOM killer 杀死的优先级,范围是[-],默认为 0
--memory-swappiness
用于设置容器的虚拟内存控制行为。值为 0~100 之间的整数
--kernel-memory
核心内存限制。格式同上,最小为 4M
用户内存限制
用户内存限制就是对容器能使用的内存和交换分区的大小作出限制。使用时要遵循两条直观的规则:-m,--memory选项的参数最小为 4 M。--memory-swap不是交换分区,而是内存加交换分区的总大小,所以--memory-swap必须比-m,--memory大。在这两条规则下,一般有四种设置方式。
你可能在进行内存限制的实验时发现docker run命令报错:WARNING: Your kernel does not support swap limit capabilities, memory limited without swap.
这是因为宿主机内核的相关功能没有打开。按照下面的设置就行。
step 1:编辑/etc/default/grub文件,将GRUB_CMDLINE_LINUX一行改为GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
step 2:更新 GRUB,即执行$ sudo update-grub
step 3: 重启系统。
如果不设置-m,--memory和--memory-swap,容器默认可以用完宿舍机的所有内存和 swap 分区。不过注意,如果容器占用宿主机的所有内存和 swap 分区超过一段时间后,会被宿主机系统杀死(如果没有设置--00m-kill-disable=true的话)。
2. 设置-m,--memory,不设置--memory-swap
给-m或--memory设置一个不小于 4M 的值,假设为 a,不设置--memory-swap,或将--memory-swap设置为 0。这种情况下,容器能使用的内存大小为 a,能使用的交换分区大小也为 a。因为 Docker 默认容器交换分区的大小和内存相同。
如果在容器中运行一个一直不停申请内存的程序,你会观察到该程序最终能占用的内存大小为 2a。
比如$ docker run -m 1G ubuntu:16.04,该容器能使用的内存大小为 1G,能使用的 swap 分区大小也为 1G。容器内的进程能申请到的总内存大小为 2G。
3. 设置-m,--memory=a,--memory-swap=b,且b & a
给-m设置一个参数 a,给--memory-swap设置一个参数 b。a 时容器能使用的内存大小,b是容器能使用的 内存大小 + swap 分区大小。所以 b 必须大于 a。b -a 即为容器能使用的 swap 分区大小。
比如$ docker run -m 1G --memory-swap 3G ubuntu:16.04,该容器能使用的内存大小为 1G,能使用的 swap 分区大小为 2G。容器内的进程能申请到的总内存大小为 3G。
4. 设置-m,--memory=a,--memory-swap=-1
给-m参数设置一个正常值,而给--memory-swap设置成 -1。这种情况表示限制容器能使用的内存大小为 a,而不限制容器能使用的 swap 分区大小。
这时候,容器内进程能申请到的内存大小为 a + 宿主机的 swap 大小。
Memory reservation
这种 memory reservation 机制不知道怎么翻译比较形象。Memory reservation 是一种软性限制,用于节制容器内存使用。给--memory-reservation设置一个比-m小的值后,虽然容器最多可以使用-m使用的内存大小,但在宿主机内存资源紧张时,在系统的下次内存回收时,系统会回收容器的部分内存页,强迫容器的内存占用回到--memory-reservation设置的值大小。
没有设置时(默认情况下)--memory-reservation的值和-m的限定的值相同。将它设置为 0 会设置的比-m的参数大 等同于没有设置。
Memory reservation 是一种软性机制,它不保证任何时刻容器使用的内存不会超过--memory-reservation限定的值,它只是确保容器不会长时间占用超过--memory-reservation限制的内存大小。
$ docker run -it -m 500M
如果容器使用了大于 200M 但小于 500M 内存时,下次系统的内存回收会尝试将容器的内存锁紧到 200M 以下。
$ docker run -it
容器可以使用尽可能多的内存。--memory-reservation确保容器不会长时间占用太多内存。
OOM killer
默认情况下,在出现 out-of-memory(OOM) 错误时,系统会杀死容器内的进程来获取更多空闲内存。这个杀死进程来节省内存的进程,我们姑且叫它 OOM killer。我们可以通过设置--oom-kill-disable选项来禁止 OOM killer 杀死容器内进程。但请确保只有在使用了-m/--memory选项时才使用--oom-kill-disable禁用 OOM killer。如果没有设置-m选项,却禁用了 OOM-killer,可能会造成出现 out-of-memory 错误时,系统通过杀死宿主机进程或获取更改内存。
下面的例子限制了容器的内存为 100M 并禁止了 OOM killer:
$ docker run -it -m 100M --oom-kill-disable ubuntu:16.04 /bin/bash
是正确的使用方法。
而下面这个容器没设置内存限制,却禁用了 OOM killer 是非常危险的:
$ docker run -it
容器没用内存限制,可能或导致系统无内存可用,并尝试时杀死系统进程来获取更多可用内存。
一般一个容器只有一个进程,这个唯一进程被杀死,容器也就被杀死了。我们可以通过--oom-score-adj选项来设置在系统内存不够时,容器被杀死的优先级。负值更教不可能被杀死,而正值更有可能被杀死。
核心内存和用户内存不同的地方在于核心内存不能被交换出。不能交换出去的特性使得容器可以通过消耗太多内存来堵塞一些系统服务。核心内存包括:
stack pages(栈页面)
slab pages
socket memory pressure
tcp memory pressure
可以通过设置核心内存限制来约束这些内存。例如,每个进程都要消耗一些栈页面,通过限制核心内存,可以在核心内存使用过多时阻止新进程被创建。
核心内存和用户内存并不是独立的,必须在用户内存限制的上下文中限制核心内存。
假设用户内存的限制值为 U,核心内存的限制值为 K。有三种可能地限制核心内存的方式:
U != 0,不限制核心内存。这是默认的标准设置方式
K & U,核心内存时用户内存的子集。这种设置在部署时,每个 cgroup 的内存总量被过度使用。过度使用核心内存限制是绝不推荐的,因为系统还是会用完不能回收的内存。在这种情况下,你可以设置 K,这样 groups 的总数就不会超过总内存了。然后,根据系统服务的质量自有地设置 U。
K & U,因为核心内存的变化也会导致用户计数器的变化,容器核心内存和用户内存都会触发回收行为。这种配置可以让管理员以一种统一的视图看待内存。对想跟踪核心内存使用情况的用户也是有用的。
$ docker run -it -m 500M
容器中的进程最多能使用 500M 内存,在这 500M 中,最多只有 50M 核心内存。
$ docker run -it
没用设置用户内存限制,所以容器中的进程可以使用尽可能多的内存,但是最多能使用 50M 核心内存。
Swappiness
默认情况下,容器的内核可以交换出一定比例的匿名页。--memory-swappiness就是用来设置这个比例的。--memory-swappiness可以设置为从 0 到 100。0 表示关闭匿名页面交换。100 表示所有的匿名页都可以交换。默认情况下,如果不适用--memory-swappiness,则该值从父进程继承而来。
$ docker run -it
将--memory-swappiness设置为 0 可以保持容器的工作集,避免交换代理的性能损失。
Docker 的资源限制和隔离完全基于 Linux cgroups。对 CPU 资源的限制方式也和 cgroups 相同。Docker 提供的 CPU 资源限制选项可以在多核系统上限制容器能利用哪些 vCPU。而对容器最多能使用的 CPU 时间有两种限制方式:一是有多个 CPU 密集型的容器竞争 CPU 时,设置各个容器能使用的 CPU 时间相对比例。二是以绝对的方式设置容器在每个调度周期内最多能使用的 CPU 时间。
CPU 限制相关参数
docker run命令和 CPU 限制相关的所有选项如下:
--cpuset-cpus=""
允许使用的 CPU 集,值可以为 0-3,0,1
-c,--cpu-shares=0
CPU 共享权值(相对权重)
cpu-period=0
限制 CPU CFS 的周期,范围从 100ms~1s,即[0]
--cpu-quota=0
限制 CPU CFS 配额,必须不小于1ms,即 &= 1000
--cpuset-mems=""
允许在上执行的内存节点(MEMs),只对 NUMA 系统有效
其中--cpuset-cpus用于设置容器可以使用的 vCPU 核。-c,--cpu-shares用于设置多个容器竞争 CPU 时,各个容器相对能分配到的 CPU 时间比例。--cpu-period和--cpu-quata用于绝对设置容器能使用 CPU 时间。
--cpuset-mems暂用不上,这里不谈。
我们可以设置容器可以在哪些 CPU 核上运行。
$ docker run -it
表示容器中的进程可以在 cpu 1 和 cpu 3 上执行。
$ docker run -it
表示容器中的进程可以在 cpu 0、cpu 1 及 cpu 3 上执行。
在 NUMA 系统上,我们可以设置容器可以使用的内存节点。
$ docker run -it
表示容器中的进程只能使用内存节点 1 和 3 上的内存。
$ docker run -it
表示容器中的进程只能使用内存节点 0、1、2 上的内存。
CPU 资源的相对限制
默认情况下,所有的容器得到同等比例的 CPU 周期。在有多个容器竞争 CPU 时我们可以设置每个容器能使用的 CPU 时间比例。这个比例叫作共享权值,通过-c或--cpu-shares设置。Docker 默认每个容器的权值为 1024。不设置或将其设置为 0,都将使用这个默认值。系统会根据每个容器的共享权值和所有容器共享权值和比例来给容器分配 CPU 时间。
假设有三个正在运行的容器,这三个容器中的任务都是 CPU 密集型的。第一个容器的 cpu 共享权值是 1024,其它两个容器的 cpu 共享权值是 512。第一个容器将得到 50% 的 CPU 时间,而其它两个容器就只能各得到 25% 的 CPU 时间了。如果再添加第四个 cpu 共享值为 1024 的容器,每个容器得到的 CPU 时间将重新计算。第一个容器的CPU 时间变为 33%,其它容器分得的 CPU 时间分别为 16.5%、16.5%、33%。
必须注意的是,这个比例只有在 CPU 密集型的任务执行时才有用。在四核的系统上,假设有四个单进程的容器,它们都能各自使用一个核的 100% CPU 时间,不管它们的 cpu 共享权值是多少。
在多核系统上,CPU 时间权值是在所有 CPU 核上计算的。即使某个容器的 CPU 时间限制少于 100%,它也能使用各个 CPU 核的 100% 时间。
例如,假设有一个不止三核的系统。用-c=512的选项启动容器{C0},并且该容器只有一个进程,用-c=1024的启动选项为启动容器C2,并且该容器有两个进程。CPU 权值的分布可能是这样的:
CPU CPU share
CPU 资源的绝对限制
Linux 通过 CFS(Completely Fair Scheduler,完全公平调度器)来调度各个进程对 CPU 的使用。CFS 默认的调度周期是 100ms。
的更多信息,参考。
我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少 CPU 时间。使用--cpu-period即可设置调度周期,使用--cpu-quota即可设置在每个周期内容器能使用的 CPU 时间。两者一般配合使用。
$ docker run -it
将 CFS 调度的周期设为 50000,将容器在每个周期内的 CPU 配额设置为 25000,表示该容器每 50ms 可以得到 50% 的 CPU 运行时间。
$ docker run -it
将容器的 CPU 配额设置为 CFS 周期的两倍,CPU 使用时间怎么会比周期大呢?其实很好解释,给容器分配两个 vCPU 就可以了。该配置表示容器可以在每个周期内使用两个 vCPU 的 100% 时间。
周期的有效范围是 1ms~1s,对应的--cpu-period的数值范围是 。而容器的 CPU 配额必须不小于 1ms,即--cpu-quota的值必须 &= 1000。可以看出这两个选项的单位都是 us。
正确的理解“绝对”
注意前面我们用--cpu-quota设置容器在一个调度周期内能使用的 CPU 时间时实际上设置的是一个上限。并不是说容器一定会使用这么长的 CPU 时间。比如,我们先启动一个容器,将其绑定到 cpu 1 上执行。给其--cpu-quota和--cpu-period都设置为 50000。
--- --- -..-
调度周期为 50000,容器在每个周期内最多能使用 50000 cpu 时间。
再用docker stats test01可以观察到该容器对 CPU 的使用率在100%左右。然后,我们再以同样的参数启动另一个容器。
--- --- -..-
再用docker stats test01 test02可以观察到这两个容器,每个容器对 cpu 的使用率在 50% 左右。说明容器并没有在每个周期内使用 50000 的 cpu 时间。
使用docker stop test02命令结束第二个容器,再加一个参数-c 2048启动它:
再用docker stats test01命令可以观察到第一个容器的 CPU 使用率在 33% 左右,第二个容器的 CPU 使用率在 66% 左右。因为第二个容器的共享值是 2048,第一个容器的默认共享值是 1024,所以第二个容器在每个周期内能使用的 CPU 时间是第一个容器的两倍。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:260079次
积分:4104
积分:4104
排名:第6064名
原创:126篇
评论:231条
(1)(4)(3)(1)(1)(2)(3)(2)(1)(2)(1)(1)(3)(1)(3)(3)(3)(7)(14)(13)(5)(1)(3)(1)(4)(1)(3)(1)(11)(2)(2)(21)(1)(5)(1)docker高级应用(CPU与内存资源限制) - 推酷
docker高级应用(CPU与内存资源限制)
本篇讲的就是利用docker本身的参数进行CPU与内存资源的限制。
1、内存限制
默认docker内存限制可以使用-m参数进行限制,但如果只使用-m参数,不添加其他的,那么内存限制不会限制死,比如-m 256m内存,那么容器里程序可以跑到2*256m后才会被杀死。
原因就是:源码里
memory.memsw.limit_in_bytes
值是被设置成我们指定的内存参数的2倍。
源码地址:
// By default, MemorySwap is set to twice the size of RAM.
// If you want to omit MemorySwap, set it to `-1'.
if d.c.MemorySwap != -1 {
if err := writeFile(dir, &memory.memsw.limit_in_bytes&, strconv.FormatInt(d.c.Memory*2, 10)); err != nil {
return err
测试一下:
限制内存为2G
docker run --privileged -d
--cpuset-cpus=&0,1& -m 2048m --name java101 javatest2:8 /sbin/init
# docker exec -it d3ed bash
进入容器使用stress进行内存测试。
安装stress
stress是一个压力测试工具,可测试服务器负载情况
安装命令:
# rpm -Uvh http://pkgs.repoforge.org/stress/stress-1.0.2-1.el7.rf.x86_64.rpm
使用stress进行测试
[root@60fcca8ba4db ~]# stress --vm 1 --vm-bytes 4089M --vm-hang 0
这个命令是跑4089M的内存
参数说明:
--vm-bytes B&& 指定malloc时内存的字节数(默认256MB)
--vm-hang N 指定在free前的秒数
--vm 1 产生1个进程,每个进程不断调用内存分配malloc和内存释放free函数
[root@60fcca8ba4db ~]# stress --vm 1 --vm-bytes 4089M --vm-hang 0
stress: info: [674] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [674] (420) &-- worker 675 got signal 9
stress: WARN: [674] (422) now reaping child worker processes
stress: FAIL: [674] (456) failed run completed in 37s
可以看到程序死了,查看原因
[root@60fcca8ba4db ~]# cat /var/log/messages
Mar 21 15:27:52 60fcca8ba4db kernel: Task in /system.slice/docker-60fcca8ba4dbd08c6f064e0bd7be2887bdb301cf28bce9bee2201e.scope killed as a result of limit of /system.slice/docker-60fcca8ba4dbd08c6f064e0bd7be2887bdb301cf28bce9bee2201e.scope
Mar 21 15:27:52 60fcca8ba4db kernel: memory: usage 2097152kB, limit 2097152kB, failcnt 368074
Mar 21 15:27:52 60fcca8ba4db kernel: memory+swap: usage 3827916kB, limit 0991kB, failcnt 0
Mar 21 15:27:52 60fcca8ba4db kernel: kmem: usage 0kB, limit 0991kB, failcnt 0
Mar 21 15:27:52 60fcca8ba4db kernel: Memory cgroup stats for /system.slice/docker-60fcca8ba4dbd08c6f064e0bd7be2887bdb301cf28bce9bee2201e.scope: cache:2516KB rss:2094636KB rss_huge:0KB mapped_file:2444KB swap:1730764KB inactive_anon:527536KB active_anon:1569412KB inactive_file:56KB active_file:20KB unevictable:0KB
Mar 21 15:27:52 60fcca8ba4db kernel: [ pid ]
tgid total_vm
rss nr_ptes swapents oom_score_adj name
Mar 21 15:27:52 60fcca8ba4db kernel: [ 1057]
Mar 21 15:27:52 60fcca8ba4db kernel: [ 1079]
0 systemd-journal
Mar 21 15:27:52 60fcca8ba4db kernel: [ 1091]
-1000 systemd-udevd
Mar 21 15:27:52 60fcca8ba4db kernel: [ 1191]
-1000 sshd
Mar 21 15:27:52 60fcca8ba4db kernel: [ 1193]
0 rsyslogd
Mar 21 15:27:52 60fcca8ba4db kernel: [ 1194]
-900 dbus-daemon
Mar 21 15:27:52 60fcca8ba4db kernel: [ 1203]
0 firewalld
Mar 21 15:27:52 60fcca8ba4db kernel: [ 1204]
0 systemd-logind
Mar 21 15:27:52 60fcca8ba4db kernel: [ 1210]
Mar 21 15:27:52 60fcca8ba4db kernel: [ 2191]
Mar 21 15:27:52 60fcca8ba4db kernel: [ 2194]
Mar 21 15:27:52 60fcca8ba4db kernel: [ 4536]
Mar 21 15:27:52 60fcca8ba4db kernel: [ 5706]
Mar 21 15:27:52 60fcca8ba4db kernel: [ 8006]
Mar 21 15:27:52 60fcca8ba4db kernel: [ 8007]
Mar 21 15:27:52 60fcca8ba4db kernel: Memory cgroup out of memory: Kill process 8007 (stress) score 877 or sacrifice child
Mar 21 15:27:52 60fcca8ba4db kernel: Killed process 8007 (stress) total-vm:4194400kB, anon-rss:2076316kB, file-rss:4kB
Mar 21 15:27:52 60fcca8ba4db root: [euid=root]:root pts/0 Mar 21 14:40 (192.168.7.173):[/root] 15:27:15 rootstress --vm 1 --vm-bytes 4089M --vm-hang 0
Mar 21 15:30:01 60fcca8ba4db systemd: Started Session 35096 of user root.
Mar 21 15:30:01 60fcca8ba4db systemd: Starting Session 35096 of user root.
显示内存使用超过2倍限制的内存,所以进行oom kill掉stress的进程,但容器不会死,仍然能正常运行。
但如果你想写死内存,可以使用
-m 2048m --memory-swap=2048m
这样就直接限制死,只要程序内存使用超过1024m,那么就会被oom给kill。
2、CPU限制
目前CPU限制可以使用绑定到具体的线程,或者是在绑定线程基础上对线程资源权重分配。
绑定线程可以使用参数--cpuset-cpus=7 ,分配线程呢可以使用参数-c 来给权重
docker run --privileged -d -c 1024 --cpuset-cpus=&4,5& -m 2048m --name java52 javatest2:8 /sbin/init
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致Docker 容器内存监控原理及应用
作者:XuXinkun
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Docker 容器内存监控原理及应用的相关资料,需要的朋友可以参考下
Docker 容器内存监控
linux内存监控
要明白docker容器内存是如何计算的,首先要明白linux中内存的相关概念。
使用free命令可以查看当前内存使用情况。
[root@localhost ~]$ free
-/+ buffers/cache:
这里有几个概念:
mem: 物理内存
swap: 虚拟内存。即可以把数据存放在硬盘上的数据
shared: 共享内存。存在在物理内存中。
buffers: 用于存放要输出到disk(块设备)的数据的
cached: 存放从disk上读出的数据
可以参考这里。
为方便说明,我对free的结果做了一个对应。
[root@localhost ~]$ free
shared_mem
-/+ buffers/cache: real_used
total_swap used_swap
物理内存总量
已使用的物理内存量
空闲的物理内存量
shared_mem
共享内存量
buffer所占内存量
cache所占内存量
实际使用的内存量
实际空闲的内存量
total_swap
已使用的swap
空闲的swap
一般认为,buffer和cache是还可以再进行利用的内存,所以在计算空闲内存时,会将其剔除。
因此这里有几个等式:
real_used = used_mem - buffer - cache
real_free = free_mem + buffer + cache
total_mem = used_mem + free_mem
了解了这些,我们再来看free的数据源。其实其数据源是来自于/proc/memeinfo文件。
[root@localhost ~]$ cat /proc/meminfo
2095356 kB
SwapCached:
Active(anon):
Inactive(anon): 4455076 kB
Active(file):
Inactive(file):
Unevictable:
SwapTotal:
Writeback:
AnonPages:
8374496 kB
SReclaimable:
8163096 kB
SUnreclaim:
KernelStack:
PageTables:
NFS_Unstable:
WritebackTmp:
CommitLimit:
Committed_AS:
VmallocTotal:
VmallocUsed:
VmallocChunk:
HardwareCorrupted:
AnonHugePages:
HugePages_Total:
HugePages_Free:
HugePages_Rsvd:
HugePages_Surp:
Hugepagesize:
DirectMap4k:
DirectMap2M:
2015232 kB
DirectMap1G:
说完linux的内存,我们再来看下docker的内存监控。docker自身提供了一种内存监控的方式,即可以通过docker stats对容器内存进行监控。
该方式实际是通过对cgroup中相关数据进行取值从而计算得到。
cgroup中的memory子系统为hierarchy提供了如下文件。
[root@localhost ~]$ ll /cgroup/memory/docker/53a11f13c030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f/
--w--w--w- 1 root root 0 2月 22 12:51 cgroup.event_control
-rw-r--r-- 1 root root 0 5月 25 17:07 cgroup.procs
-rw-r--r-- 1 root root 0 2月 22 12:51 memory.failcnt
--w------- 1 root root 0 2月 22 12:51 memory.force_empty
-rw-r--r-- 1 root root 0 3月 30 17:06 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 2月 22 12:51 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 2月 22 12:51 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 3月 30 17:06 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 2月 22 12:51 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 2月 22 12:51 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 2月 22 12:51 memory.move_charge_at_immigrate
-rw-r--r-- 1 root root 0 2月 22 12:51 memory.oom_control
-rw-r--r-- 1 root root 0 3月 30 17:06 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 2月 22 12:51 memory.stat
-rw-r--r-- 1 root root 0 2月 22 12:51 memory.swappiness
-r--r--r-- 1 root root 0 2月 22 12:51 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 2月 22 12:51 memory.use_hierarchy
-rw-r--r-- 1 root root 0 2月 22 12:51 notify_on_release
-rw-r--r-- 1 root root 0 2月 22 12:51 tasks
这些文件的具体含义可以查看相关资料cgroup memory。
这里主要介绍几个与docker监控相关的。
memory.usage_in_bytes
已使用的内存量(包含cache和buffer)(字节),相当于linux的used_meme
memory.limit_in_bytes
限制的内存总量(字节),相当于linux的total_mem
memory.failcnt
申请内存失败次数计数
memory.memsw.usage_in_bytes
已使用的内存和swap(字节)
memory.memsw.limit_in_bytes
限制的内存和swap容量(字节)
memory.memsw.failcnt
申请内存和swap失败次数计数
memory.stat
内存相关状态
以下为一个容器的样例。
[root@localhost 53a11f13c030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f]$ cat memory.usage_in_bytes
[root@localhost 53a11f13c030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f]$ cat memory.memsw.usage_in_bytes
[root@localhost 53a11f13c030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f]$ cat memory.stat
mapped_file
inactive_anon 4218880
active_anon
inactive_file
active_file
unevictable 0
hierarchical_memory_limit
hierarchical_memsw_limit
total_cache
total_mapped_file
total_pgpgin
total_pgpgout
total_swap
total_inactive_anon 4218880
total_active_anon
total_inactive_file
total_active_file
total_unevictable 0
memory.stat
memory.stat包含有最丰富的
页缓存,包括 tmpfs(shmem),单位为字节
匿名和 swap 缓存,不包括 tmpfs(shmem),单位为字节
mapped_file
memory-mapped 映射的文件大小,包括 tmpfs(shmem),单位为字节
存入内存中的页数
从内存中读出的页数
swap 用量,单位为字节
active_anon
在活跃的最近最少使用(least-recently-used,LRU)列表中的匿名和 swap 缓存,包括 tmpfs(shmem),单位为字节
inactive_anon
不活跃的 LRU 列表中的匿名和 swap 缓存,包括 tmpfs(shmem),单位为字节
active_file
活跃 LRU 列表中的 file-backed 内存,以字节为单位
inactive_file
不活跃 LRU 列表中的 file-backed 内存,以字节为单位
unevictable
无法再生的内存,以字节为单位
hierarchical_memory_limit
包含 memory cgroup 的层级的内存限制,单位为字节
hierarchical_memsw_limit
包含 memory cgroup 的层级的内存加 swap 限制,单位为字节
active_anon + inactive_anon = anonymous memory + file cache for tmpfs + swap cache
active_file + inactive_file = cache - size of tmpfs
docker原生内存监控
再来说到docker原生的docker stats。其具体实现在libcontainer中可以看到。其将容器的内存监控分为cache,usage,swap usage,kernel usage,kernel tcp usage。
其中cache是从memory.stat中的cache中获取。
usage是使用memory.usage_in_bytes和memory.limit_in_bytes进行相除来计算使用率。这一方式有一个弊端,就是不够细化,没有区分出cache部分,不能真正反映内存使用率。因为一般来说cache是可以复用的内存部分,因此一般将其计入到可使用的部分。
可以考虑的改进计算方式
改进方式在统计内存使用量时将cache计算排除出去。类似于linux中计算real_used时将buffer和cache排除一样。
cache并不能直接应用memory.stat中的cache,因为其中包括了tmpfs,而tmpfs算是实际使用的内存部分。
tmpfs即share memory,共享内存
因为在memory.stat中存在有
active_file + inactive_file = cache - size of tmpfs
因此可以计算实际使用的内存量为
real_used = memory.usage_in_bytes - (rss + active_file + inactive_file)
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 docker限制容器内存 的文章

 

随机推荐