Memory Cgroup とは
Memory Cgroup は Cgroup の 1 つで、プロセスが使用するメモリの量をコントロールするためのものとなる。
例えば、一時的に大きなファイル (もしくは大量のファイル) を扱うことによって発生する不要なページキャッシュ増大によるメモリ圧迫を回避するといった使い方が考えられる。また、マルチユーザー環境にて、ユーザー毎にメモリに対して Quota を設定するという使用方法も考えられる。
使い方
Memory Cgroup を使用するには cgroup ファイルシステムのマウントが必要となる。
$ sudo mount -t cgroup -o memory memcg /cgroup/
$ ls -l /cgroup/
total 0
-rw-r--r-- 1 root root 0 Feb 4 01:39 cgroup.clone_children
--w--w--w- 1 root root 0 Feb 4 01:39 cgroup.event_control
-rw-r--r-- 1 root root 0 Feb 4 01:39 cgroup.procs
-r--r--r-- 1 root root 0 Feb 4 01:39 cgroup.sane_behavior
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.failcnt
--w------- 1 root root 0 Feb 4 01:39 memory.force_empty
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.kmem.failcnt
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.kmem.limit_in_bytes
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.kmem.max_usage_in_bytes
-r--r--r-- 1 root root 0 Feb 4 01:39 memory.kmem.slabinfo
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.kmem.tcp.failcnt
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.kmem.tcp.limit_in_bytes
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.kmem.tcp.max_usage_in_bytes
-r--r--r-- 1 root root 0 Feb 4 01:39 memory.kmem.tcp.usage_in_bytes
-r--r--r-- 1 root root 0 Feb 4 01:39 memory.kmem.usage_in_bytes
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.limit_in_bytes
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.max_usage_in_bytes
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.memsw.failcnt
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.memsw.limit_in_bytes
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.memsw.max_usage_in_bytes
-r--r--r-- 1 root root 0 Feb 4 01:39 memory.memsw.usage_in_bytes
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.move_charge_at_immigrate
-r--r--r-- 1 root root 0 Feb 4 01:39 memory.numa_stat
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.oom_control
---------- 1 root root 0 Feb 4 01:39 memory.pressure_level
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.soft_limit_in_bytes
-r--r--r-- 1 root root 0 Feb 4 01:39 memory.stat
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.swappiness
-r--r--r-- 1 root root 0 Feb 4 01:39 memory.usage_in_bytes
-rw-r--r-- 1 root root 0 Feb 4 01:39 memory.use_hierarchy
-rw-r--r-- 1 root root 0 Feb 4 01:39 notify_on_release
-rw-r--r-- 1 root root 0 Feb 4 01:39 release_agent
-rw-r--r-- 1 root root 0 Feb 4 01:39 tasks
なお、Memory Cgroup 関連の主な特殊ファイルは以下の通りとなる。
ファイル名 | 説明 |
---|---|
memory.usage_in_bytes | 現在のメモリ (プロセスメモリ + ページキャッシュ) 使用量の表示 |
memory.memsw.usage_in_bytes | 現在のメモリ (プロセスメモリ + ページキャッシュ) + スワップ使用量の表示 |
memory.limit_in_bytes | メモリ (プロセスメモリ + ページキャッシュ) 使用量の制限値の設定* 表示 |
memory.memsw.limit_in_bytes | メモリ (プロセスメモリ + ページキャッシュ) + スワップ使用量の制限値の設定* 表示 |
memory.failcnt | メモリ (プロセスメモリ + ページキャッシュ) が制限値に達した回数の表示 |
memory.memsw.failcnt | メモリ (プロセスメモリ + ページキャッシュ) + スワップが制限値に達した回数の表示 |
memory.max_usage_in_bytes | 記録されたメモリ (プロセスメモリ + ページキャッシュ) 使用量の最大値の表示 |
memory.memsw.max_usage_in_bytes | 記録されたメモリ (プロセスメモリ + ページキャッシュ) + スワップ使用量の最大値の表示 |
memory.stat | 統計情報の出力 |
memory.force_empty | グループに割り当てられているメモリの強制解放 |
memory.use_hierarchy | 階層構造使用の設定* 表示 |
memory.swappiness | グループに対する swappiness (sysctl の vm.swappiness 相当) の設定* 表示 |
メモリ使用量を制限する
実際にメモリ使用量を制限するには、memory.limit_in_bytes を使用する。ここでは GroupA という名のグループを作成し、メモリ使用量の制限を 10 MB とする。
$ sudo mkdir /cgroup/GroupA
$ sudo bash -c "echo 10M > /cgroup/GroupA/memory.limit_in_bytes"
$ sudo bash -c "echo $$ > /cgroup/GroupA/tasks"
それでは実際に大きなファイルを取得し、メモリの使用量がどう変わるのかを見てみる。
[ メモリ使用量制限無しの場合 ]
$ free
total used free shared buffers cached
Mem: 64463556 564504 63899052 68 82124 221468
-/+ buffers/cache: 260912 64202644
Swap: 0 0 0
$ wget https://buildlogs.centos.org/centos/7/isos/x86_64/CentOS-7-livecd-x86_64.iso
--2020-02-04 05:00:45-- https://buildlogs.centos.org/centos/7/isos/x86_64/CentOS-7-livecd-x86_64.iso
Resolving buildlogs.centos.org (buildlogs.centos.org)... 162.254.149.130, 2604:4500:0:109::10
Connecting to buildlogs.centos.org (buildlogs.centos.org)|162.254.149.130|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 719323136 (686M) [application/octet-stream]
Saving to: 'CentOS-7-livecd-x86_64.iso'
CentOS-7-livecd-x86_64.iso 100%[======================================================================================================================>] 686.00M 555KB/s in 21m 55s
2020-02-04 05:22:41 (534 KB/s) - 'CentOS-7-livecd-x86_64.iso' saved [719323136/719323136]
$ free
total used free shared buffers cached
Mem: 64463556 1286992 63176564 68 82156 924036
-/+ buffers/cache: 280800 64182756
Swap: 0 0 0
-> 約 700 MB がファイルキャッシュとして使用されていることがわかる。
それでは一旦先ほどダウンロードしたファイルを削除し、ファイルキャッシュを消した上で GroupA に所属するプロセス (bash) から再度同様のコマンドを実施する。
ちなみに以下の用量で一旦 swap をオンにした。(じゃないと途中で使用可能なメモリがなくなってプロセスが死ぬ)
$ sudo dd if=/dev/zero of=/swapfile bs=128M count=32
32+0 records in
32+0 records out
4294967296 bytes (4.3 GB) copied, 2.57173 s, 1.7 GB/s
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 4194300 KiB
no label, UUID=a194c7c2-50cf-40b6-8488-d8c2a5a3ce4f
$ sudo swapon /swapfile
$ sudo swapon -s
Filename Type Size Used Priority
/swapfile file 4194300 0 -2
[ メモリ使用量制限有りの場合 ]
$ free
total used free shared buffers cached
Mem: 64463556 4895240 59568316 68 82820 4429092
-/+ buffers/cache: 383328 64080228
Swap: 4194300 0 4194300
$ wget https://buildlogs.centos.org/centos/7/isos/x86_64/CentOS-7-livecd-x86_64.iso
--2020-02-04 05:50:21-- https://buildlogs.centos.org/centos/7/isos/x86_64/CentOS-7-livecd-x86_64.iso
Resolving buildlogs.centos.org (buildlogs.centos.org)... 38.110.33.4, 2607:1680:0:1::2
Connecting to buildlogs.centos.org (buildlogs.centos.org)|38.110.33.4|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 719323136 (686M) [application/octet-stream]
Saving to: 'CentOS-7-livecd-x86_64.iso'
CentOS-7-livecd-x86_64.iso 100%[======================================================================================================================>] 686.00M 554KB/s in 21m 58s
2020-02-04 06:12:19 (533 KB/s) - 'CentOS-7-livecd-x86_64.iso' saved [719323136/719323136]
$ free
total used free shared buffers cached
Mem: 64463556 4903112 59560444 68 82844 4435296
-/+ buffers/cache: 384972 64078584
Swap: 4194300 768 4193532
-> ちょっと swap 領域もあるためわかりにくいが、ファイルキャッシュとして利用された領域は一気に少なくなることがわかる。