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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,258 @@
{
"version": "1.1",
"id": "vms-sharing-one-nvme",
"title": "가상 머신 둘과 호스트 프로세스가 하나의 NVMe 로 모인다",
"question": "서로 다른 곳에서 시작한 I/O 는 어디에서 하나로 모여 device 로 나가는가",
"type": "flow",
"direction": "TB",
"audience": [
"가상 머신 위에서 본 저장소 지연의 원인을 가르려는 사람",
"Storage Contention 과 CPU Contention 을 나눠 재려는 사람"
],
"summary": "VM1 QEMU 와 VM2 QEMU, Nginx, 호스트의 다른 프로세스에서 시작한 I/O 가 모두 하나의 Host Block Layer queue 로 들어가 NVMe 로 dispatch 된다.",
"alt": "VM1 QEMU, VM2 QEMU, Nginx, Host 기타 네 곳에서 나온 화살표가 하나의 Host Block Layer 로 모이고 거기서 NVMe 로 나가는 수렴 흐름도.",
"long_description": "위쪽에 네 출발점이 나란히 있다. VM1 QEMU 는 WRITE X 와 READ Y, WRITE Z 를 내고 VM2 QEMU 는 READ A 와 WRITE B 를 내며, 그 옆에 호스트의 Nginx 와 다른 프로세스가 있다. 네 갈래가 모두 가운데의 Host Block Layer 하나로 모인다. Host Block Layer 는 그 I/O 가 가상 머신 안에서 시작했는지 호스트 프로세스에서 시작했는지를 본질적으로 구분해 처리하는 계층이 아니라 들어온 것을 모두 Host block request 로 다루고, 그 요청들을 queue 에서 관리해 맨 아래 NVMe 로 dispatch 한다. 여기서 생기는 경쟁이 Storage Contention 이고 CPU 실행 시간을 두고 벌어지는 CPU Contention 과는 다투는 자원이 다르다는 것은 본문 문단이 맡는다.",
"source_context": {
"document": "docs/virtualization/final/document.md",
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
"anchor": {
"kind": "heading",
"value": "159. 여러 VM이 하나의 NVMe를 공유하면",
"line": 7026
}
},
"composition": {
"profile": "component-flow",
"diagram_only": true,
"reference_ids": [
"payment-event-flow"
],
"rationale": "이 절이 주장하는 것은 서로 다른 네 곳에서 시작한 요청이 한 자리로 모인다는 것이다. query-fanout 은 하나가 여러 저장소로 갈라지는 문법이라 방향이 반대이고, orchestrator-workers 는 가운데가 아래의 워커들에게 일을 나눠 주는 그림이라 「모인다」가 「나눈다」로 뒤집힌다. comparison 은 네 출발점을 나란히 늘어놓기만 해서 하나의 queue 로 모인다는 사실이 사라진다.",
"focus_node": "host-block-layer"
},
"groups": [],
"nodes": [
{
"id": "vm1-qemu",
"label": "VM1 QEMU",
"kind": "service",
"role": "source",
"shape": "box",
"details": [
"WRITE X",
"READ Y",
"WRITE Z"
],
"description": "가상 머신 하나의 QEMU 프로세스. 게스트의 I/O 가 여기서 호스트 파일 I/O 가 된다.",
"evidence": [
{
"start_line": 7029,
"end_line": 7029
},
{
"start_line": 7041,
"end_line": 7044
}
],
"assumption": false
},
{
"id": "vm2-qemu",
"label": "VM2 QEMU",
"kind": "service",
"role": "source",
"shape": "box",
"details": [
"READ A",
"WRITE B"
],
"description": "다른 가상 머신의 QEMU 프로세스.",
"evidence": [
{
"start_line": 7031,
"end_line": 7031
},
{
"start_line": 7046,
"end_line": 7048
}
],
"assumption": false
},
{
"id": "nginx",
"label": "Nginx",
"kind": "service",
"role": "source",
"shape": "box",
"description": "호스트에서 직접 도는 프로세스.",
"evidence": [
{
"start_line": 7033,
"end_line": 7033
}
],
"assumption": false
},
{
"id": "host-other",
"label": "Host 기타",
"kind": "service",
"role": "source",
"shape": "box",
"description": "그 밖의 호스트 프로세스.",
"evidence": [
{
"start_line": 7035,
"end_line": 7038
}
],
"assumption": false
},
{
"id": "host-block-layer",
"label": "Host Block Layer",
"kind": "service",
"role": "queue",
"shape": "box",
"emphasis": "primary",
"details": [
"Host block request",
"blk-mq"
],
"description": "어디서 왔는지 구분하지 않고 모두 Host block request 로 다루는 계층. queue 에서 관리해 device 로 내보낸다.",
"evidence": [
{
"start_line": 7031,
"end_line": 7031
},
{
"start_line": 7017,
"end_line": 7022
},
{
"start_line": 7054,
"end_line": 7054
},
{
"start_line": 7058,
"end_line": 7060
}
],
"assumption": false
},
{
"id": "nvme",
"label": "NVMe",
"kind": "device",
"role": "sink",
"shape": "cylinder",
"description": "네 갈래가 결국 함께 쓰는 하나의 물리 device.",
"evidence": [
{
"start_line": 7031,
"end_line": 7031
},
{
"start_line": 7019,
"end_line": 7019
},
{
"start_line": 7066,
"end_line": 7069
}
],
"assumption": false
}
],
"edges": [
{
"id": "vm1-to-block-layer",
"from": "vm1-qemu",
"to": "host-block-layer",
"label": "",
"kind": "data",
"style": "solid",
"order": 1,
"evidence": [
{
"start_line": 7029,
"end_line": 7031
}
],
"assumption": false
},
{
"id": "vm2-to-block-layer",
"from": "vm2-qemu",
"to": "host-block-layer",
"label": "",
"kind": "data",
"style": "solid",
"order": 2,
"evidence": [
{
"start_line": 7031,
"end_line": 7031
}
],
"assumption": false
},
{
"id": "nginx-to-block-layer",
"from": "nginx",
"to": "host-block-layer",
"label": "",
"kind": "data",
"style": "solid",
"order": 3,
"evidence": [
{
"start_line": 7031,
"end_line": 7033
}
],
"assumption": false
},
{
"id": "host-other-to-block-layer",
"from": "host-other",
"to": "host-block-layer",
"label": "",
"kind": "data",
"style": "solid",
"order": 4,
"evidence": [
{
"start_line": 7031,
"end_line": 7035
}
],
"assumption": false
},
{
"id": "block-layer-to-nvme",
"from": "host-block-layer",
"to": "nvme",
"label": "dispatch",
"kind": "data",
"style": "solid",
"order": 5,
"evidence": [
{
"start_line": 7031,
"end_line": 7031
},
{
"start_line": 7054,
"end_line": 7054
}
],
"assumption": false
}
],
"legend": [],
"metadata": {
"rationale": "component-flow 를 고른 이유는 이 절이 답하는 물음이 「여러 곳에서 온 요청이 어디에서 하나가 되는가」이기 때문이고, 그 수렴은 자리로만 보인다. 네 출발점의 화살표에는 라벨을 달지 않았다 — 넷이 같은 「Host block request」라는 것이 이 그림의 논지인데 같은 라벨을 네 번 겹쳐 놓으면 라벨끼리 먹힌다. 그래서 그 이름은 모이는 노드의 details 로 올렸다. blk-mq 도 노드가 아니라 details 다 — §160 이 그리는 것은 CPU 넷이 자기 queue 를 갖는 다른 수렴이라 이 그림의 네 출발점과 같은 축에 놓을 수 없다. I/O Scheduler 와 NVMe Driver 는 §161 과 §164 가 대는 사실인데 이 앵커의 준비된 문맥(§158~§160) 밖이라 넣지 않았다. §159 의 「Host Process READ C」도 붙이지 않았다 — 그 프로세스가 Nginx 인지 Host 기타인지 SSOT 가 말하지 않는다."
}
}