Swap을 추가하기 전에 확인할 메모리 압박과 튜닝 기준
예전 Swap 글에는 메모리가 부족할 때 디스크를 보조 공간으로 쓰는 개념, 4GB 스왑 파일 예제, swappiness를 10~20으로 낮추는 설정, vfs_cache_pressure를 50으로 바꾸는 예시를 함께 적었다. 다시 읽어 보니 초보자가 숫자만 복사해 적용할 수 있는 형태였다. 특히 두 커널 설정은 서로 다른 대상을 조정하므로 하나의 “Swap 최적화값”처럼 묶으면 안 된다.
Swap은 RAM의 빠른 대체품이 아니다
Linux는 메모리 압박이 생기면 회수 가능한 메모리를 찾고, 설정과 페이지 종류에 따라 일부 익명 메모리 페이지를 Swap으로 내보낼 수 있다. Swap이 있으면 특정 상황에서 메모리 부족을 늦추는 완충 역할을 할 수 있지만 RAM과 같은 속도를 제공하지는 않는다. 작업 집합이 계속 Swap과 RAM 사이를 오가면 응답이 크게 느려지고, 그래도 시스템이 필요한 메모리를 회수하지 못하면 OOM killer가 프로세스를 종료할 수 있다.
먼저 현재 상태를 확인한다.
free -h
swapon --show
vmstat 1
Swap 사용량이 있다는 사실만으로 곧바로 장애라고 판단하지 않는다. 반대로 사용량이 적어 보여도 메모리 압박이 없다고 단정하지 않는다. vmstat에서 swap-in/swap-out 변화가 지속되는지, 응답 시간과 함께 악화되는지 살피고, 지원되는 Linux 환경에서는 /proc/pressure/memory의 PSI 지표와 커널 OOM 기록도 함께 본다.
swappiness와 vfs_cache_pressure는 역할이 다르다
커널 6.15 문서는 vm.swappiness를 Swap I/O와 파일시스템 페이징의 상대 비용을 나타내는 값으로 설명한다. 범위는 0~200이고 문서상 기본값은 60이며, 최적값은 장치와 워크로드에 따라 실험해야 한다. “서버는 무조건 10~20”이라는 고정 규칙이 아니다. 실행 중인 커널의 문서와 현재 값을 먼저 확인한 뒤, 변경 전후 지표를 비교해야 한다.
vm.vfs_cache_pressure는 Swap 사용량이 아니라 디렉터리 엔트리(dentry)와 inode 캐시를 회수하려는 경향을 조정한다. 기본값 100에서 낮추면 이 캐시를 더 오래 유지하려는 방향으로 작동한다. 특히 0은 메모리 압박 때 이 캐시를 회수하지 않게 만들어 OOM 위험을 높일 수 있다. 근거 없이 50으로 낮추는 것 역시 보편적인 최적화로 볼 수 없다.
설정을 바꾸기 전에는 이 설정을 필요로 하는 병목이 실제로 있는지, 지속적인 Swap I/O가 있는지, 어떤 프로세스가 메모리를 차지하는지 확인한다. 값을 바꿨다면 변경 기록, 이전 값, 되돌리는 방법과 관찰 시간을 남긴다. Swap 파일 크기도 모든 서버에 통하는 4GB 공식이 없으며, 메모리 용도·워크로드·최대 동시 작업·최대 절전 필요 여부·파일시스템과 배포판 정책에 맞춰 정해야 한다.
컨테이너는 호스트 설정과 런타임 제한을 함께 본다
컨테이너가 Swap을 사용할 수 있는지 여부를 모든 Docker·Kubernetes 환경에 대해 한 문장으로 단정할 수 없다. Docker Engine에서는 호스트의 Swap 구성, 커널의 cgroup 지원, --memory와 --memory-swap 제한 조합이 실제 사용 가능 범위에 영향을 준다. 예를 들어 메모리 한도와 메모리+Swap 총 한도를 같게 지정하면 해당 컨테이너의 Swap 사용을 막는 설정이 된다.
따라서 호스트에 Swap을 추가했더라도 컨테이너가 자동으로 기대한 양만큼 사용할 거라고 가정하지 않는다. 반대로 Swap을 무제한 허용해 OOM을 미루는 것이 항상 안전한 것도 아니다. 컨테이너 메모리 한도, 호스트 여유, 애플리케이션의 실제 메모리 요구량을 함께 측정해야 한다.
이번에 다시 정리하며 바꾼 결론은 “Swap을 늘리면 메모리 문제가 해결된다”가 아니다. Swap은 장애를 없애는 장치가 아니라 압박 상황에서 선택지를 늘리는 구성이다. 커널의 VM sysctl 문서는 swappiness와 vfs_cache_pressure의 역할을 각각 설명하고, 메모리 압박 지표 PSI는 작업이 메모리 대기 때문에 멈춘 시간을 관찰하는 방법을 제공한다. Docker를 쓴다면 컨테이너 메모리와 Swap 제한도 함께 확인해야 한다.
당시 기록: Swap Memory