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,95 @@
---
id: decbab8d-9c98-45c6-b5b8-e6162e407299
kind: REFERENCE
slug: a-speedup-that-removed-durability-is-not-an-optimization
title: 빨라진 구성이 durability contract 를 지운 것은 아닌지 먼저 가른다
topic: storage-virtualization
topicName: 스토리지 가상화
project: virtualization
status: 초안
studio: "https://hyeonworks.com/studio/documents/decbab8d-9c98-45c6-b5b8-e6162e407299/edit"
sourceRevision: no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다
source:
- final/document.md#171-성능과-durability의-trade-off
- final/document.md#152-가장-위험한-상황-거짓-완료
- final/document.md#156-writeback-=-위험-이라고-단정하면-안-되는-이유
- final/document.md#148-write-완료와-영속화는-다르다
- final/document.md#157-device-side-cache
- final/document.md#150-fsync-가-필요한-이유
- final/document.md#170-postgresql-예시-wal과-durability
- final/document.md#174-핵심-claim
---
# 빨라진 구성이 durability contract 를 지운 것은 아닌지 먼저 가른다
durability 는 전원이 나가도 데이터가 남아 있는 영속성을 말한다. 쓰기 지연이 줄면 그 변경은 성능 개선으로 기록되지만, 무엇을 더 이상 보장하지 않게 됐는지는 아무 데도 적히지 않는다. 개념 문서는 fsync() 를 없애서 빨라졌다면 그것이 최적화가 아니라 durability contract 를 제거한 것일 수 있다고 적었다. 게스트가 요청한 FLUSH 에 완료로 응답했는데 데이터는 호스트 RAM 에만 있는 상태도 성능 문제가 아니라 correctness 문제로 놓았다. 이 기준은 빨라진 구성을 평가할 때 어느 단계가 빠졌는지를 먼저 적게 한다.
## 관계
- **완료라는 말의 네 가지 뜻 — write · writeback · flush · 전원 장애 생존**
이 기준이 갈라 적으라고 하는 네 단계를 그 글이 설명한다.
- **/dev/vda 뒤에 있는 것 — qcow2 · RAW · Host block device**
영속성을 어느 백엔드 위에서 이야기하는지 그 글이 설명한다.
- **이 VM 들의 QEMU disk cache mode 는 무엇인가**
이 기준이 걸리는 설정 값을 이 환경에서 읽는 물음이다.
- **Guest 의 fsync() 지연과 Host storage 지연은 같이 오르는가**
영속성을 지킨 상태의 지연이 얼마인지 이 환경에서 재는 물음이다.
- **지연 원인을 CPU 로 읽기 전에 storage 계층을 따로 잰다**
같은 스토리지 판독에 쓰는 기준이고, 그쪽은 자원을 가르고 이쪽은 보장을 가른다.
## 목적
스토리지 설정을 바꿔 쓰기 지연이 줄었을 때 그것을 성능 항목으로만 적으면 어떤 실패에 노출됐는지가 기록에 남지 않는다. 개념 문서가 가장 위험한 상황으로 든 것은 거짓 완료다. 게스트가 WRITE 와 FLUSH 를 요청했는데 데이터는 호스트 RAM 에 있고 물리 스토리지에는 옛 데이터가 있는 상태인데도 게스트에게 FLUSH 완료라고 응답하는 경우다. 그러면 PostgreSQL 은 영속성이 확보되었다고 판단하고, 직후 호스트 전원이 나가면 RAM 의 데이터가 사라진다.
이 기준은 빨라진 것을 되돌리라고 하지 않는다. 무엇이 빨라졌는지 옆에 어느 보장이 사라졌는지를 같이 적게 한다.
이것을 완료의 네 단계를 설명하는 개념 기록 안의 각주로 두지 않고 따로 뺀 것은 이것이 필요해지는 때가 다르기 때문이다. 개념을 읽을 때가 아니라 설정을 고르고 성능 개선을 평가할 때 걸리는데, 각주로 두면 다음에 같은 판단을 하는 사람이 그때 이것을 찾지 못한다.
## 규칙
### 1. 완료를 네 단계로 갈라 어디까지 보장되는지 적는다
개념 문서는 write() 완료와 writeback 완료와 fsync/flush 완료와 전원 장애에도 안전한 durability 를 서로 다른 것으로 놓았다. write(fd, data, size) 가 성공했다는 것만으로 정전 이후 생존이 보장되지 않으므로, 필요한 시점에 fsync(fd) 를 불러 변경 내용을 필요한 영속성 경계까지 반영하도록 요청한다. 어떤 구성을 적을 때 이 네 단계 중 어디까지가 보장되는지를 함께 적는다.
### 2. 빨라진 구성에서 사라진 경계를 이름으로 적는다
무엇이 몇 밀리초 줄었는지보다 먼저, 그 변경이 위 네 단계 중 어느 것을 건너뛰게 했는지를 적는다. 개념 문서가 그린 전달 경로는 게스트가 요구한 durability 에서 시작한다. 거기서 Guest Filesystem, Guest Block Layer, virtio, QEMU 와 backend, Host Storage, Device 로 이어진다. 이 경로는 어디에서 의미가 끊겨도 결과가 같아서, 끊긴 곳을 짚지 못하면 그 구성이 무엇을 보장하는지 다음 사람이 다시 조사해야 한다.
### 3. 거짓 완료를 성능 항목으로 분류하지 않는다
FLUSH 완료 응답을 받은 쪽은 그 데이터가 살아남는다고 가정하고 그 다음 동작을 한다. PostgreSQL 이라면 COMMIT 을 성공으로 처리한다. 이 가정이 틀린 상태는 느려지는 것이 아니라 응답한 내용이 사실과 다른 것이므로, 개념 문서는 이것을 durability contract 가 깨지는 correctness 문제로 적었다.
### 4. 캐시 모드를 이름만 보고 안전과 위험으로 가르지 않는다
개념 문서는 none 을 캐시 자체가 없음으로, writeback 을 무조건 위험으로 읽는 것이 부정확하다고 적었다. cache=writeback 을 골라도 정상적인 스택이라면 게스트의 fsync 와 FLUSH 는 virtio FLUSH 와 QEMU 와 백엔드를 지나 호스트의 sync 와 flush 로 전달된다. 필요한 완료 확인 뒤에 게스트로 완료가 돌아간다. 개념 문서는 정확한 표현을 이렇게 적었다 — writeback caching 에서는 volatile cache 가 존재할 수 있으므로 Guest 의 flush/fsync semantics 가 전체 backend/storage stack 에서 올바르게 보존되는지가 중요하다.
그래서 이 기준은 어느 캐시 모드를 쓰라고 말하지 않는다. 개념 문서는 두 설정의 뜻과 각각의 오해를 갈라 놓기만 했고 어느 쪽으로 정했다고 적지 않았으며 감수한 비용도 적지 않았다. 이 호스트가 지금 무엇을 쓰고 있는지도 아직 읽지 않았다.
### 5. DB 부하에서는 애플리케이션이 쓰는 영속성 규약을 함께 적는다
PostgreSQL 은 WAL 등의 durability protocol 을 사용하며 필요한 시점에 스토리지 동기화를 수행한다. 가상 머신의 스토리지 계층이 flush 와 fsync 의 의미를 제대로 보존하지 않으면 애플리케이션이 전제한 영속성과 실제 스토리지 동작이 어긋난다. 그래서 설정만 적지 않고 그 위에서 도는 애플리케이션이 무엇을 언제 동기화하는지도 같이 적는다.
## 적용 조건
- 스토리지 관련 설정이나 코드를 바꿔 쓰기 지연이나 커밋 지연이 줄었을 때
- QEMU 의 캐시 모드를 고르기 전
- Direct I/O 를 켜거나 끄기 전
- fsync() 호출을 더하거나 뺄 때
- 파일시스템의 마운트 옵션을 고를 때
## 예외
- 영속성을 실제로 포기해도 되는 데이터가 있다. 다시 만들 수 있는 캐시나 파생 파일이 그렇고, 그때는 빨라진 것이 정당한 선택이다. 이 기준이 요구하는 것은 포기를 막는 것이 아니라 무엇을 포기했는지 적게 하는 것이다.
- cache=none 이나 Direct I/O 를 골랐다고 영속성이 확보되지도 않는다. 개념 문서는 Direct I/O 의 핵심이 페이지 캐시 우회이며 호스트 페이지 캐시를 우회하는 것이 즉시 durable media 반영을 뜻하지 않는다고 적었고, 그 뒤에 스토리지 컨트롤러나 장치가 휘발성 쓰기 캐시를 가질 수 있다고 덧붙였다.
- 개념 문서는 실제 ordering 과 durability semantics 가 더 복잡하다고 밝혔다. 그래서 이 기준으로 특정 설정이 안전하다는 결론을 내지 않는다. 실제 운영에서는 장치의 flush 와 FUA semantics, power-loss protection 여부도 함께 본다.
- 이 저장소에는 영속성을 실제로 재 본 실험이 없다. 여기 적은 것은 개념 문서가 서술한 구분이고 이 호스트에서 확인된 동작이 아니다.
## 예시
- write() 완료 : 애플리케이션 호출이 돌아온 상태
- writeback 완료 : 캐시에서 아래로 내려간 것까지다
- fsync/flush 완료 : 여기서도 장치 쪽 휘발성 캐시가 뒤에 남을 수 있다
- 전원 장애에도 안전한 상태 : 위 셋과 다른 단계로 센다
- 빨라졌다 : 어느 단계를 건너뛰었는지 옆에 적는다
- 포기해도 되는 데이터 : 다시 만들 수 있는 캐시 · 파생 파일
- 이 호스트에서 잰 영속성 측정 : x
@@ -0,0 +1,91 @@
---
id: 274c5636-33f6-4c19-a54b-d2a96af31289
kind: REFERENCE
slug: confirm-the-disk-backend-on-the-host
title: Guest 안에서 본 disk 로 backend 를 단정하지 않는다
topic: storage-virtualization
topicName: 스토리지 가상화
project: virtualization
status: 초안
studio: "https://hyeonworks.com/studio/documents/274c5636-33f6-4c19-a54b-d2a96af31289/edit"
sourceRevision: no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다
source:
- final/document.md#145-host-block-device를-직접-backend로-사용-가능
- final/document.md#146-실제-연결-확인
- final/document.md#143-qcow2-virtual-size와-실제-host-사용량
- final/document.md#144-raw-image
- final/document.md#135-dev-vda-guest가-보는-가상-block-device
- final/document.md#142-qcow2-host에서는-파일-guest에서는-디스크
- final/document.md#169-storage-관측-명령어
---
# Guest 안에서 본 disk 로 backend 를 단정하지 않는다
백엔드는 게스트가 디스크로 쓰는 그 장치를 호스트 쪽에서 실제로 대 주는 것을 말한다. 게스트에 로그인해 lsblk 를 돌리면 /dev/vda 와 그 파티션이 나오고, 거기까지는 물리 머신과 같은 화면이다. 개념 문서는 그 이름이 호스트의 실제 SSD 를 뜻하지 않으며 아래에 qcow2 파일과 RAW 파일과 호스트 블록 장치 셋이 올 수 있다고 적었다. 이 기준은 용량과 성능과 영속성을 판단하기 전에 호스트 쪽에서 무엇에 붙어 있는지를 먼저 확정하게 한다.
## 관계
- **/dev/vda 뒤에 있는 것 — qcow2 · RAW · Host block device**
이 기준이 가르라고 하는 세 갈래를 그 글이 설명한다.
- **Guest 의 write() 가 virtqueue 에 실리기까지 — VFS · Filesystem · Page Cache · Block Layer · virtio-blk**
게스트가 본 그 디스크 이름이 어디에서 나왔는지를 그 글이 설명한다.
- **이 호스트의 /dev/vda 는 어떤 backend 에 붙어 있는가**
이 기준의 첫 확인을 이 환경에서 실제로 돌리는 물음이다.
- **이 disk image 는 qcow2 인가 RAW 인가, 그리고 Guest 가 보는 크기와 Host 가 실제로 쓰는 크기는 얼마나 다른가**
백엔드가 파일로 확정됐을 때 형식과 크기를 읽는 물음이다.
- **disk image 는 최종적으로 어느 Host block device 위에 있는가**
그 파일이 놓인 파일시스템과 블록 장치까지 잇는 물음이다.
- **지연 원인을 CPU 로 읽기 전에 storage 계층을 따로 잰다**
그 기준의 호스트 쪽 관측은 여기서 확정한 백엔드를 전제한다.
## 목적
게스트 안의 이름을 호스트의 저장 구조로 읽으면 그 위에서 하는 판단이 모두 어긋난다. 개념 문서는 게스트 리눅스가 /dev/vda 를 하나의 블록 장치로 인식하지만 그것이 호스트의 실제 SSD 를 뜻하지는 않는다고 적었다. 같은 대상을 호스트 관점에서 보면 파일 하나이고 게스트 관점에서 보면 디스크이며, 둘 다 맞다.
무엇 위에서 재고 있는지가 정해지지 않으면 용량 판독과 성능 판독이 서로 다른 대상을 가리킨다. 게스트가 100 GB 를 본다는 사실과 호스트가 그만큼 쓰고 있다는 사실은 다른 이야기이고, 형식이 무엇인지에 따라 확인할 항목도 달라진다.
개념 문서가 실제 서버에서 확인하라고 적어 둔 물음 가운데 넷이 이 확정 위에서 돌아간다. 백엔드가 무엇인지, 형식이 무엇인지, 크기가 얼마나 벌어져 있는지, 그 아래가 어느 장치인지다. 넷마다 같은 절차를 되풀이해 적지 않고 한 편으로 두었으므로 각 물음이 여기를 가리킨다.
## 규칙
### 1. 게스트의 장치 이름을 호스트의 저장 장치로 옮겨 읽지 않는다
물리 머신에서는 /dev/sda 나 /dev/nvme0n1 이 보이고 virtio-blk 를 쓰는 가상 머신에서는 /dev/vda 나 /dev/vdb 가 보인다. 이름이 그렇게 갈릴 뿐 게스트 쪽 화면은 두 경우 모두 블록 장치 하나와 그 파티션으로 보인다. 게스트에서 얻은 이름은 게스트가 인식한 것까지 말해 주고 그 아래 구조는 말해 주지 않는다.
### 2. Target 과 Source 를 이어 붙인 뒤에 판독을 시작한다
게스트에서 lsblk 로 보이는 블록 장치와 파티션을 적고, 호스트에서 virsh domblklist <VM_NAME> 로 Target 과 Source 를 적는다. 개념 문서가 든 예시에서는 Target vda 에 Source /var/lib/libvirt/images/vm1.qcow2 가 붙어 있었다. 이 대응이 있어야 게스트의 /dev/vda 에서 virtio-blk 와 QEMU 를 지나 그 파일까지 이어진다. 그 경로는 개념 문서가 예시로 붙여 둔 이름이고 이 호스트에서 읽은 값이 아니다 — 두 명령을 이 호스트에서 돌린 출력은 아직 없다.
### 3. Source 가 파일인지 호스트 블록 장치인지 확정한다
개념 문서는 백엔드가 반드시 파일일 필요는 없다고 적고 게스트의 /dev/vda 아래에 호스트의 /dev/nvme0n1p3 이 오는 구성을 들었다. 파일이면 qemu-img info 에 그 경로를 주어 형식을 읽고, 호스트 블록 장치면 qcow2 쪽 확인 항목은 애초에 걸리지 않는다.
### 4. 용량은 virtual size 와 실제 할당을 갈라 읽는다
qcow2 는 가상 디스크 크기와 실제 호스트 할당량이 다를 수 있다. 개념 문서가 든 그림은 게스트가 보는 공간 100 GB 에 호스트 실제 할당 3GB 였다. 게스트가 데이터를 기록하면서 Actual 이 1GB 에서 10GB 로, 다시 40GB 로 늘 수 있다는 예도 함께 보였다. qemu-img info 를 볼 때 virtual size 와 실제 allocation 을 구분해서 봐야 한다.
### 5. 파일이면 그 파일이 놓인 호스트 파일시스템과 블록 장치까지 적는다
백엔드가 qcow2 파일이면 QEMU 는 결국 호스트 리눅스에 파일 입출력을 요청한다. 그 요청은 Host Filesystem 과 Host Block Layer 와 NVMe Driver 를 지나 Physical NVMe 로 내려간다. 게스트의 스토리지 스택 아래에 호스트의 스토리지 스택이 한 번 더 있으므로, 어느 파일시스템과 어느 블록 장치 위에 있는지를 lsblk 로 함께 적는다.
## 적용 조건
- 가상 머신의 디스크 성능이나 용량이나 영속성을 판단하기 전
- 게스트 안에서 잰 스토리지 수치를 해석하기 전
- 저장 공간 계획을 세우거나 이미지를 옮기기 전
- 가상 머신 여러 대가 같은 물리 장치를 쓰는지 확인할 때
## 예외
- 백엔드가 호스트 블록 장치면 qcow2 쪽 확인은 걸리지 않는다. 가상 크기와 실제 할당량의 차이도, 매핑과 메타데이터 처리도 그 구성에는 없다.
- 백엔드를 확정해도 성능은 예측되지 않는다. 개념 문서는 RAW 는 무조건 빠르고 qcow2 는 무조건 느리다는 식으로 일반화하지 말라고 못박고, 실제 성능이 캐시 모드와 스토리지 백엔드와 부하 패턴과 큐 깊이와 스냅숏 체인과 그 아래 파일시스템과 물리 장치에 영향을 받는다고 들었다. 이 기준은 무엇 위에서 재고 있는지까지만 확정한다.
- 이 저장소에는 이 절차를 실제로 돌린 출력이 없다. 여기 적은 것은 개념 문서가 서술한 확인 순서이고 이 호스트에서 나온 값이 아니다.
## 예시
- 게스트에서 보이는 것 : /dev/vda 와 그 파티션
- 호스트에서 이어 붙일 것 : Target 과 Source 의 대응
- Source 의 세 갈래 : qcow2 파일 · RAW 파일 · 호스트 블록 장치
- 용량 : virtual size 와 실제 allocation 을 따로 적는다
- 파일이면 더 볼 것 : 그 파일이 올라간 파일시스템과 블록 장치
- 이 호스트에서 돌린 출력 : x
@@ -0,0 +1,104 @@
---
id: b1cda8c4-d31d-4ae4-a4d9-4103a0ab3109
kind: REFERENCE
slug: read-storage-before-blaming-cpu-for-latency
title: 지연 원인을 CPU 로 읽기 전에 storage 계층을 따로 잰다
topic: storage-virtualization
topicName: 스토리지 가상화
project: virtualization
status: 초안
studio: "https://hyeonworks.com/studio/documents/b1cda8c4-d31d-4ae4-a4d9-4103a0ab3109/edit"
sourceRevision: no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다
source:
- final/document.md#168-cpu가-정상이어도-storage-때문에-느릴-수-있다
- final/document.md#167-storage-contention
- final/document.md#169-storage-관측-명령어
- final/document.md#174-핵심-claim
- final/document.md#177-최종-요약
---
# 지연 원인을 CPU 로 읽기 전에 storage 계층을 따로 잰다
요청이 느린데 CPU 사용률이 낮으면 CPU 는 원인이 아니라고 읽고 다음 후보로 넘어가기 쉬운데, 그 사이에 스토리지 대기는 어느 지표에도 나타나지 않는다. 개념 문서는 애플리케이션이 스토리지 완료를 기다리는 동안 CPU 사용률이 높지 않을 수 있다고 적고 CPU 30% 인데 요청 지연 2초인 조합을 들었다. 이 기준은 자원을 CPU 와 스토리지로 가르는 순서와, 그때 같은 시간축에 무엇을 남길지를 고정한다.
## 관계
- **VM 아래에 한 번 더 있는 Host block stack — blk-mq · I/O Scheduler · NVMe**
이 기준이 함께 보라고 하는 호스트 쪽 지표가 어느 계층에서 나오는지를 그 글이 설명한다.
- **Guest 의 write() 가 virtqueue 에 실리기까지 — VFS · Filesystem · Page Cache · Block Layer · virtio-blk**
게스트 안에서 잰 입출력 지연이 어디까지의 시간인지를 그 글이 설명한다.
- **Guest 안에서 본 disk 로 backend 를 단정하지 않는다**
무엇 위에서 재고 있는지를 먼저 확정하는 기준이다. 이 기준의 호스트 쪽 관측은 그 확정을 전제한다.
- **VM1 의 storage 부하가 VM2 의 지연을 실제로 밀어 올리는가**
다른 가상 머신의 스토리지 부하를 함께 보라는 항목을 이 환경에서 재는 물음이다.
- **Guest 의 fsync() 지연과 Host storage 지연은 같이 오르는가**
게스트 지표와 호스트 지표를 같은 시간축에 놓으라는 항목을 이 환경에서 재는 물음이다.
- **메모리 증상 하나로 계층을 단정하지 않는다**
같은 형태의 판독 기준이고, 그쪽은 메모리 증상 안에서 계층을 가른다.
## 목적
CPU 사용률 하나로 지연 원인을 자원에 귀속하면 스토리지 대기가 후보에서 빠진다. 개념 문서는 그 조합을 그대로 적었다. PostgreSQL 이 스토리지 완료를 기다리고 있으면 CPU 사용률이 높지 않을 수도 있어서, CPU 30% 인데 요청 지연 2초가 가능하다.
CPU 경쟁과 스토리지 경쟁은 경쟁하는 자원이 다르다. 개념 문서는 앞의 것을 호스트 논리 CPU 실행 시간 경쟁으로, 뒤의 것을 IOPS 와 대역폭과 큐와 장치 처리시간 경쟁으로 갈라 두었다. 두 자원을 한 지표로 대신 읽으면 어느 쪽이 밀렸는지 갈리지 않는다.
## 규칙
### 1. CPU 사용률이 낮다는 이유로 스토리지를 후보에서 빼지 않는다
CPU 사용률이 낮은 것은 CPU 가 놀고 있다는 뜻일 수도 있고 무언가를 기다리고 있다는 뜻일 수도 있다. 개념 문서가 그린 경로는 HTTP Request 에서 Keycloak, PostgreSQL, fsync(), Storage 로 이어진다. 이 경로에서 PostgreSQL 이 스토리지 완료를 기다리면 CPU 는 그 시간 동안 일하지 않으므로, CPU 지표만으로 지연 원인을 판단하지 않는다.
### 2. CPU 경쟁과 스토리지 경쟁을 다른 자원 경쟁으로 세어 적는다
호스트 논리 CPU 실행 시간이 모자란 것과 IOPS 나 대역폭이나 큐나 장치 처리시간이 모자란 것은 다른 사건이다. 개념 문서는 여러 가상 머신이 같은 물리 NVMe 를 쓰면 VM1 에서 대량 입출력이 발생했을 때 VM2 의 스토리지 지연이 커질 수 있다고 적었다. 이때 VM2 의 vCPU 는 부족하지 않을 수 있어서, 두 경쟁을 한 칸에 적으면 조치할 대상이 정해지지 않는다.
### 3. 여덟 지표를 같은 시간축에 함께 남긴다
개념 문서가 스토리지 문제를 분석할 때 CPU 사용률과 함께 보라고 적은 것은 여덟이다.
Guest I/O latency
Host I/O queue
Host storage latency
QEMU backend
cache mode
I/O Scheduler
NVMe
다른 VM 의 Storage load
앞의 셋은 시간에 따라 변하는 값이라 같은 시각에 함께 찍어야 짝이 맞다. 뒤의 다섯은 그때의 구성이라 한 번 적어 두면 그 측정 구간 전체에 붙는다. 이 여덟을 이 호스트에서 한 시간축에 모아 찍은 기록은 아직 없다.
### 4. 게스트 안에서 잰 값만으로 스토리지 성능을 결론내지 않는다
개념 문서의 Claim 6 은 스토리지 성능이 게스트 내부만으로 결정되지 않는다고 적었다. 영향을 주는 것으로 든 것은 QEMU 와 백엔드, 호스트 블록 큐, 입출력 스케줄러, NVMe, 캐시, 다른 가상 머신의 스토리지 부하다. 게스트 쪽 지표는 이 여섯이 모두 반영된 뒤의 값이므로, 게스트만 보면 값이 왜 그렇게 나왔는지는 알 수 없다.
### 5. 무엇을 볼지 정한 뒤에 명령을 고른다
명령 목록 자체는 규칙이 아니다. 무엇을 함께 볼지는 앞의 규칙들이 정하고 명령은 그 도구를 댈 뿐이라, 목록만 옮겨 적으면 무엇을 가르려고 그것을 보는지가 남지 않는다.
장치 입출력 관측은 iostat -xz 1 로 한다. 읽기와 쓰기의 처리량과 IOPS 와 요청 지연과 큐 상태와 device utilization 성격의 지표가 여기서 나오고, 어떤 프로세스가 입출력을 발생시키는지는 iotop 으로 본다. 개념 문서가 양쪽에 나눠 적은 명령은 이렇다.
Guest : lsblk · mount · df -h · cat /proc/mounts · iostat -xz 1
Host : virsh domblklist <VM_NAME> · qemu-img info 에 disk image 경로 · lsblk · /sys/block 아래 그 device 의 queue/scheduler · iostat -xz 1 · iotop
## 적용 조건
- 요청 지연이나 처리량 저하의 원인을 자원에 귀속하려는 판독 전부
- CPU 사용률이 낮은데 요청 지연이 큰 구간
- 데이터베이스가 요청 경로에 들어 있는 서비스
- 가상 머신 여러 대가 한 물리 장치를 함께 쓰는 환경
## 예외
- 이 기준은 어느 자원인지를 좁힐 뿐 원인을 확정하지 않는다. 스토리지 지표가 깨끗하게 나와도 CPU 쪽을 배제하려면 vCPU 경쟁과 steal time 을 따로 본다. 그것은 CPU 가상화 쪽 기준이 받는다.
- iostat -xz 1 이 보여 주는 device utilization 성격의 지표는 NVMe 처럼 병렬성이 큰 장치에서 포화도로 그대로 읽히지 않는다. 개념 문서가 NVMe 는 높은 병렬성과 큐 깊이를 지원한다고 적었다.
- 호스트에서 잰 값은 어느 가상 머신의 입출력인지 갈라 주지 않는다. 개념 문서는 Host Block Layer 가 그 입출력을 가상 머신 안의 프로세스가 시작했는지 호스트 프로세스가 시작했는지 본질적으로 구분해서 처리하는 계층이 아니라고 밝혔다. 가상 머신별로 가르려면 iotop 이나 게스트 쪽 관측을 같은 시각에 함께 찍는다.
- 이 저장소에는 이 기준으로 원인을 실제로 가른 측정이 없다. 여기 적은 것은 개념 문서가 서술한 판독 순서이고 이 호스트에서 확인된 값이 아니다.
## 예시
- CPU 30% · 요청 지연 2초 : 스토리지 대기가 후보에 남는 조합
- CPU Contention : 호스트 논리 CPU 실행 시간 경쟁
- Storage Contention : IOPS · 대역폭 · 큐 · 장치 처리시간 경쟁
- 같은 시각에 함께 찍는 값 : Guest I/O latency · Host I/O queue · Host storage latency
- 측정 구간에 한 번 적어 두는 구성 : QEMU backend · cache mode · I/O Scheduler · NVMe
- 이 호스트에서 잰 값 : x