Docker容器內存監控


linux內存監控

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

使用free命令可以查看當前內存使用情況。

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

這里有幾個概念:

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

可以參考這里

為方便說明,我對free的結果做了一個對應。

[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文件。

[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中相關數據進行取值從而計算得到。

cgroup

cgroup中的memory子系統為hierarchy提供了如下文件。

[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監控相關的。

文件名 說明
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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM