feat: 가상화 문서들 추가

This commit is contained in:
DongHyeonka
2026-09-10 08:54:05 +09:00
parent e9f6a93327
commit 43e1aadef0
695 changed files with 153404 additions and 12754 deletions
@@ -0,0 +1,120 @@
---
id: 63fa33e5-9957-4d28-8d3c-c75735a73bd6
kind: REFERENCE
slug: memory-symptom-needs-layer-separation
title: 메모리 증상 하나로 계층을 단정하지 않는다
topic: memory-virtualization
topicName: 메모리 가상화
project: virtualization
status: 초안
studio: "https://hyeonworks.com/studio/documents/63fa33e5-9957-4d28-8d3c-c75735a73bd6/edit"
sourceRevision: no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다
source:
- final/document.md#86-문제를-진단할-때의-분류
- final/document.md#63-swap-used만-보고-장애를-판단하면-안-된다
- final/document.md#78-numa는-실제-장비-topology부터-확인한다
- final/document.md#88-결론
- final/document.md#61-guest-swap과-host-swap
- final/document.md#72-guest-oom과-host-oom
---
# 메모리 증상 하나로 계층을 단정하지 않는다
§86 은 메모리 지연이나 OOM(Out Of Memory, 커널이 필요한 메모리를 확보하지 못해 프로세스를 종료할 수 있는 상태)이 보일 때 한 번에 「메모리 부족」이라고 결론내리지 말라고 적었다. 대신 증상을 먼저 다섯 갈래로 가르는 분류를 두었다. Guest Virtual Memory · Virtualization Translation · Host Memory · Dynamic Memory · NUMA 다섯이다. 마지막의 NUMA(Non-Uniform Memory Access, 비균일 메모리 접근)는 어느 CPU 가 어느 RAM 에 접근하느냐에 따라 비용이 달라질 수 있는 구조다.
같은 요구가 개념 문서 안에서 세 번 더 나온다. Swap Used 값 하나로 판단하지 않고(§63), NUMA 최적화를 토폴로지를 재기 전에 정하지 않으며(§78), 게스트 하나의 free -h 만 보고 메모리 상태를 판단하지 않는다(§88). 이 기준은 그 넷을 한 판독 절차로 묶는다. 뒤의 셋을 따로 규칙으로 세우지 않은 것은 보는 대상만 다를 뿐 §86 과 같은 말을 하기 때문이다. 규칙이 세 벌이면 판독하는 사람이 어느 것을 따르는지가 갈린다.
## 관계
- **VM 에서 page fault 는 세 계층에서 따로 일어난다**
Guest Virtual Memory 갈래와 Virtualization Translation 갈래, Host Memory 갈래가 각각 어떤 fault 로 보이는지를 그 기록이 푼다.
- **Host 메모리 압박이 Guest 와 스토리지까지 내려가는 경로**
Host Memory 갈래로 좁힌 뒤에 무엇이 이어지는지를 그 기록이 설명한다.
- **virtio-balloon 이 Guest 메모리를 회수하고 돌려주는 방식**
Dynamic Memory 갈래에서 볼 balloon target 과 Guest pressure 가 그 기록에서 나온다.
- **NUMA 에서는 vCPU 배치와 메모리 배치를 함께 본다**
NUMA 갈래로 좁혔을 때 vCPU placement 와 memory placement 를 왜 따로 읽으면 안 되는지를 그 기록이 설명한다.
- **메모리 실험 결과에는 Host · VM · Workload 조건을 함께 남긴다**
이 기준은 갈래를 좁히는 데까지만 쓰이고, 원인을 확정하는 측정은 그 기준이 요구한 조건과 함께 남긴다.
- **지금 게스트와 호스트에서 swap 이 실제로 오가고 있는가**
2 번 규칙과 3 번 규칙이 요구한 관측을 이 호스트에서 실제로 수행하는 물음이다.
- **게스트 page fault 증가는 workload 변화를 따라가는가**
Guest Virtual Memory 갈래로 좁힌 증상을 워크로드와 견주는 물음이다.
## 목적
이 기준은 증상 하나를 원인으로 바로 옮기는 판독을 막는다. §86 이 든 예가 메모리 지연과 OOM 인데, 둘 다 다섯 계층 어디서든 나올 수 있다.
다섯 갈래를 개념 한 편 안에 넣지 않고 따로 세운 것은 갈래마다 받는 개념이 다르기 때문이다. 어느 한 개념 안에 두면 그 글이 나머지 넷을 가리키지 못한다.
좁히는 것과 확정하는 것을 갈라 둔 이유도 여기 있다. 이 기준은 어느 갈래인지까지만 좁히고, 원인 확정은 §85 의 조건을 함께 남긴 측정이 한다.
## 규칙
### 1. 증상을 다섯 갈래로 먼저 가른다
§86 의 분류는 메모리 지연이나 OOM 을 다섯으로 나누고, 갈래마다 볼 것을 함께 적었다.
Guest Virtual Memory : Page Fault · Guest reclaim · Guest swap · Guest OOM
Virtualization Translation : EPT-related event · TLB pressure · Huge-page/mapping 특성
Host Memory : Host reclaim · Host swap · Host major fault · Host OOM
Dynamic Memory : Balloon target · Guest pressure · Hotplug/virtio-mem 여부
NUMA : vCPU placement · memory placement · remote access
### 2. Swap Used 값 하나로 메모리 압박을 단정하지 않는다
§63 은 Swap Used = 2 GiB 라는 값만으로 지금 메모리 압박이 심하다고 단정할 수 없다고 적었다. 과거에 swap-out 된 cold page 가 남아 있을 수도 있기 때문이다.
같은 절이 대신 물으라고 한 것은 넷이다.
현재 swap-in/out 이 지속되는가?
reclaim pressure 가 증가하는가?
major fault 가 증가하는가?
storage latency 가 같이 증가하는가?
이 넷은 게스트와 호스트를 동시에 확인해야 한다고 §63 이 못박았고, 확인 명령으로 free -h 와 vmstat 1 을 들었다.
### 3. 게스트 스왑과 호스트 스왑을 한 값으로 세지 않는다
§61 은 두 스왑이 서로 다른 경로라고 적었다. 게스트 스왑은 게스트 메모리 압박에서 시작해 게스트 커널과 게스트 스왑을 지나 /dev/vda 로 내려가고, virtio-blk 와 QEMU 를 거쳐 호스트 스토리지에 닿는다. 호스트 스왑은 게스트 RAM 의 QEMU memory backing 이 호스트 메모리 압박을 만나 호스트 커널의 스왑으로 내려가는 경로다.
경로가 이렇게 갈리다 보니, 게스트는 메모리에 여유가 있어 보이는데 호스트에서는 스왑과 reclaim 이 심할 수도 있다.
### 4. OOM 은 발생 계층을 확인한 뒤에 부른다
§72 는 게스트 OOM 과 호스트 OOM 을 갈랐다. 게스트 RAM 이 모자라서 게스트 커널이 프로세스를 죽이면 Keycloak 프로세스 종료 같은 결과가 된다. 호스트 물리 RAM 이 모자라서 호스트 커널이 QEMU 를 victim 으로 고르면 그 VM 전체가 중단될 수 있다.
cgroup memory limit 이 걸린 환경은 예외로 둔다. 호스트 전체 RAM 에 여유가 있어도 그 cgroup 경계에서 OOM 이 발생할 수 있다고 같은 절이 적었다.
### 5. NUMA 갈래는 토폴로지를 잰 뒤에 순위를 매긴다
§78 은 호스트가 NUMA node 한 개면 cross-node remote-memory 문제가 주요 이슈가 아닐 수 있어서, 실제 환경에서는 먼저 토폴로지를 재고 NUMA 최적화가 필요한지 판단하라고 했다.
확인 명령으로는 lscpu 와 numactl --hardware 를 들었다. QEMU 프로세스별 메모리 분포는 numastat -p <QEMU_PID>, vCPU 배치는 virsh vcpupin <VM_NAME> 과 virsh vcpuinfo <VM_NAME> 을 들었다.
### 6. 게스트 하나의 free -h 로 닫지 않는다
§88 은 실제 테스트 서버에서 게스트 하나의 free -h 만 보고 메모리 상태를 판단하지 않는다고 적었다. Guest → QEMU → Host → NUMA → Storage 영향을 같은 시간축에서 관측해야 한다고 했다.
## 적용 조건
메모리 증상을 원인으로 옮기려는 판독 전부에 걸린다. 지연 증가, 스왑 관측, OOM, fault 증가가 여기 들어간다.
가르는 축은 다섯이고, 갈래마다 무엇을 볼지는 1 번 규칙에 적혀 있다.
## 예외
cgroup memory limit 이 걸린 환경에서는 호스트 전체 RAM 에 여유가 있어도 그 경계에서 OOM 이 나기 때문에, Host Memory 갈래를 곧바로 지우면 안 된다(§72).
NUMA node 가 하나인 호스트에서는 NUMA 갈래의 우선순위를 낮춰도 된다고 §78 이 적었다. 그것도 토폴로지를 잰 뒤의 이야기다.
이 기준은 갈래를 좁힐 뿐 원인을 확정하지 않는다. 확정은 §85 의 조건을 남긴 측정이 한다.
## 예시
- 게스트에서 Swap Used 만 보고 「메모리 부족」으로 닫은 판독 : swap-in/out 이 지속되는지를 재지 않았다
- 게스트 free -h 에 여유가 보여 호스트를 보지 않은 판독 : 호스트 reclaim 과 호스트 스왑을 확인하지 않았다
- Keycloak 프로세스가 죽었는데 호스트 커널 로그를 보지 않은 판독 : 게스트 OOM 인지 호스트 OOM 인지 갈리지 않는다
- 호스트 RAM 에 여유가 있다는 이유로 OOM 을 다른 갈래로 넘긴 판독 : cgroup 경계를 확인하지 않았다
- 토폴로지를 재지 않고 vCPU pinning 부터 손댄 조치 : NUMA 갈래가 이 호스트에 걸리는지 모른다
- 게스트와 호스트를 다른 시각에 찍어 한 표로 놓은 기록 : 같은 시간축이 아니다
@@ -0,0 +1,106 @@
---
id: ded41b52-ec08-4231-a54c-86d6c80d38f0
kind: REFERENCE
slug: record-the-conditions-with-every-memory-experiment
title: 메모리 실험 결과에는 Host · VM · Workload 조건을 함께 남긴다
topic: memory-virtualization
topicName: 메모리 가상화
project: virtualization
status: 초안
studio: "https://hyeonworks.com/studio/documents/ded41b52-ec08-4231-a54c-86d6c80d38f0/edit"
sourceRevision: no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다
source:
- final/document.md#85-실험-시-반드시-같이-기록할-것
- final/document.md#84-권장-실험-순서
- final/document.md#83-실제-환경에서-확인할-open-question
---
# 메모리 실험 결과에는 Host · VM · Workload 조건을 함께 남긴다
메모리 측정은 값만 남기면 다음 사람이 그 값을 어디에 쓸 수 있는지 알 수 없다. §85 는 실험마다 함께 적을 조건을 Host 여덟 · VM 일곱 · Workload 다섯으로 못박았다. 이유도 한 줄로 적었는데, 조건을 남기지 않으면 「Memory pressure에서 느려졌다」는 결과를 다른 환경에 재사용하기 어렵다는 것이다.
이 기준은 그 세 묶음을 메모리 측정 기록의 필수 항목으로 둔다. 어느 단계에서 그 값을 얻는지는 §84 의 권장 실험 순서에서 가져왔다. 이 주제의 열린 물음 열둘이 전부 같은 규칙에 걸려서, 조건 목록을 물음마다 되풀이하는 대신 여기 한 편에 두고 각 물음이 가리킨다.
## 관계
- **메모리 증상 하나로 계층을 단정하지 않는다**
증상을 어느 갈래로 좁힐지는 그 기준이 정하고, 좁힌 뒤에 재는 값을 어떤 조건과 함께 남길지는 이 기준이 정한다.
- **Guest 메모리 주소가 물리 RAM 에 닿기까지 — GVA · GPA · HPA**
VM 묶음의 Configured RAM 과 Current RAM 을 왜 따로 적는지가 그 기록의 세 값 구분에서 나온다.
- **Huge Page 를 VM 에서 볼 때 갈라지는 세 자리**
Host 묶음의 THP policy 와 VM 묶음의 Memory backing 설정이 그 기록에서 갈라지는 두 값이다.
- **Host 메모리 압박이 Guest 와 스토리지까지 내려가는 경로**
Host 묶음에 Swap 설정과 Physical storage 가 들어간 이유를 그 기록이 설명한다.
- **호스트 메모리 압박이 게스트 애플리케이션 지연을 실제로 밀어 올리는가**
baseline 과 부하 구간을 비교하는 실험이라 세 묶음을 두 시점에 각각 남겨야 한다.
- **NUMA remote access 가 이 작업의 지연을 실제로 바꾸는가**
Host 묶음의 NUMA topology 를 먼저 적지 않으면 이 물음의 결과를 다른 장비에 옮길 수 없다.
## 목적
이 기준은 두 가지를 막는다. 조건 없이 남긴 측정값을 다른 장비의 판단 근거로 쓰는 일과, baseline 과 부하 구간을 비교해 놓고 두 시점 사이에 무엇이 달라져서 값이 달라졌는지 되짚지 못하는 일이다.
메모리 값은 장비 설정에 크게 기댄다. §53 은 THP(Transparent Huge Pages, 커널이 조건이 맞는 메모리 영역에 큰 page 를 자동으로 쓰는 기능) 정책을 실제 시스템에서 확인하라고 적었다. 정책 값이 커널과 배포판, 호스트 설정에 따라 다르기 때문이다. §78 은 호스트가 NUMA(Non-Uniform Memory Access, 비균일 메모리 접근) node 한 개면 cross-node remote-memory 문제가 주요 이슈가 아닐 수 있다고 적었다. 같은 워크로드를 돌려도 이 두 설정이 다르면 두 측정을 나란히 놓고 읽을 수 없다.
## 규칙
### 1. Host 조건 여덟 항목을 실험마다 적는다
CPU model, Core / Thread 수, RAM, NUMA topology, Swap 설정, Kernel version, THP policy, Physical storage 여덟을 적는다.
이 가운데 넷은 개념 문서가 따로 이유를 적어 두었다. THP policy 는 §53 이 커널과 배포판, 호스트 설정에 따라 다르니 실제 시스템에서 확인하라고 했고, NUMA topology 는 §78 이 최적화가 필요한지 판단하기 전에 먼저 재라고 했다.
Swap 설정과 Physical storage 가 들어간 이유는 §62 가 이어 놓은 경로에 있다. 호스트 메모리 압박이 reclaim 과 스왑을 부르면 그 I/O 가 데이터베이스 I/O, filesystem writeback 과 같은 물리 장치로 몰리기 때문에 애플리케이션 지연까지 올라갈 수 있다.
### 2. VM 조건 일곱 항목을 적되 Configured RAM 과 Current RAM 을 따로 적는다
vCPU, Configured RAM, Current RAM, Memory backing 설정, Balloon device, Guest swap, Guest kernel 일곱이다.
§42 는 configured memory 와 게스트가 지금 실제로 쓰는 메모리, 호스트에서 지금 resident 인 물리 메모리 셋이 같지 않을 수 있다고 적었다. RAM 을 한 값으로 줄여 적으면 나중에 그 숫자가 셋 가운데 무엇이었는지 알 수 없다.
### 3. Workload 조건 다섯 항목을 적는다
Application, Heap/Memory 설정, Request concurrency, DB workload, 측정 시간 다섯이다.
측정 시간은 §88 이 요구한 관측을 가능하게 한다. 게스트와 QEMU, 호스트, NUMA, 스토리지 영향을 같은 시간축에 놓으려면 각 값이 언제 찍혔는지 알아야 하기 때문이다.
### 4. baseline 과 부하 구간을 비교하는 실험은 두 시점 모두에 세 묶음을 남긴다
세 묶음 안에는 실험 중에 달라지는 항목이 들어 있다. Current RAM 이 그렇고(§42), 게스트 스왑과 호스트 스왑도 부하 구간에서만 오갈 수 있다(§61 · §63).
부하 전 값이 없으면 부하 중 값 하나만으로는 그것이 증가인지 원래 그런 값인지 갈리지 않으니, 두 시점을 모두 남긴다.
### 5. 조건이 먼저 채워지는 순서로 실험을 배치한다
§84 의 권장 순서는 호스트 물리 메모리와 NUMA 확인에서 시작한다. 이어서 VM configured memory, Guest free/meminfo, QEMU RSS 와 HVA backing 상태, THP/HugeTLB 상태를 차례로 본다. 압박 실험은 열 번째다.
앞의 다섯 단계가 Host 묶음과 VM 묶음을 그대로 채우기 때문에, 순서를 지키면 압박 실험을 시작할 때 조건을 다시 모으지 않아도 된다.
§84 를 따로 뽑아 기록 한 편으로 만들지는 않았다. 그 순서는 어느 물음을 먼저 여느냐를 정할 뿐이라 순서만 읽을 사람이 없고, 조건이 먼저 채워진다는 뜻만 이 규칙으로 옮겼다.
## 적용 조건
메모리 관련 측정을 남기는 실험 전부에 걸린다. §83 의 OQ-1 부터 OQ-14 까지가 여기 들어가고, 이 주제의 열린 물음 열둘도 같은 규칙을 따른다.
남길 조건은 세 묶음이다.
Host : CPU model · Core/Thread 수 · RAM · NUMA topology · Swap 설정 · Kernel version · THP policy · Physical storage
VM : vCPU · Configured RAM · Current RAM · Memory backing 설정 · Balloon device · Guest swap · Guest kernel
Workload : Application · Heap/Memory 설정 · Request concurrency · DB workload · 측정 시간
## 예외
단일 값을 한 번 읽고 끝나는 확인에는 Workload 묶음이 비어 있어도 된다. THP 정책 문자열 하나를 읽는 §83 OQ-4 가 그렇다.
baseline 과 부하 구간을 비교하는 실험에서는 세 묶음을 두 시점에 각각 남긴다. 한 번만 남기면 비교한 두 시점 가운데 한쪽의 조건이 빈다.
이 프로젝트는 조건 목록을 실제 장비 값으로 채운 적이 없다. §85 가 준 것은 항목 이름이고 값은 아직 없다.
## 예시
- 호스트 RAM 을 적지 않고 남긴 「부하 중 게스트가 느려졌다」 : 다른 장비에서 다시 쓸 수 없다
- THP 정책 문자열 하나만 읽는 확인 : Workload 묶음을 비워 둔다
- Configured RAM 만 적고 Current RAM 을 비운 기록 : §42 가 갈라 놓은 값을 하나로 합친 것이라 다시 재야 한다
- 부하 전 값 없이 부하 중 vmstat 만 남긴 기록 : 증가폭을 적을 수 없다
- 측정 시간을 빼고 게스트 값과 호스트 값을 따로 남긴 기록 : 같은 시간축에 놓을 수 없다
- 권장 순서 1 번부터 5 번까지를 먼저 돌린 뒤 시작한 압박 실험 : Host 묶음과 VM 묶음이 이미 채워져 있다