이슈상황
1 2 3 4 5 | $ free total used free shared buffers cached Mem: 32901680 29978376 2923304 0 193676 9317964 -/+ buffers/cache: 20466736 12434944 Swap: 7812092 6379492 1432600 | cs |
free 명령어로 조회했을 때의 결과입니다.
4번째 줄을 보면 버퍼/캐시 영역을 제외하고 12GB 의 여유 메모리가 있습니다.
5번째 줄 Swap 을 보면 6GB 를 사용하고 있는 것으로 나옵니다.
보통의 경우 물리메모리가 부족해지면 버퍼/캐시 영역을 프로세스 메모리로 재할당해 주는 방식으로 구성됩니다.
그러나 버퍼/캐시 영역이 반환되지 않고 SWAP 영역을 사용하고 있는 것으로 나왔습니다.
왜 이런일이 나오게 되었을까?
SWAP 에 대한 개념과, 테스트를 통해 SWAP 사용 기준에 대해 정리해 보았습니다.
SWAP 메모리란
SWAP 메모리란 물리메모리가 부족할 경우를 대비해서 만들어놓은 공간을 의미합니다.
메모리는 프로세스에서 요청하는 연산을 하기위해 존재하는데
물리메모리가 부족하면 프로세스는 연산을 위한 공간을 할당받을 수 없어 프로세스 멈춤현상(행 : Hang)이 발생하게 됩니다.
( 이럴 때는 OOM Killer 가 프로세스를 강제로 죽이기도 합니다. https://mozi.tistory.com/28 )
이런 이슈를 대비하기 위해 비상용으로 확보해 놓은 메모리가 SWAP 입니다.
SWAP 은 디스크의 공간을 메모리처럼 사용합니다.
따라서 SWAP 을 사용하게 되면 메모리에 비해 처리 속도가 떨어져 성능 저하로 이어지게 됩니다.
예로, 메모리DB 를 사용하는 경우 SWAP 영역에 구성되어 있으면 디스크DB 나 다를바가 없고
응답속도도 많이 떨어지게 되겠죠?
SWAP 영역을 확인하는 방법
free 명령어로 메모리 정보(K바이트 단위)를 확인하면 SWAP 영역이 출력됩니다.
Swap 부분에서 출력되는 내용는 나름 직관적으로 되어 있기 때문에 설명하진 않겠습니다.
1 2 3 4 | $ free total used free shared buff/cache available Mem: 8152876 964500 6252848 20760 935528 6921788 Swap: 969960 0 969960 | cs |
SWAP 을 사용하는 프로세스 조회
프로세스는 /proc/ 의 자신 PID 경로에서 자신과 관련된 모든 정보를 기록합니다.
/proc/PID 경로의 status 의 항목을 보면 VmSwap 부분이 출력됩니다.
1 2 3 4 5 6 7 8 9 | # ps -ef | grep mysql mysql 918 1 0 21:41 ? 00:00:04 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid # cd /proc/918/ # cat status Name: mysqld ... VmSwap: 0 kB | cs |
VmSwap 이 0 으로 출력되지 않으면 Swap 영역을 사용한다는 의미입니다.
버디시스템과 메모리 재할당 방식
버디 시스템
커널은 버디 시스템을 통해서 메모리를 할당합니다.
버디시스템은 물리적으로 연속된 페이지들로 이루어진 고정된 크기의 세그먼트로부터 메모리를 할당합니다.
할당은 2^n 단위로 4KB, 8KB, 16KB .. 식으로 할당받게 됩니다.
만약 세그먼트의 크기가 128KB 이고 31KB 의 메모리를 프로세스가 요구하였을 때
세그먼트는 64KB / 64KB 버디로 나눠지고, 그 중 하나는 다시 32 KB / 32KB 로 나뉘어 지게 됩니다.
이 32KB 의 버디중 하나가 31KB 의 요구 사항을 처리하기 위해 사용됩니다.
단위별로 할당 가능한 수는 /proc/buddyinfo 에서 확인이 가능하며
앞에서부터 4KB, 8KB, 16KB, 32KB 순으로 할당가능한 세그먼트가 있습니다.
1 2 3 4 5 6 7 8 9 | # cat /proc/buddyinfo Node 0, zone DMA 1 1 1 0 2 1 1 0 1 1 3 Node 0, zone DMA32 4 6 5 6 8 5 5 7 8 5 863 Node 0, zone Normal 91 11 102 84 49 17 8 2 2 2 648 # free total used free shared buff/cache available Mem: 8152876 968000 6248032 20760 936844 6918100 Swap: 969960 0 969960 | cs |
계산식은 (4KB + 96) + (8KB + 18) + (16KB + 108) .. 이며 이를 합하면 6,249,040 입니다.
free 명령어의 Mem free 부분을 보면 비슷한 값을 가지고 있는 것을 알 수 있습니다.
메모리 재할당 방식
OS 는 자원이 유휴상태에 있는것을 좋아하지 않으므로 남는 메모리는 버퍼/캐시 영역으로 활용됩니다.
캐시 용도로 사용되다가 프로세스에서 메모리를 추가적으로 요청할 때, 프로세스 메모리 할당 방식은 2가지로 나뉩니다.
- 캐시 메모리를 반환 후 요청한 프로세스 메모리로 할당
- 기존 프로세스 Inactive 메모리를 SWAP 영역으로 내려쓴 후 요청한 프로세스 메모리로 할당
( Inactive 인 메모리를 반환하지 않는 이유는, 메모리에 어떤 내용이 있는지 알 수 없기 때문 )
캐시 용도의 메모리를 반환할 만큼 하고도 메모리가 없다면, SWAP 영역을 사용하게 됩니다.
SWAP 영역은 프로세스가 사용하는 메모리 중 Inactive 상태에 있는 메모리를 골라서 SWAP 영역으로 이동시킵니다.
그런 다음 해당 메모리 영역을 해제하고 다른 프로세스에 할당하게 됩니다.
문제는 OS 가 항상 캐시영역을 먼저 없애고 SWAP 을 사용하는 방식이 아니며,
SWAP 은 Disk I/O 가 발생하기 때문에 성능에 영향을 미치게 된다는 것 입니다.
vm.swappiness 파라미터로 SWAP 사용기준 설정
swappiness 파라미터
swappiness 에 대한 설명은 아래처럼 나와있습니다.
OS에서 메모리영역을 SWAP으로 내려쓰는 강도를 결정하는 파라미터입니다.
메모리가 부족한 상황에서 새로운 프로세스가 메모리를 요청할 때
캐시를 반환할지 특정 프로세스의 Inactive 메모리 영역을 SWAP 으로 옮길지를 결정합니다.
값이 커질수록 프로세스의 메모리를 SWAP 영역으로 옮기는 확률이 증가합니다.
swappiness ( 값 범위 1 ~ 100 ) |
캐시 메모리 |
기존 프로세스 Inactive 메모리 |
값이 작을수록 |
반환 확률 높음 |
SWAP 영역으로 갈 확률 낮음 |
값이 클수록 |
반환 확률 낮음 |
SWAP 영역으로 갈 확률 높음 |
swap 사용여부 계산식
1 | swap_tendency = mapped_ratio / 2 + distress + swappiness | cs |
단어 |
설명 |
mapped_ratio |
물리적메모리 크기 대비 구동중인 프로세스 메모리들의 비율입니다. |
distress |
메모리 확보가 얼마나 어려운 상태인지를 체크하는 값으로, 사용자가 조절할 수 없습니다. 작게 할당된 메모리부터 확보를 시도하며 실패하는 경우, 더 많이 할당된 메모리들을 확보하려고 시도합니다. (우선순위 : 하단 표 참고) |
swappiness |
파라미터 값으로 사용자가 조절 가능합니다. |
distress 의 우선순위 별 계산에 사용되는 distress 값 ( 사용자가 조절 불가능하며 대부분의 경우는 0 값임 )
priority | 12~7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
distress | 0 | 1 | 3 | 6 | 12 | 25 | 50 | 100 |
만약 8G 메모리 중 5G 메모리가 사용되고 있다면, 아래와 같은 계산식을 가지게 됩니다.
단, distress 값은 0이라는 전제조건을 가지고 있어야 합니다.
1 2 3 | swap_tendency = ( 5 / 8 * 100 ) / 2 + 0 + 60 = 31.5 + 60 = 91.5 | cs |
'Linux > 실습하기' 카테고리의 다른 글
[LINUX] 쉘 스크립트 파일 한 줄씩 읽을 때 ssh 를 사용하면 한줄만 읽는 문제 (0) | 2020.10.12 |
---|---|
[LINUX] 비밀번호를 출력하지 않는 스크립트 만들기 (0) | 2018.09.11 |
[LINUX] GOLDILOCKS 온라인 백업 스크립트 만들어보기 (0) | 2018.07.13 |
[LINUX] CENTOS 에 JEUS 웹서버 설치하기 (0) | 2018.06.28 |