238 lines
6.8 KiB
JSON
238 lines
6.8 KiB
JSON
{
|
|
"version": "1.1",
|
|
"id": "memory-pressure-reclaim-swap-oom",
|
|
"title": "Host memory pressure가 storage와 OOM으로 갈라지는 경로",
|
|
"question": "Host memory pressure가 생겼을 때 reclaim 이후 어떤 경로가 swap I/O와 storage contention으로 이어지고, 확보 실패는 어디서 OOM으로 이어지는가",
|
|
"type": "data-flow",
|
|
"direction": "LR",
|
|
"audience": [
|
|
"VM host 메모리 압박을 추적하는 개발자",
|
|
"swap과 OOM의 발생 계층을 구분하려는 운영자"
|
|
],
|
|
"summary": "Host memory pressure는 reclaim으로 시작한다. clean file-backed page는 버렸다가 필요할 때 storage에서 다시 읽을 수 있고 anonymous page는 Host swap I/O로 이어질 수 있다. reclaim으로도 메모리를 확보하지 못하면 Host OOM 경로가 열린다.",
|
|
"alt": "Host memory pressure가 reclaim에서 clean page 재읽기, anonymous page의 Host swap과 storage contention, 메모리 확보 실패에 따른 Host OOM으로 갈라지는 흐름도. QEMU가 OOM victim이 될 때 VM 전체가 중단될 수 있다는 결과는 본문에서 설명한다.",
|
|
"long_description": "왼쪽에서 Host memory pressure가 reclaim으로 들어간다. reclaim 이후 clean file-backed page는 버렸다가 필요할 때 storage에서 다시 읽는 경로, anonymous page는 Host swap I/O를 통해 physical storage와 경쟁하는 경로, 필요한 메모리를 확보하지 못하면 Host OOM으로 가는 경로로 갈린다. storage contention이 application latency로 이어지는 결과와 Host OOM이 QEMU를 victim으로 고를 때 VM 전체가 중단될 수 있다는 결과는 본문에서 이어 설명한다.",
|
|
"source_context": {
|
|
"document": "docs/virtualization/final/document.md",
|
|
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
|
|
"anchor": {
|
|
"kind": "heading",
|
|
"value": "제2부 — 메모리 가상화",
|
|
"line": 1670
|
|
}
|
|
},
|
|
"composition": {
|
|
"profile": "component-flow",
|
|
"diagram_only": true,
|
|
"reference_ids": [
|
|
"payment-event-flow"
|
|
],
|
|
"rationale": "압박 하나가 reclaim 뒤 여러 자원 경로로 갈라지고 다시 storage contention과 OOM 결과로 이어지는 흐름이 핵심이다.",
|
|
"focus_node": "reclaim"
|
|
},
|
|
"groups": [],
|
|
"nodes": [
|
|
{
|
|
"id": "pressure",
|
|
"label": "Host memory pressure",
|
|
"kind": "resource",
|
|
"role": "source",
|
|
"description": "실제 Host RAM 수요가 available physical memory에 접근한 상태.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2818,
|
|
"end_line": 2831
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "reclaim",
|
|
"label": "Reclaim",
|
|
"kind": "component",
|
|
"role": "service",
|
|
"emphasis": "primary",
|
|
"description": "Linux가 회수 가능한 page/cache를 처리하는 첫 대응.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2818,
|
|
"end_line": 2831
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "clean-page",
|
|
"label": "clean file-backed page",
|
|
"kind": "data",
|
|
"role": "service",
|
|
"details": [
|
|
"discard · reread"
|
|
],
|
|
"description": "원본이 storage에 있어 RAM에서 제거하고 나중에 다시 읽을 수 있다.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2834,
|
|
"end_line": 2848
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "host-swap",
|
|
"label": "Host swap I/O",
|
|
"kind": "storage",
|
|
"role": "store",
|
|
"details": [
|
|
"anonymous page"
|
|
],
|
|
"description": "anonymous page의 backing이 필요할 때 host swap I/O가 생길 수 있다.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2850,
|
|
"end_line": 2852
|
|
},
|
|
{
|
|
"start_line": 2856,
|
|
"end_line": 2886
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "storage",
|
|
"label": "Storage contention",
|
|
"kind": "storage",
|
|
"role": "store",
|
|
"shape": "database",
|
|
"details": [
|
|
"Host swap",
|
|
"DB I/O",
|
|
"writeback"
|
|
],
|
|
"description": "여러 I/O가 한 physical device에 몰려 contention을 만든다.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2938,
|
|
"end_line": 2965
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "host-oom",
|
|
"label": "Host OOM",
|
|
"kind": "result",
|
|
"role": "service",
|
|
"description": "reclaim 등으로도 필요한 memory 확보에 실패했을 때 Host kernel에서 발생할 수 있다.",
|
|
"evidence": [
|
|
{
|
|
"start_line": 3213,
|
|
"end_line": 3231
|
|
},
|
|
{
|
|
"start_line": 3249,
|
|
"end_line": 3265
|
|
}
|
|
],
|
|
"assumption": false
|
|
}
|
|
],
|
|
"edges": [
|
|
{
|
|
"id": "pressure-reclaim",
|
|
"from": "pressure",
|
|
"to": "reclaim",
|
|
"label": "pressure",
|
|
"kind": "control",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2818,
|
|
"end_line": 2831
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "reclaim-clean",
|
|
"from": "reclaim",
|
|
"to": "clean-page",
|
|
"label": "file-backed",
|
|
"kind": "control",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2834,
|
|
"end_line": 2848
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "clean-storage",
|
|
"from": "clean-page",
|
|
"to": "storage",
|
|
"label": "reread",
|
|
"kind": "data",
|
|
"style": "dashed",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2834,
|
|
"end_line": 2848
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "reclaim-swap",
|
|
"from": "reclaim",
|
|
"to": "host-swap",
|
|
"label": "anonymous",
|
|
"kind": "data",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2850,
|
|
"end_line": 2852
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "swap-storage",
|
|
"from": "host-swap",
|
|
"to": "storage",
|
|
"label": "swap",
|
|
"kind": "data",
|
|
"evidence": [
|
|
{
|
|
"start_line": 2871,
|
|
"end_line": 2886
|
|
},
|
|
{
|
|
"start_line": 2940,
|
|
"end_line": 2946
|
|
}
|
|
],
|
|
"assumption": false
|
|
},
|
|
{
|
|
"id": "reclaim-oom",
|
|
"from": "reclaim",
|
|
"to": "host-oom",
|
|
"label": "확보 실패",
|
|
"kind": "control",
|
|
"style": "dashed",
|
|
"evidence": [
|
|
{
|
|
"start_line": 3213,
|
|
"end_line": 3231
|
|
}
|
|
],
|
|
"assumption": false
|
|
}
|
|
],
|
|
"legend": [],
|
|
"metadata": {
|
|
"rationale": "분기와 재합류를 모두 넣어 자동 배치가 교차하던 이전 안을 줄였다. 그림은 Host pressure가 reclaim 뒤 clean-page·Host swap·Host OOM으로 갈리는 구조까지만 보이고, application latency와 QEMU victim 결과는 본문에 남긴다."
|
|
}
|
|
}
|