중복 제거
개요
메모리 중복 제거(deduplication)는 동일한 내용을 가진 메모리 페이지들을 하나의 공유 페이지로 병합하여 물리적 RAM 사용량을 줄이는 Linux 커널 기술입니다. 대표적인 구현인 KSM(Kernel Samepage Merging)은 KVM 가상화 환경에서 유사한 게스트 OS 이미지 간의 공유를 위해 개발되었으나, 다중 사용자 시스템이나 동일한 데이터를 반복적으로 생성하는 모든 응용 프로그램에 적용할 수 있습니다.
이 문서는 Linux 커널의 메모리 중복 제거 메커니즘인 KSM의 동작 원리, 설정 방법, 모니터링 기법, 그리고 페이지 공유와 관련된 다양한 기술적 고려 사항을 정리합니다. 또한 중복 제거가 가져오는 이점과 함께 CPU 오버헤드, 보안, 성능 트레이드오프 같은 한계점도 함께 분석합니다.
그림 1. Linux 메모리 중복 제거 기술 분류와 적용 계층
핵심 개념
KSM (Kernel Samepage Merging)
KSM은 Linux 2.6.32부터 커널에 포함된 메모리 중복 제거 기능입니다. CONFIG_KSM=y 옵션으로 활성화되며, 커널 스레드인 ksmd가 주기적으로 사용자 메모리 영역을 스캔하여 동일한 내용을 가진 페이지를 찾아 하나의 쓰기 보호 페이지로 병합합니다. 프로세스가 해당 페이지를 수정하려 하면 자동으로 복사(Copy-on-Write)가 발생합니다.
- ksmd 커널 스레드가 백그라운드에서 등록된 메모리 영역을 주기적으로 스캔합니다.
- 페이지 내용의 해시 값을 비교한 후 memcmp()로 완전한 일치를 확인합니다.
- 병합된 페이지는 쓰기 보호되며, 쓰기 발생 시 COW로 복제됩니다.
MADV_MERGEABLE로 등록한 익명(anonymous) 페이지만 병합 대상이 됩니다.- 파일 기반 페이지(pagecache)는 병합하지 않습니다.
madvise 인터페이스
KSM은 madvise(2) 시스템 콜을 통해 응용 프로그램이 병합 대상 영역을 직접 지정합니다.
MADV_MERGEABLE: 지정된 주소 범위를 KSM 병합 대상으로 등록합니다.MADV_UNMERGEABLE: 이전에 등록된 병합 대상을 취소하고, 이미 병합된 페이지를 해제합니다.- 병합 해제 시 갑자기 더 많은 메모리가 필요할 수 있어 OOM 킬러가 발동될 수 있습니다.
CONFIG_KSM이 비활성화된 커널에서는MADV_MERGEABLE이 EINVAL로 실패합니다.
KSM 스캔 시간 어드바이저
KSM 어드바이저는 후보 페이지 수의 동적인 변화에 적응하여 pages_to_scan 파라미터를 자동으로 조절합니다.
advisor_mode=scan-time: 스캔 시간 기반 어드바이저를 활성화합니다.advisor_target_scan_time: 전체 후보 페이지 스캔 목표 시간(초)을 설정합니다. 기본값 200초.advisor_max_cpu: ksmd 스레드의 최대 CPU 사용률 상한을 설정합니다. 기본값 70%.advisor_min_pages_to_scan/advisor_max_pages_to_scan:pages_to_scan의 범위를 제한합니다.- 스캔 완료 후
pages_to_scan이 재계산되어 동적으로 조절됩니다.
제로 페이지 최적화
use_zero_pages 옵션은 빈 페이지(zero page)를 특별 처리하여 커널 제로 페이지와 병합하도록 합니다.
use_zero_pages=1로 설정하면 빈 페이지들이 각각 제로 페이지와 병합됩니다.- 색상 제로 페이지(coloured zero page)를 사용하는 아키텍처에서 성능이 향상될 수 있습니다.
- 특정 워크로드에서는 채점(checksum)이 일치하는 빈 페이지를 과도하게 스캔할 수 있어 주의가 필요합니다.
NUMA 인식 병합
merge_across_nodes 파라미터는 서로 다른 NUMA 노드의 페이지 병합을 제어합니다.
merge_across_nodes=1(기본값): 모든 노드의 페이지를 병합하여 최대한 많은 공유를 달성합니다.merge_across_nodes=0: 동일한 NUMA 노드 내 페이지만 병합하여 접근 지연시간을 최소화합니다.- NUMA 거리가 큰 멀티노드 시스템에서는 0으로 설정하여 지연시간을 줄이는 것이 효과적입니다.
- 설정 변경 시 먼저
run=2로 모든 공유를 해제한 후 변경해야 합니다.
비교/분석
| 기법 | 원리 | 적합한 대상 | CPU 비용 | 메모리 절약 효과 | 보안 고려 |
|---|---|---|---|---|---|
| KSM (madvise) | 주기적 스캔으로 동일 페이지 병합 | KVM, 다중 사용자 | 중간~높음 | 높음 (최대 300% 오버커밋) | Side-channel 위험 |
| KSM (global) | 전체 익명 페이지 스캔 | 범용 | 높음 | 중간 | 높은 스캔 비용 |
| COW (fork) | fork 시 페이지 공유, 쓰기 시 복제 | 프로세스 생성 | 낮음 | 중간 | 안전 |
| 투명 대형 페이지 | 4KB→2MB 페이지 병합 | 대용량 워크로드 | 낮음 | 캐시 효율 향상 | 안전 |
| 페이지 공유 (Uffd) | userfaultfd를 통한 공유 | VM 마이그레이션 | 중간 | 높음 | VM 의존 |
동작 원리
KSM 스캔 및 병합 흐름
- 응용 프로그램이
madvise(MADV_MERGEABLE)로 메모리 영역을 KSM에 등록합니다. - ksmd 스레드가 설정된 간격(
sleep_millisecs)마다 후보 영역을 스캔합니다. - 각 페이지에 대해 해시 값을 계산하고, 동일한 해시를 가진 기존 페이지와 비교합니다.
memcmp()로 페이지 내용이 완전히 일치하면 해당 페이지들을 하나의 쓰기 보호 페이지로 병합합니다.- 병합된 페이지를 참조하는 모든 프로세스의 페이지 테이블 엔트리가 하나의 물리 페이지를 가리키도록 변경됩니다.
- 나중에 어떤 프로세스가 해당 페이지에 쓰기를 시도하면 COW가 발생하여 복제됩니다.
병합 경로:
App Memory → madvise(MERGEABLE) → ksmd Scan → Hash Compare → memcmp → Merge (COW)
쓰기 경로:
Process Write → COW Fault → Page Copy → Unmerge
그림 2. KSM 페이지 스캔, 병합, COW 흐름
KSM 수익성 계산
KSM은 메모리를 절약하지만 rmap_item 구조체를 통해 메타데이터를 추가로 소비합니다. 수익성은 다음 공식으로 근사 계산합니다.
general_profit ≈ ksm_saved_pages × sizeof(page) - (all_rmap_items) × sizeof(rmap_item)
ksm_saved_pages:pages_sharing+ksm_zero_pages의 합all_rmap_items:pages_sharing+pages_shared+pages_unshared+pages_volatile의 합- 64비트 CPU에서 rmap_item 크기는 64B, 32비트에서는 32B
ksm_rmap_items / ksm_merging_pages비율이 64(64비트) 또는 128(32비트)를 초과하면 수익이 거의 없거나 음수
스마트 스캔
smart_scan은 이전에 병합에 실패한 페이지를 스캔에서 건너뛰어 ksmd의 CPU 사용량을 줄입니다.
- 이전 스캔에서 병합되지 않은 페이지는 스캔 빈도를 점진적으로 줄입니다.
pages_skipped메트릭으로 건너뛴 페이지 수를 확인할 수 있습니다.- 기본적으로 활성화되어 있으며,
smart_scan=0으로 비활성화할 수 있습니다.
최대 공유 수 제한
max_page_sharing은 하나의 KSM 페이지에 허용되는 최대 공유 수를 제한합니다.
- 메모리 조작(swap, compaction, NUMA 밸런싱, 페이지 마이그레이션) 시 가상 매핑 순회 비용을 제한합니다.
- 값을 높이면 병합 속도와 중복 제거 비율이 증가하지만, 최악의 경우 지연시간이 증가합니다.
stable_node_chains_prune_millisecs로 이 한계에 도달한 페이지의 메타데이터를 주기적으로 정리합니다.
장단점
장점
- 물리적 RAM을 효율적으로 사용하여 동일한 하드웨어에서 더 많은 VM이나 프로세스를 실행할 수 있습니다.
- KVM 환경에서 최대 300%까지 메모리 오버커밋이 가능합니다.
- Windows 게스트의 경우 해제된 메모리를 제로 페이지로 초기화하여 높은 공유율을 달성합니다.
- 응용 프로그램 수정 없이
madvise만으로 투명하게 동작합니다. use_zero_pages로 제로 페이지를 추가로 절약할 수 있습니다.- 어드바이저가 동적으로 스캔 비용을 조절하여 리소스 사용을 최적화합니다.
단점
- ksmd 스캔이 상당한 CPU 리소스를 사용하여 다른 워크로드에 영향을 줄 수 있습니다.
- 스캔 주기가 짧으면 CPU 사용량이, 길면 중복 제거 효과가 떨어집니다.
- COW 발생 시 페이지 복제 비용이 발생하여 쓰기 워크로드의 성능이 저하될 수 있습니다.
- rmap_item 메타데이터가 추가 메모리를 소비하여 실제 절약량이 줄어듭니다.
- 스캔 실패율이 높은 워크로드에서는 CPU 대비 절약 효과가 미미할 수 있습니다.
- KSM 페이지에 대한 메모리 접근 패턴 분석이 가능하여 보안 측면에서 Side-channel 공격 위험이 있습니다.
MADV_UNMERGEABLE호출 시 갑작스러운 메모리 부족으로 OOM 킬러가 발동될 수 있습니다.
관련 기술
- Linux 메모리 관리 기초
- Linux 메모리 최적화
- Linux Memory Tiering Deep
- Virtual Memory
- CPU Cache Architecture
- 소프트웨어 메모리 압축
- 하드웨어 메모리 압축
- Linux Kernel Documentation: KSM (
Documentation/admin-guide/mm/ksm.rst) - Jonathan Corbet, "/dev/ksm: dynamic memory sharing", LWN.net, 2008
- Izik Eidus, Hugh Dickins, "Kernel Samepage Merging", Linux kernel patch, 2009
- Linux man-pages: madvise(2) - MADV_MERGEABLE, MADV_UNMERGEABLE
핵심 정리
Linux 메모리 중복 제거는 KSM(Kernel Samepage Merging)을 통해 동일한 내용의 익명 페이지를 하나의 쓰기 보호 페이지로 병합하여 RAM 사용량을 줄이는 기술입니다. ksmd 커널 스레드가 주기적으로 스캔하여 중복 페이지를 찾아내며, MADV_MERGEABLE로 등록된 영역에서만 동작합니다. KVM 가상화 환경에서 가장 큰 효과를 보이며, 최대 300% 메모리 오버커밋을 가능하게 하지만, CPU 스캔 비용, rmap_item 메타데이터 오버헤드, COW 발생 시 복제 비용, 그리고 보안 측면의 Side-channel 위험 같은 한계점이 존재합니다. 스마트 스캔, 어드바이저, NUMA 인식 병합 같은 최적화 기법을 통해 워크로드에 맞게 튜닝할 수 있습니다.