Docker容器內存監控

linux內存監控

要明白docker容器內存是如何計算的,首先要明白linux中內存的相關概念。html

使用free命令能夠查看當前內存使用狀況。linux

[root@localhost ~]$ free 
             total       used       free     shared    buffers     cached
Mem:     264420684  213853512   50567172   71822688    2095364  175733516
-/+ buffers/cache:   36024632  228396052
Swap:     16777212    1277964   15499248

這裏有幾個概念:git

  • mem: 物理內存
  • swap: 虛擬內存。便可以把數據存放在硬盤上的數據
  • shared: 共享內存。存在在物理內存中。
  • buffers: 用於存放要輸出到disk(塊設備)的數據的
  • cached: 存放從disk上讀出的數據

能夠參考這裏github

爲方便說明,我對free的結果作了一個對應。docker

[root@localhost ~]$ free 
             total       used       free        shared    buffers   cached
Mem:     total_mem   used_mem    free_mem   shared_mem    buffer     cache
-/+ buffers/cache:  real_used   real_free
Swap:   total_swap  used_swap   free_swap
名稱 說明
total_mem 物理內存總量
used_mem 已使用的物理內存量
free_mem 空閒的物理內存量
shared_mem 共享內存量
buffer buffer所佔內存量
cache cache所佔內存量
real_used 實際使用的內存量
real_free 實際空閒的內存量
total_swap swap總量
used_swap 已使用的swap
free_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文件。app

[root@localhost ~]$ cat /proc/meminfo 
MemTotal:       264420684 kB
MemFree:        50566436 kB
Buffers:         2095356 kB
Cached:         175732644 kB
SwapCached:       123688 kB
Active:         165515340 kB
Inactive:       37004224 kB
Active(anon):   92066880 kB
Inactive(anon):  4455076 kB
Active(file):   73448460 kB
Inactive(file): 32549148 kB
Unevictable:      362900 kB
Mlocked:           74696 kB
SwapTotal:      16777212 kB
SwapFree:       15499248 kB
Dirty:              2860 kB
Writeback:             0 kB
AnonPages:      24932928 kB
Mapped:         58165040 kB
Shmem:          71822688 kB
Slab:            8374496 kB
SReclaimable:    8163096 kB
SUnreclaim:       211400 kB
KernelStack:       45824 kB
PageTables:       606296 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    148987552 kB
Committed_AS:   114755628 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      772092 kB
VmallocChunk:   34225428328 kB
HardwareCorrupted:     0 kB
AnonHugePages:  22083584 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:        7168 kB
DirectMap2M:     2015232 kB
DirectMap1G:    266338304 kB

docker

說完linux的內存,咱們再來看下docker的內存監控。docker自身提供了一種內存監控的方式,便可以經過docker stats對容器內存進行監控。
該方式實際是經過對cgroup中相關數據進行取值從而計算獲得。tcp

cgroup

cgroup中的memory子系統爲hierarchy提供了以下文件。ide

[root@localhost ~]$ ll /cgroup/memory/docker/53a11f13c08099dd6d21030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f/
總用量 0
--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監控相關的。ui

文件名 說明
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 53a11f13c08099dd6d21030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f]$ cat memory.usage_in_bytes 
135021858816

[root@localhost 53a11f13c08099dd6d21030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f]$ cat memory.memsw.usage_in_bytes 
135679291392

[root@localhost 53a11f13c08099dd6d21030dd2ddade54d5cdd7ae7e9e68f5ba055ad28498b6f]$ cat memory.stat 
cache 134325506048
rss 695980032
mapped_file 16155119616
pgpgin 21654116032
pgpgout 21705492352
swap 655171584
inactive_anon 4218880
active_anon 74202603520
inactive_file 8365199360
active_file 52449439744
unevictable 0
hierarchical_memory_limit 137438953472
hierarchical_memsw_limit 274877906944
total_cache 134325506048
total_rss 695980032
total_mapped_file 16155119616
total_pgpgin 21654116032
total_pgpgout 21705492352
total_swap 655171584
total_inactive_anon 4218880
total_active_anon 74202603520
total_inactive_file 8365199360
total_active_file 52449439744
total_unevictable 0

memory.stat

memory.stat包含有最豐富的

統計 描述
cache 頁緩存,包括 tmpfs(shmem),單位爲字節
rss 匿名和 swap 緩存,不包括 tmpfs(shmem),單位爲字節
mapped_file memory-mapped 映射的文件大小,包括 tmpfs(shmem),單位爲字節
pgpgin 存入內存中的頁數
pgpgout 從內存中讀出的頁數
swap 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_bytesmemory.limit_in_bytes進行相除來計算使用率。這一方式有一個弊端,就是不夠細化,沒有區分出cache部分,不能真正反映內存使用率。由於通常來講cache是能夠複用的內存部分,所以通常將其計入到可以使用的部分。

能夠考慮的改進計算方式

改進方式在統計內存使用量時將cache計算排除出去。相似於linux中計算real_used時將buffercache排除同樣。

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)
相關文章
相關標籤/搜索