서버 자원 - Memory
Memory
메모리란
메모리는 CPU에서 명령을 수행하기 위해 필요한 데이터를 일시적으로 보관하는 주 기억 장치이다.
여기서 정의하는 메모리는 휘발성 메모리인 RAM(Random Access Memory)을 의미한다.
대표적인 메모리 모니터링 지표로는 메모리 사용량이 있다.
메모리 사용량
메모리 사용량은 전체 메모리 대비 사용한 메모리 비율(%) 혹은 용량(kB)이다.
메모리 사용량을 이해하기 위해서는 먼저 운영체제의 메모리 관리 방식을 알아야 한다.
운영체제는 프로그램이 물리 메모리에 직접 접근하지 않고 추상화된 가상 메모리(Virtual Memory)에 접근하도록 메모리를 관리한다.
가상 메모리 구조를 사용하는 이유는 다음과 같다.
- 스왑 영역(메모리가 부족할 때 사용하는 디스크 공간)을 묶어서 물리 메모리보다 더 큰 용량의 메모리를 다룰 수 있게 해준다.
- 물리 메모리 상에서 연속적이지 않은 메모리 영역을 하나의 연속된 영역처럼 인식하게 해준다.
- 서로 다른 프로세스가 참조하는 가상 메모리 영역을 동일한 물리 메모리 영역에 대응시켜 내용을 공유할 수 있게 해준다. (Shared Memory, IPC)
이처럼 가상 메모리 구조를 통해 얻을 수 있는 이득이 많지만, 메모리 일부를 스왑 영역으로 옮기거나 스왑 영역으로부터 메모리를 로드하는 스와핑(Swapping) 작업은 디스크를 사용하는 만큼 서버에 큰 부하를 준다.
따라서 메모리 사용량이 100%여도 서버 성능에 문제가 없을 수 있지만 메모리 공간이 부족하여 스와핑이 자주 발생하면 높은 확률로 서버 성능이 저하된다.
즉, 안정적인 서버를 운영하기 위해서는 스와핑 발생을 최소화해야 한다.
프로세스 정보에 나온 VSZ(Virtual Set Size)는 프로세스가 확보한 가상 메모리 영역의 크기를 의미하고 RSS(Resident Set Size)는 물리 메모리 영역의 크기를 의미한다.
Page Cache
리눅스는 한번 디스크에서 읽어들인 데이터를 가능한 한 메모리에 캐싱해서 디스크 읽기를 고속으로 처리할 수 있게 한다. 이때 메모리에 캐싱한 데이터를 Page Cache라고 한다.
페이지(Page) : 운영체제에서 관리하는 4KB 크기의 메모리 접근 단위
리눅스는 남아있는 메모리 공간을 최대한 Page Cache로 활용하다 보니 모니터링할 때 캐시된 메모리 영역 때문에 메모리 여유 공간이 부족해 보일 수 있다.
하지만 프로세스에 메모리가 필요할 경우, 페이지 캐시보다 메모리 할당이 우선시 되므로 걱정할 필요 없다.
Buffer Cache와 혼동할 수 있는데 Page Cache가 파일의 내용을 저장한다면 Buffer Cache는 파일 시스템의 메타 데이터와 관련된 블록을 저장한다. 커널 2.4 버전 이후부터 Buffer Cache는 Page Cache 내부로 통합되었다.
메모리 모니터링 도구들
메모리 정보 확인
# 메모리 정보 확인
$ cat /proc/meminfo
free를 사용한 메모리 사용량 확인
$ free
total used free shared buff/cache available
Mem: 32578316 1476356 12507092 179116 18594868 30468380
스왑: 2097148 0 2097148
total
: 전체 메모리 용량used
: 사용 중인 메모리 용량free
: 사용되고 있지 않은 메모리 용량shared
: 공유 중인 메모리 용량buff/cache
: 버퍼(Buffer Cache)/캐시(Page Cache)로 사용되는 메모리 용량available
: 스왑하지 않고 사용할 수 있는 메모리 용량 추정치
sar를 사용한 메모리 사용량 확인
# 1초 간격으로 메모리 사용률 출력
$ sar 1 -r
21시 47분 24초 kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
21시 47분 25초 12507372 30468668 1277564 3.92 1184368 16681252 5068720 14.62 8261104 10571560 4
21시 47분 26초 12507372 30468668 1277564 3.92 1184368 16681252 5068720 14.62 8261104 10571560 4
21시 47분 27초 12507372 30468668 1277564 3.92 1184368 16681252 5068720 14.62 8261104 10571560 4
21시 47분 28초 12507372 30468668 1277564 3.92 1184368 16681252 5068720 14.62 8261104 10571560 4
kbmemfree
: 사용되고 있지 않은 메모리 용량(kB)kbmemused
: 사용 중인 메모리 용량(kB)%memused
: 메모리 사용률(%)kbbuffers
: 커널 내의 버퍼로 사용되고 있는 물리 메모리 용량kbcached
: 커널 내에서 캐시용 메모리로 사용되고 있는 물리 메모리 용량kbswpfree
: 사용되고 있지 않은 스왑 영역 용량kbswpued
: 사용 중인 스왑 영역 용량kbcommit
: overcommit(메모리 초과 할당)하는 메모리 용량%commit
: overcommit(메모리 초과 할당)하는 메모리 사용률kbactive
: 최근에 사용된 메모리 용량kbinact
: 최근에 사용되지 않은 메모리 용량(메모리가 높아지면 커널이 제거할 수 있는 메모리 페이지)kbdirty
: 디스크에 쓰기 대기 중인 메모리 용량
vmstat을 사용한 메모리 사용량 확인
# 5초 간격으로 2회 통계한 가상 메모리 정보를 출력
$ vmstat 5 2
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 12506628 1184708 17410444 0 0 0 4 1 1 0 0 99 0 0
0 0 0 12506628 1184708 17410444 0 0 0 9 90 208 0 0 100 0 0
r
(run-queue) : CPU 할당 대기 중인 프로세스(스레드) 개수b
(blocking) : 입출력나 페이징으로 대기 중인 프로세스(스레드) 개수swpd
: 가상 메모리 사용 페이지 개수free
: 메인 메모리 여유 페이지 개수buff(buffer)
: Buffer Cache 페이지 개수cache
: Page Cache 페이지 개수si
(swap in) : 초당 스왑 영역에서 읽은 양so
(swap out) : 초당 스왑 영역에서 쓴 양bi
(block in) : 초당 디스크(블록 디바이스)에서 읽은 블록 양bo
(block out) : 초당 디스크(블록 디바이스)에서 쓴 블록 양in
: 초당 인터럽트 발생 횟수cs
: 초당 Context Switching 발생 횟수us
: 사용자가 사용한 CPU 시간의 비율sy
: 커널이 사용한 CPU 시간의 비율id
: 대기한 CPU 시간의 비율wa
: I/O 대기한 CPU 시간의 비율