다음으로 소개할 방법은 cgroup을 이용하는 방법이다.
Cgroup (control group)은 리눅스 커널이 제공하는 시스템의 자원 사용률을 그룹별로 제어하기 위한 방법이다.
이 또한 sysfs 인터페이스를 통해 사용 가능한데, 기존 cgroup v1과 Linux 4.5.x 때부터(정확한지는 모르겠지만 이때쯤) 지원하기 시작한 cgroup v2 두 종류가 있다. 사용방법이 사뭇 다르므로 정확한 용법은 커널 도큐먼트(Documentation/cgroup-v2.txt)를 확인해 보는 것이 좋다.
일단 아무데나 원하는 위치에 디렉토리를 만들고, 다음과 같이 cgroup sysfs를 마운트하자.
# mkdir cgroup
# mount -t cgroup2 none ./cgroup
해당 마운트포인트에서 ls -l 명령을 실행시키면 다음과 같은 결과가 나올 것이다.
-r--r--r-- 1 root root 0 Dec 9 03:20 cgroup.controllers
-rw-r--r-- 1 root root 0 Dec 9 03:20 cgroup.procs
-rw-r--r-- 1 root root 0 Dec 9 03:21 cgroup.subtree_control
여기서 cgroup.controllers는 현재 cgroup v2가 사용가능한 컨트롤러들을 뜻한다. 부트 파라미터를 통해 cgroup v1을 효과적으로 disable 했다면, (혹은 애초에 cgroup v1을 사용하지 않는다면) 다음과 같은 결과를 볼 수 있다.
# cat cgroup.controllers
io memory pids
I/O와 memory, 그리고 pid에 대한 컨트롤러를 제공하며, 이 말은 cgroup 인터페이스를 통해 원하는 그룹에 저 세 가지 자원에 대한 제한을 걸 수 있다는 뜻이 된다.
cgroup.procs 는 현재 해당 컨트롤 그룹에 속해있는 프로세스를 의미하며, 현재 시스템에 등록되어 동작하고 있는 대부분의 프로세스가 여기에 등록되어 있을 것이다. 즉, 마운트포인트의 루트 디렉토리는 시스템의 루트 컨트롤 그룹에 대한 정보가 등록되어 있는 것이다.
cgroups.subtree_control 은 하위 컨트롤 그룹에 대해 어떤 컨트롤러를 사용할 것인지 지정하는 것이다. 현재는 아무런 정보도 없을 것이다.
이제 새로운 컨트롤 그룹을 생성할 시간이다. 아래의 명령을 입력해보자.
# mkdir cgroup_child
생성된 디렉토리 아래로 가게 되면, 부모 디렉토리와 마찬가지로 cgroup.controllers, cgroup.subtree_control, cgroup.procs, 그리고 cgroup.events 파일이 존재할 것이다.
생성된 그룹에 프로세스를 추가하기 위해서는, 해당 프로세스의 pid를 알아내어 다음과 같이 입력하면 된다.
# echo "pid" > ./cgroup/cgroup_child/cgroup.procs
그리고 원하는 컨트롤러를 "부모" 디렉토리의 cgroup.subtree_control에 입력하자. 여기서는 페이지 캐시 사용량을 제한하려고 하니, memory 컨트롤러를 입력하면 된다.
# echo "+memory" > ./cgroup/cgroup.subtree_control
여기서 +는 해당 컨트롤러를 추가한다는 의미이며, -로 입력할 경우 해당 컨트롤러를 제거한다는 의미가 된다.
해당 명령을 수행하면, 자녀 디렉토리에 다음과 같은 파일들이 추가로 생성된다.
-r--r--r-- 1 root root 0 Dec 9 03:21 cgroup.controllers
-r--r--r-- 1 root root 0 Dec 9 03:21 cgroup.events
-rw-r--r-- 1 root root 0 Dec 9 03:21 cgroup.procs
-rw-r--r-- 1 root root 0 Dec 9 03:21 cgroup.subtree_control
-r--r--r-- 1 root root 0 Dec 9 03:21 memory.current
-r--r--r-- 1 root root 0 Dec 9 03:22 memory.events
-rw-r--r-- 1 root root 0 Dec 9 03:21 memory.high
-rw-r--r-- 1 root root 0 Dec 9 03:22 memory.low
-rw-r--r-- 1 root root 0 Dec 9 03:21 memory.max
-r--r--r-- 1 root root 0 Dec 9 03:21 memory.stat
각각의 의미는 다음과 같다.
File |
Description |
memory.current |
컨트롤 그룹의 현재 메모리 사용량 |
memory.high |
메모리 사용량의 soft limit |
memory.low |
메모리 사용량의 하한 |
memory.max |
메모리 사용량의 hard limit |
memory.events |
low, high, max, oom 에 대한 이벤트 횟수 |
memory.stat |
컨트롤 그룹의 메모리 사용량 통계 |
메모리 사용량이 soft limit(memory.high)에 도달할 경우, 해당 그룹의 프로세스들을 throttling 하며, memory 회수를 빈번하게 수행시키기 위한 압박을 주게 된다. 만약, 메모리 사용량이 hard limit (memory.max)를 넘어서게 될 경우, 커널은 OOM killer를 호출하여 해당 프로세스를 종료시키게 된다.
두 항목에 적절한 값을 설정하고, free 명령을 통해 메모리 사용량 변화의 추이를 살펴보자.
root@ubuntu:/home/ubuntu# free -c 10
total used free shared buff/cache available
Mem: 65722960 410052 59913708 9736 5399200 64511200
Swap: 33326076 0 33326076
total used free shared buff/cache available
Mem: 65722960 410612 59913580 9736 5398768 64510436
Swap: 33326076 0 33326076
total used free shared buff/cache available
Mem: 65722960 410908 59913108 9736 5398944 64510268
Swap: 33326076 0 33326076
total used free shared buff/cache available
Mem: 65722960 411000 59913268 9736 5398692 64510304
Swap: 33326076 0 33326076
total used free shared buff/cache available
Mem: 65722960 410824 59913176 9736 5398960 64510368
Swap: 33326076 0 33326076
total used free shared buff/cache available
Mem: 65722960 410348 59913612 9736 5399000 64510896
Swap: 33326076 0 33326076
total used free shared buff/cache available
Mem: 65722960 410980 59913340 9736 5398640 64509924
Swap: 33326076 0 33326076
total used free shared buff/cache available
Mem: 65722960 410580 59913672 9736 5398708 64510560
Swap: 33326076 0 33326076
total used free shared buff/cache available
Mem: 65722960 411080 59912944 9736 5398936 64509680
Swap: 33326076 0 33326076
total used free shared buff/cache available
Mem: 65722960 410504 59913820 9736 5398636 64510612
Swap: 33326076 0 33326076
모든 가용영역을 캐시용도로 쓰던 과거에서 벗어나, 제한된 만큼 사용하는 것을 확인할 수 있다.
엄밀히 따지자면, 이 방법은 페이지 캐시를 제한하기 위해 존재하는 방법은 아니다.
하지만 내 용도가 페이지 캐시를 제한하는 것 이었던 만큼 이 항목으로 포스팅을 남긴다.
'Writings > Linux kernel' 카테고리의 다른 글
페이지 캐시의 크기 제한걸기 (1/2) (0) | 2017.12.10 |
---|---|
Enabling Cgroup v2 (0) | 2017.12.09 |