KSM(Kernel Samepage Merging)은 리눅스 커널에서 메모리 중복을 줄이기 위해 사용되는 기술이다. KSM은 동일한 메모리 페이지를 가진 프로세스들을 결합하여 메모리 사용량을 최적화할 수 있다. 이 글에서는 KSM의 동작 원리, 설정 방법, 그리고 실제 사용 예제를 통해 KSM을 효율적으로 사용하는 방법에 대해 다룬다.
KSM이란?
KSM은 메모리 중복을 감지하고 동일한 페이지를 공유하도록 설정하여 메모리 사용량을 줄이는 메커니즘이다. 주로 가상화 환경에서 여러 가상 머신이 동일한 운영체제를 실행할 때 중복되는 메모리가 많아 큰 효과를 볼 수 있다.
KSM은 다음과 같은 과정을 통해 메모리를 최적화한다.
- 메모리 페이지 검사: KSM은 시스템의 메모리 페이지를 주기적으로 스캔하여 동일한 내용을 가진 페이지를 찾는다.
- 페이지 결합: 동일한 페이지를 찾으면, 이 페이지들을 하나의 페이지로 결합하고 이를 공유하도록 설정한다.
- 변경 감지: 만약 어느 프로세스가 공유된 페이지를 수정하려고 하면, KSM은 해당 페이지를 복사하여 독립적인 페이지로 만든다. 이를 COW(Copy-on-Write)라 한다.
KSM 작동 원리
KSM의 작동 원리는 다음과 같다.
- KSM 프로세스: KSM은 사용자가 설정한 주기(슬리프 시간)마다 메모리 페이지를 스캔하여 동일한 페이지를 찾는다.
- 메모리 공유: 동일한 페이지를 찾으면 페이지들을 병합하고 이를 공유하도록 설정하여 메모리 사용량을 줄인다.
- 메모리 해제: 더 이상 공유할 필요가 없는 페이지는 해제되어 시스템 메모리에서 제거된다.
KSM 활성화 및 설정
1. CONFIG_KSM 확인
KSM을 사용하려면 커널에서 CONFIG_KSM이 활성화 되어 있어야 한다.
아래와 같이 현재 커널에 KSM이 활성화 되어 있는지 확인한다.
grep CONFIG_KSM /boot/config-$(uname -r)출력 결과가 CONFIG_KSM=y 라면, KSM이 현재 커널에 활성화 된 상태이다.
$ grep CONFIG_KSM /boot/config-$(uname -r)
CONFIG_KSM=y
우분투를 포함한 대부분의 배포판 커널은 기본적으로 CONFIG_KSM=y로 빌드되어 있어 별도 컴파일 없이 바로 사용할 수 있다. 만약 비활성화되어 있다면 커널 설정을 변경한 뒤 재컴파일해야 한다. 아래 글을 참고하여 커널을 컴파일한다.
KSM을 활성화 하려면 아래와 같이 CONFIG_KSM을 enable 한다.
./scripts/config --enable CONFIG_KSM
2. KSM 실행 활성화 (run)
커널 설정에서 CONFIG_KSM=y인 것은 KSM 기능이 빌드되어 있다는 의미일 뿐, 실제로 스캔·병합이 동작하는 것은 아니다. KSM이 활성화 되어 있으면 /sys/kernel/mm/ksm 디렉토리와 관련 파일들이 생성된다.
$ ls /sys/kernel/mm/ksm/
advisor_max_cpu advisor_mode general_profit merge_across_nodes pages_sharing pages_unshared sleep_millisecs stable_node_chains_prune_millisecs
advisor_max_pages_to_scan advisor_target_scan_time ksm_zero_pages pages_scanned pages_skipped pages_volatile smart_scan stable_node_dups
advisor_min_pages_to_scan full_scans max_page_sharing pages_shared pages_to_scan run stable_node_chains use_zero_pages
이 중 run 파일이 KSM 스캐너 동작을 켜고 끄는 스위치다. 값의 의미는 다음과 같다.
- 0: KSM 중지 (기본값). 스캔을 하지 않는다.
- 1: KSM 실행. 병합 가능한 페이지를 스캔해 병합한다.
- 2: KSM 중지 후 이미 병합된 페이지를 모두 병합 해제한다.
다음 명령으로 KSM 스캐너를 켠다.
echo 1 | sudo tee /sys/kernel/mm/ksm/run
단, run을 켜는 것만으로 시스템의 모든 프로세스 메모리가 자동으로 병합 대상이 되는 것은 아니다. 일반 프로세스는 madvise(2) 시스템 콜을 MADV_MERGEABLE 플래그로 호출해 자신의 메모리 영역을 명시적으로 병합 대상으로 등록해야 한다. 예외적으로 QEMU/KVM은 게스트 가상 머신의 메모리 영역에 대해 이 작업을 자동으로 수행하기 때문에, KSM이 실무에서는 주로 여러 VM을 운용하는 가상화 호스트에서 사용된다.
3. ksmtuned로 자동 튜닝
run과 sleep_millisecs, pages_to_scan 같은 값을 직접 조정할 수도 있지만, ksmtuned 데몬을 이용하면 시스템 메모리 상태에 맞춰 이 값들을 자동으로 조정할 수 있다. 우분투에는 기본 설치되어 있지 않으므로 먼저 패키지를 설치한다.
sudo apt install ksmtuned
KSM의 동작을 조정하기 위해 /etc/ksmtuned.conf 파일을 편집할 수 있다.
sudo nano /etc/ksmtuned.conf
KSM 설정 파일에는 다양한 옵션이 존재한다. 몇 가지 주요 설정은 다음과 같다.
- KSM_MONITOR_INTERVAL: KSM의 모니터링 주기(밀리초)다. 기본값은 1000ms다.
- KSM_SLEEP_MSEC: 메모리 페이지를 스캔할 때의 슬리프 시간이다. 이 값이 작을수록 더 자주 스캔한다.
- KSM_NPAGES_MIN: 최소 스캔할 페이지 수다.
- KSM_NPAGES_MAX: 최대 스캔할 페이지 수다.
예를 들어, 다음과 같이 설정할 수 있다.
KSM_MONITOR_INTERVAL=1000
KSM_SLEEP_MSEC=50
KSM_NPAGES_MIN=32
KSM_NPAGES_MAX=256
설정을 변경한 후에는 ksmtuned 서비스를 다시 시작해야 변경 사항이 적용된다.
sudo systemctl restart ksmtuned
4. KSM 상태 확인
KSM의 현재 상태를 확인하기 위해 /sys/kernel/mm/ksm 디렉토리 내의 파일들을 확인할 수 있다.
cat /sys/kernel/mm/ksm/pages_shared
cat /sys/kernel/mm/ksm/pages_sharing
cat /sys/kernel/mm/ksm/pages_unshared
cat /sys/kernel/mm/ksm/pages_volatile
이 파일들은 각각 다음과 같은 정보를 제공한다.
- pages_shared: KSM에 의해 공유되고 있는 고유 페이지 수
- pages_sharing: 공유된 페이지 덕분에 추가로 절약된 페이지 수
- pages_unshared: 병합 대상으로 스캔했지만 동일한 페이지를 찾지 못한 고유 페이지 수
- pages_volatile: 내용이 너무 자주 바뀌어 병합 트리에 등록하지 못한 페이지 수
주의사항 및 팁
- CPU 오버헤드: KSM 스캐너는 백그라운드에서 지속적으로 메모리를 스캔하고 비교하므로 CPU 사용률이 늘어난다. 메모리 절약 효과와 CPU 부하를 함께 벤치마크한 뒤 도입 여부를 결정하는 것이 안전하다.
- 사이드 채널 위험: 서로 다른 보안 도메인(예: 멀티테넌트 VM)의 메모리가 병합되면, 쓰기 시 발생하는 COW 지연 시간을 측정해 다른 VM의 메모리 내용을 간접적으로 추론하는 사이드 채널 공격이 알려져 있다. 신뢰 경계가 다른 VM 사이에서는
/sys/kernel/mm/ksm/merge_across_nodes및 관련 설정을 통해 병합 범위를 제한하거나, 클라우드 환경에서는 KSM 자체를 비활성화하는 것이 일반적이다. - 메모리 회수와의 관계: KSM으로 절약된 메모리는 언제든 COW로 되돌아갈 수 있으므로, KSM 절약분을 실제 여유 메모리처럼 취급해 과다하게 오버커밋하면 메모리 부족 상황에서 문제가 될 수 있다.
마치며
KSM은 동일한 메모리 페이지를 하나로 병합해 메모리 사용량을 줄이는 리눅스 커널 기능으로, 특히 여러 가상 머신을 운용하는 환경에서 효과가 크다. CONFIG_KSM 커널 설정으로 기능이 빌드되어 있는지 확인하고, /sys/kernel/mm/ksm/run으로 실제 스캐너를 켠 뒤, 필요하면 ksmtuned로 자동 튜닝을 적용하는 순서로 도입하면 된다. 다만 CPU 오버헤드와 사이드 채널 위험이 있으므로 프로덕션에 적용하기 전에는 반드시 워크로드에 맞는 벤치마크를 거치는 것이 좋다.