Docker 容器內(nèi)存監(jiān)控原理及應(yīng)用
Docker 容器內(nèi)存監(jiān)控
linux內(nèi)存監(jiān)控
要明白docker容器內(nèi)存是如何計算的,首先要明白linux中內(nèi)存的相關(guān)概念。
使用free命令可以查看當(dāng)前內(nèi)存使用情況。
[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: 物理內(nèi)存
- swap: 虛擬內(nèi)存。即可以把數(shù)據(jù)存放在硬盤上的數(shù)據(jù)
- shared: 共享內(nèi)存。存在在物理內(nèi)存中。
- buffers: 用于存放要輸出到disk(塊設(shè)備)的數(shù)據(jù)的
- cached: 存放從disk上讀出的數(shù)據(jù)
可以參考這里。
為方便說明,我對free的結(jié)果做了一個對應(yīng)。
[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 | 物理內(nèi)存總量 |
used_mem | 已使用的物理內(nèi)存量 |
free_mem | 空閑的物理內(nèi)存量 |
shared_mem | 共享內(nèi)存量 |
buffer | buffer所占內(nèi)存量 |
cache | cache所占內(nèi)存量 |
real_used | 實際使用的內(nèi)存量 |
real_free | 實際空閑的內(nèi)存量 |
total_swap | swap總量 |
used_swap | 已使用的swap |
free_swap | 空閑的swap |
一般認為,buffer和cache是還可以再進行利用的內(nèi)存,所以在計算空閑內(nèi)存時,會將其剔除。
因此這里有幾個等式:
real_used = used_mem - buffer - cache real_free = free_mem + buffer + cache total_mem = used_mem + free_mem
了解了這些,我們再來看free的數(shù)據(jù)源。其實其數(shù)據(jù)源是來自于/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的內(nèi)存,我們再來看下docker的內(nèi)存監(jiān)控。docker自身提供了一種內(nèi)存監(jiān)控的方式,即可以通過docker stats對容器內(nèi)存進行監(jiān)控。
該方式實際是通過對cgroup中相關(guān)數(shù)據(jù)進行取值從而計算得到。
cgroup
cgroup中的memory子系統(tǒng)為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
這些文件的具體含義可以查看相關(guān)資料cgroup memory。
這里主要介紹幾個與docker監(jiān)控相關(guān)的。
文件名 | 說明 |
---|---|
memory.usage_in_bytes | 已使用的內(nèi)存量(包含cache和buffer)(字節(jié)),相當(dāng)于linux的used_meme |
memory.limit_in_bytes | 限制的內(nèi)存總量(字節(jié)),相當(dāng)于linux的total_mem |
memory.failcnt | 申請內(nèi)存失敗次數(shù)計數(shù) |
memory.memsw.usage_in_bytes | 已使用的內(nèi)存和swap(字節(jié)) |
memory.memsw.limit_in_bytes | 限制的內(nèi)存和swap容量(字節(jié)) |
memory.memsw.failcnt | 申請內(nèi)存和swap失敗次數(shù)計數(shù) |
memory.stat | 內(nèi)存相關(guān)狀態(tài) |
以下為一個容器的樣例。
[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包含有最豐富的
統(tǒng)計 | 描述 |
---|---|
cache | 頁緩存,包括 tmpfs(shmem),單位為字節(jié) |
rss | 匿名和 swap 緩存,不包括 tmpfs(shmem),單位為字節(jié) |
mapped_file | memory-mapped 映射的文件大小,包括 tmpfs(shmem),單位為字節(jié) |
pgpgin | 存入內(nèi)存中的頁數(shù) |
pgpgout | 從內(nèi)存中讀出的頁數(shù) |
swap | swap 用量,單位為字節(jié) |
active_anon | 在活躍的最近最少使用(least-recently-used,LRU)列表中的匿名和 swap 緩存,包括 tmpfs(shmem),單位為字節(jié) |
inactive_anon | 不活躍的 LRU 列表中的匿名和 swap 緩存,包括 tmpfs(shmem),單位為字節(jié) |
active_file | 活躍 LRU 列表中的 file-backed 內(nèi)存,以字節(jié)為單位 |
inactive_file | 不活躍 LRU 列表中的 file-backed 內(nèi)存,以字節(jié)為單位 |
unevictable | 無法再生的內(nèi)存,以字節(jié)為單位 |
hierarchical_memory_limit | 包含 memory cgroup 的層級的內(nèi)存限制,單位為字節(jié) |
hierarchical_memsw_limit | 包含 memory cgroup 的層級的內(nèi)存加 swap 限制,單位為字節(jié) |
active_anon + inactive_anon = anonymous memory + file cache for tmpfs + swap cache
active_file + inactive_file = cache - size of tmpfs
docker原生內(nèi)存監(jiān)控
再來說到docker原生的docker stats。其具體實現(xiàn)在libcontainer中可以看到。其將容器的內(nèi)存監(jiān)控分為cache,usage,swap usage,kernel usage,kernel tcp usage。
其中cache是從memory.stat中的cache中獲取。
usage是使用memory.usage_in_bytes和memory.limit_in_bytes進行相除來計算使用率。這一方式有一個弊端,就是不夠細化,沒有區(qū)分出cache部分,不能真正反映內(nèi)存使用率。因為一般來說cache是可以復(fù)用的內(nèi)存部分,因此一般將其計入到可使用的部分。
可以考慮的改進計算方式
改進方式在統(tǒng)計內(nèi)存使用量時將cache計算排除出去。類似于linux中計算real_used時將buffer和cache排除一樣。
cache并不能直接應(yīng)用memory.stat中的cache,因為其中包括了tmpfs,而tmpfs算是實際使用的內(nèi)存部分。
tmpfs即share memory,共享內(nèi)存
因為在memory.stat中存在有
active_file + inactive_file = cache - size of tmpfs
因此可以計算實際使用的內(nèi)存量為
real_used = memory.usage_in_bytes - (rss + active_file + inactive_file)
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
docker-compose---安裝掛載本地文件啟動mariadb問題
這篇文章主要介紹了docker-compose---安裝掛載本地文件啟動mariadb問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03Docker mysql+nacos單機部署的實現(xiàn)步驟
本文主要介紹了Docker mysql+nacos單機部署的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08Dockerfile構(gòu)建Redis鏡像的方法實現(xiàn)(yum方式)
本文主要介紹了Dockerfile構(gòu)建Redis鏡像的方法實現(xiàn)(yum方式),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08Docker 本地導(dǎo)入鏡像/保存鏡像/載入鏡像/刪除鏡像的方法
這篇文章主要介紹了Docker 本地導(dǎo)入鏡像/保存鏡像/載入鏡像/刪除鏡像的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12