0x0102

DevOps - free 명령이 숨기고 있는 것들 본문

Study/DevOps

DevOps - free 명령이 숨기고 있는 것들

jxx_yxjx 2024. 1. 22. 14:37

CPU가 프로세스와 연산 과정에 필요한 리소스라면, 메모리는 프로세스가 연산을 할 수 있는 공간을 제공해주는 리소스로 커널이 제공하는 중요한 정보이다. 
free 명령어로 시스템 메모리의 사용량을 확인하고 의미하는 바를 확인해보자.
 

1. 메모리 사용량 확인

# free

free 명령어로는 전체 메모리 용량과 사용 중인 용량, buffers와 cahed로 명명되는 캐싱 영역의 용량을 확인하는데 사용된다.
+) -m 옵션은 숫자들을 MB단위로 보기 위함이다.
 
윗줄
7962 : 시스템에 설치되어 있는 전체 메모리의 양
719 : 시스템에서 사용하고 있는 메모리의 양
6399: 시스템에서 아직 사용하고 있지 않는 메모리의 양
8 : 프로세스 사이에 공유하고 있는 메모리의 양
843 : buffers와 cache 영역을 제외하고 사용하고 있는 영역
6987 : buffers와 cache 여역을 제외하고 사용하지 않는 영역 (free 영역보다 큰 값)
 
아랫줄
swap : swap 영역에 대한 정보
2047 : swap 영역의 전체 용량
0 : swap 영역 중 실제로 사용하고 있는 영역
2047: swap 영역 중 사용하지 않은 영역에 대한 정보
 

2. buffers와 cached 영역

buff/cache 영역에 대해 더 알아보자.
커널은 디스크(=블록 디바이스)에서 데이터를 읽거나 저장한다.
이 때 디스크의 속도가 매우 느리기 때문에 커널은 메모리의 일부를 디스크 요청에 대한 캐싱 영역으로 할당해서 사용한다.
따라서 한번 읽은 디스크의 내용을 메모리에 저장하고, 동일한 내용을 읽고자 할 때 디스크에 요청하는 것이 아닌 메모리로 요청하게 되는 것이다. 
이러한 캐싱 기능을 통해 커널은 디스크 요청을 빠르게 처리할 수 있는데 이 때 사용되는 캐싱 영역을 buffers, cached라고 부른다.
두 영역은 시스템의 I/O 성능 향상을 위해 커널이 사용하는 영역인 것이다.
 

 
Page Cache : 파일의 내용을 저장하는 캐시
Buffer Cache : 파일 시스템의 메타 데이터를 담고 있는 블록을 저장하는 캐시
 
free 명령이 buffers 와 cached 영역을 제외한 영역을 가용 영역으로 보여주는 이유 :
메모리가 부족한 상황이 되면 커널은 해당 영역을 자동으로 반환하기 때문에 free 명령에서도 해당 영역을 제외한 영역을 실제 사용 가능 영역으로 계산해주는 것이다.
 

3. /proc/meminfo 읽기

free 명령어는 간편하지만 각 메모리가 시스템의 어느 부분에 사용되고 있는지 자세히 알 수 없다.
이에 대해 리눅스에서는 /proc/meminfo로 자세한 메모리 현황을 볼 수 있도록 하였다.

# cat /proc/meminfo

 
SwapCached : swap으로 빠진 메모리 영역 중 다시 메모리로 돌아온 영역 (swap 영역에서 삭제되지는 않음)
Active (anon) : 특정 파일의 내용을 저장하는 Page Cache  영역을 제외한 메모리 영역. 주로 프로세스들이 사용하는 메모리 영역이자 비교적 최근에 참조되어 swap 영역으로 이동되지 않을 메모리 영역
Inactive(anon) : 비교적 참조된지 오래되어 swap 영역으로 이동될 수 있는 메모리 영역
Active(file): 커널이 I/O 성능 향상을 위해 사용하는 영역 &  비교적 최근에 참조되어 swap 영역으로 이동되지 않을 메모리 영역 (buffers와 cached영역도 이곳에 포함)
Inactive(file) : 커널이 I/O 성능 향상을 위해 사용하는 영역 & 비교적 참조된지 오래되어 swap 영역으로 이동될 수 있는 메모리 영역
Dirty : I/O 성능 향상을 위해 커널이 캐시 목적으로 사용하는 영역 중 쓰기 작업이 이루어져 실제 블록 디바이스의 블록에 씌어져야 할 영역
 

4. slab 메모리 영역

커널 역시 프로세스의 일종이기 때문에 메모리를 필요로 한다. 이번에는 커널 내부를 살펴보자.

/proc/meminfo의 일부

Slab: 메모리 영역 중 커널이 직접 사용하는 영역
SReclaimable: slab 영역 중 재사용될 수 있는 영역. 주로 캐시 용도로 사용하는 메모리
SUnreclaim: slab 영역 중 재사용될 수 없는 영역. 커널이 현재 사용 중인 영역
 

#slabtop -o

# slabtop -o 로 slab 영역에 대한 더 자세한 정보를 살펴볼 수 있다.
커널은 I/O 작업을 빠르게 하기 위해 inode cache, dentry cache 등을 사용하거나 네트워크 소켓을 위한 메모리 영역을 확보하는 작업들을 하게 되는데 이 과정에서 메모리가 필요하다.
이를 충족하기 위해 커널은 slab 할당자를 통해 원하는 메모리 영역을 확보한다.
만약 파일에 자주 접근하거나 디렉터리의 생성 삭제가 빈번한 시스템이 있다면 slab 메모리가 높아질 수 있다.
 
또한 slab 할당자는 free 명령에서 used로 계산된다.
커널이 사용하기 때문에 buffers/cached 영역에 포함될 것이라고 생각할 수 있으나 used 영역으로 계산된다.
그래서 간혹 프로세스들이 사용하는 메모리 영역을 다 더해도 used와 다를 수 있고 이 경우 slab 메모리에서 누수가 발생한다고 생각해볼 수 있다.
 

5. case study - slab 메모리 누수

운영 중 실제로 발생한 메모리 누수와 관련된 이슈
case )
운영하던 서버에서 지속적으로 메모리 사용량이 증가하는 이슈가 발생했다. free 명령으로는 20GB가 넘게 확인되었지만 ps 명령을 통해 확인한 프로세스들의 메모리 사용량을 합한 값은 10GB도 되지 않았다.
 
how)
 /proc/meminfo 확인 -> slab 메모리 영역이 27GB나 사용하고 있는 것 확인 -> slabtop 명령으로 문제 확인 -> *dentry cache가 26GB 가량 사용하는 것 확인 -> drop cache로 캐시 영역 강제 플러싱 -> 같은 문제 발생
-> 본질 찾기 (slabtop기록 확인) -> 일정한 간격을 두고 dentry cache가 증가하는 것을 보고 스케줄링되어 있는 작업이 영향을 끼치는 것이라고 판단 -> cron에 curl 관련 작업이 영향을 준 것으로 확인  -> 버그 발견 
*dentry cache : 파일 시스템의 디렉터리 엔트리를 저장하고 있는 캐시 / 디렉터리 간 이동을 빠르게 할 수 있도록 도와주는 캐시
 
conclusion)
이번 경우처럼 slab 영역에서 누수가 발생하는 것은 free 명령어로만 확인할 수 없기 대문에 /proc/meminfo를 활용하는 것도 필요하다.