I/O ìë ëë (Bottleneck) íìë
íì ìììí (3ì ìì)
- ëì: I/O ìë ëëìë ììíì ìì ìëë(Throughput)ì ëìí, ëíìí, íìììí ë I/O subsystemì ìë ëëì ìíëë íììë, CPUë ëëëëë I/O ëêê ìì ìì ìêì ëëëì ììíë êìê ëì ííë.
- êì: I/O ëëì ìíí íìíë, SSD ëì, RAID êì ëê, ëëê I/O ìì, ìì ìë ìë ë ìë íìê êì íêììì íëí ì ìë.
- ìí: I/O ëë ëìì íìììí(Ext4, XFS, ZFS), ëë ëìì, SCSI/NVMe ëëìë, ëíìí ìí ë ìë êìì êì ììëë, ê êìë ëê(iostat, perf, bpftrace ë)ëììí íí ëìì íìíë.
1. êì ë íìì
êë ë ìì
I/O ìë ëëì ììíì ëìíëíëCPUìëëëìììë. ììíì ìì ìë ìêìì I/O ëêê ììíë ëìì ëììë I/O ëëì ìêíëë ëìë.
I/O ëëì ìì ììì ëìê êë:
- ëìí ììì ìë ìë íê: HDDì ëëì ìí ìê(íì ìê + íì ìì)
- RAID ìíëë ìì: RAID5/6ì íëí êìì ëë ìê ëë
- íìììí ëíëìíìì:ìíëí
- ëë ëìì í êì íê: ëìì ìë êëí I/O ìì ì ìí
- ëíìí ëìí íí: ëìë ëìí ìì ì ëíìí ëìí êê
ì I/O ëë ëìì ììíê
CPUìëê ìëë ëìë, ëìíëìëììíêì ëìíëìì ìë, íì ìë, êì ëì, ë ëëëìI/Oì ëêíëë, I/O ëëì íêíë ììíì íìë ìëììëì êëí ì ìë.
[ììí ìì ìë ìê ëì]
[CPU ëìë íëêëì êì]
ìì ìê = 100%
|| CPU ìë (100%)
| |
[CPU + I/O íí íëêëì êì]
ìì ìê = 100%
|| CPU ìë (30%)
|| I/O ëê (70%)
| ìêì I/O ëë!
[I/O ëë íê í]
ìì ìê = 43%
|| CPU ìë (30%) <- ììê ëì
|| I/O ëê (13%) <- 70%ìì 13%ë êì!
| I/O ììíë ìì ìêì 57% ëìë!
[ëììêë íì] I/O ëë íêì"ëëìíêì"ì ëìí ì ìë.ëìí ììëCPU(ìê)ì ìëë ëëëI/O(ëë)ê ëëìëìììë
- ìì ëì: I/O ëëì "êì ëë ëì"ì êë. ìììì ììì ëëêê ìëë ëëë( CPU ), ëë ìëì ìêë(ëìí ìëë) ëë êì ëíë(ëíìí ëìí) íìëì ìëì ììë ëì ëíë.
2. ìííì ë íì ìë
I/O ìí êìì ê êìë ëë íìí
[]
> [File System Layer] <- ëíëìí ìì, ìê, ëí ìì
> [Block Layer] <- I/O ìììë, í êë
> [SCSI/NVMe Layer] <- ëìí ìíëë, í êì
> [Physical Disk] <- ìì ëìí read/write
ê êìë ëë íìí:
[File System êì]
- ëíëìí ìê/ìê ìì ìì (íííì)
- íìììí ëí ìì ëì ->ëìì
- ìê êí (fs-wide inode mutex ë)
[Block Layer]
- I/O ìììë ìí (noop, cfq, deadline, mq-deadline)
- í êì (queue depth) ìí
- ëë (unbalanced I/O ëì)
[ëìí ìíëë]
- RAID íëí êì (RAID5/6 ìê)
- ìíëë ìì Hit/Miss
- SSDì êì FTL(Flash Translation Layer) ìëíë
[ëë ëìí]
- HDD: íì ìê (seek time) + íì ìì (rotational latency)
- SSD: NAND íëì I/O ìê ( erase + program)
I/O ëë ìë ëê êì
| ëê | ëì êì | íì ìí |
|---|---|---|
| iostat | ëë ëìì + ëìí | tps, KB_read/s, KB_wrtn/s, await, %util |
| iotop | íëììë | ëìí I/O ììëë íëìì ìë |
| pidstat | íëììë | PIDë I/O íê |
| blktrace | ëë ëìì | êë I/O ììì latency ëí |
| bpftrace | ëë êì | ìë íì ììì ìì ìì |
| perf | CPU + I/O | CPI, I/O êë íëìì ìëí |
iostat ìì ìí íë
Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn await %util
sda 154.32 1234.56 567.89 123456 56789 12.34 45.67
[ìí ìë]
tps (Transactions Per Second): ìë ìëëë I/O ìì ì
kB_read/s: ìë ìì íëëìí
kB_wrtn/s: ìë ì íëëìí
await: I/O ìììì ëìíì ëëê ìëêììíê ëê ìê (ëëì)
%util: ëìí ììë (100%ë ëìí íí!)
ëë íë êì:
- %util > 80%: ëìí íí -> ìê I/O ììì ëêíì í
- await > 100ms: ëì ëë ëìí ìë -> HDDì êì typical, SSDëë ëì ìì
- avgqu-sz (ëê í íê) > 4: ëì I/Oê íìì ëê ì -> ëë íì
[ëë íë íë]
%utilì 80% ìììê?
ì: ëìíê ëëìë
ìê ëìì ëëë -> ìê ììí (ìì, ëë ahead)
ìê ëìì ëëë -> ìê ììí (ëì ìê, SSD ëì)
ìëì: CPUë ëíìí ìì íì
CPU %iowaitê ëìê?
ì: I/O ëêë CPUê ëê ìí -> I/O ëëìë
CPU ììê ëìê?
ì: CPU ëëìë
[ëììêë íì] iostatì %utilì"êìëë ííë"ê êë. 80% ìíìë ìëì ìííê íëìë, 80% ììì ëë ìë ìì êêì ìììê ìëê ëëìë. 100%ì ìëë êìëëê ìì ííëì ìë ìë ìììì ëíë.
SSD vs HDD ëë íì ëê
| ìí | HDD | SSD (SATA) | SSD (NVMe) |
|---|---|---|---|
| ìì ìê ìë | 100~200 MB/s | 500~550 MB/s | 3,000~7,000 MB/s |
| ìì ìê ìë | 100~200 MB/s | 400~500 MB/s | 2,000~6,000 MB/s |
| ìê ìììê | 5~10 ms | 0.05~0.1 ms | 0.01~0.05 ms |
| ìê ìììê | 5~10 ms | 0.05~0.1 ms | 0.01~0.05 ms |
| ëë | íì ìê + íì | SATA ëìí + ìíëë | í êì (Queue Depth) |
| ëë íêì | SSDë êì | NVMeë êì | í êì ììí |
- ìì ëì: I/O ëë ìëì "ëë ììì"ì êë. êêì"ììì ì ììì"ëê íë, restoranìì ëìëì(ììí ì), ëëììììì(I/O ìë), ëëìì ëíëì(ëíìí/ëìí ëë) ê êêì ììíì"ìëì ëìê ëìíëì"ë íìíì íë.
3. ìí ëê ë ëêë ëì
I/O ëë vs CPU ëë: ìíí ìëì ììì
| ìì | ìì ìì | ìì ìì | êê |
|---|---|---|---|
| CPU %iowait ëì | I/O ëë | ììëë CPUê I/O ëêê ìë ëë ëê ìí | ìëë ììí |
| ìëë ëì | ëìí ëë | ëíìí ëìí íí | ëìí êì |
| ìë ìì | CPU ëì | I/O ëê í íì | CPU ì |
[ìíí ëë ìë êì]
ëê 1: ììí ìì íì
uptime (ëí íê)
vmstat 1 (CPU, I/O, ëëë ìí)
iostat -x 1 (ëìí ììë, ìë ìê)
ëê 2: CPU vs I/O ëë êë
vmstatìì CPUë ììë ëì
us (user) + sy (system) ëì -> CPU ëì
wa (wait I/O) ëì -> I/O ëê
iostatìì ëìí ììë ëì
%util 80% ìì -> ëìí íí
%util 80% ëë -> ëë êì ëì
ëê 3: ìì ìì íì
iotop: ìë íëììê I/Oë êì ëì ëììíëì
blktrace: I/O ììë latency ëí
bpftrace: ìë ëë I/O ìë íì ìì
[ëììêë íì] I/O ëë ìëì"ìë ìí ìë"ê êë. íìêì(CPU íê), X-ray(ëìí íê), ììë(ëíìí íê) ë ìë êìë íì ìíììë íëíì"ìì ìì"ì ì ì ìë. í êì êìëìë íëíë ìëë ìëë íê ë ì ìë.
íìììíë I/O íì
| íìììí | êì | ìì | ìíí ìì |
|---|---|---|---|
| Ext4 | ëì ííì, ìëë | ìë | ëì ìë, êêì |
| XFS | í íì, ëë ìë | ëíëìí ìì ìëíë | ëìíëìì, HPC |
| ZFS | ëìí ëêì, ìëì | ëëë ìë í | ëì, íì ìë |
| Btrfs | ìì, ìëìê | ìì maturity ëì | êë íê |
- ìì ëì: íìììí ìíì"ëìì ëë êê ìí"ê êë. ëêìëìXFSìSDAìêê ëë ëêë ìë êìë,ì ëê íìììíì ìííì íë.
4. ìë ìì ë êììì íë
ìë ìëëì: ëìíëìì ìë ìë ìí íê
ìí:ë ìëì ìíëì ìí êì ìëê ìì ëëìê ììë.ìí ëìíê ëìììë ìëìììëìííìë.
ìë êì:
iostat -x 1ìí -> ëìí %utilê 95%ë ííiotop-> mysql/mariadb íëììêì ëëëìblktraceë ìì ëì -> ìì íêê ëëë 4KB~16KB ( ëìí ìê)perf stat -a -e block:block_rq_issueë ëì -> ëì ìì 4KB ìê ìì ëì
ìì:ìí ìëê ìë êì ììì ëì ììëìê êìëë ëììíì.
ëìì:
- ëëíìëëëí ëëëì (Buffer Pool íë)
- ìí ìëìë í íìë íìì sequential readë ëê
- InnoDB ìììì
innodb_flush_method = O_DIRECTììíì OS ìì ìí
êê: ëìí %utilê 95%ìì 30%ë êì, ìë ìëê íê 80% íì
ëì ìíëìí
- ëìí íí ìë íì: iostatìì %utilê 80%ë ëìë ëìíê ëëìë.
- ìê vs ìê ëì ëì: ìê ëìì ëìë ìì ìì, ìê ëìì ëìë ìê ììí
- íëììë I/O ëì: iotopìë ìë íëììê êì ëì I/Oë ëìíëì íì
- ìì íì ëëìì: ëì ìì ìì íììíë ìëíëê íëë, íëë íìêë ìíëì íì
ìííí
-
"%utilì ëìë I/O ëëì ìëë" íë: %utilì ëìë await(ìë ìê)ê ëìë ëìí ììì ìë ìë ëìê ìì ì ìë.
-
SSD ëìëìë ëë ëë íê: SSDë ëëìë,ìì ëìíë I/O ìììììì ììë ììí ëëì ë ì ìë.
-
ììëìë íêíë í: ìì ííìì ëìë(= ìì íëëì ëëë íêëì ììë) ìíëììììë ëìí ëì ìë ììë ëììêíì íë.
-
ìì ëì: I/O ëë íêì "ëì êí íì íê"ê êë. Royceíë(SSD êì)ëìëìê ëë(ìì ì ìê) ë ëíë. ììì(ìì), ìë ííì ììê(ìì ììí), ëëìëë íìììë ëëë êììë.
5. êëíê ë êë
ìë/ìì êëíê
| êë | I/O ëë ëíê | I/O ëë íê í |
|---|---|---|
| íê ìë ìê | 500ms | 50ms |
| ìëë (QPS) | 100 req/s | 1,000 req/s |
| CPU íì | I/O ëêë ëë | CPUê ìì ììì íì |
| íëìì íìë | ëìí íí, CPU ìì | êí ìí íì |
ëë ìë
NVMe-oF(ëíìíë íí NVMe), ìííììë ìíëì(ìíëììì ìì ìì), êëê AI êë I/O íí ìì ëì ëë I/O ëë íêì ìëì ëíì ë êìë.
ìê íì
-
Linux iostat documentation: https://man7.org/linux/man-pages/man1/iostat.1.html
-
blktrace documentation: https://wiki.btrfs.org/wiki/ blktrace
-
NIST SP 800-88: ìíëì ìíí êìëëì
-
ìì ëì: I/O ëë íêì "ëë ìê íìí"ì êë. íëìëëê(íëìì ì)ìê ëë íëë ëíê(ìííìì ììí)ëë êë ììíìíë(ìì, ìì) ìì ëë ìëê ëìììë íìëë.
êë êë ë
| êë ëì | êê ë ìëì ìë |
|---|---|
| ëìí ìììë | I/O ììì ëìíì ëëê ì ìì ìëíë ìêëììë, ìêëì ìíì ëë ëë íì ëë ìíêëíë. |
| RAID | ìë ëìíë íëì ëëì ëëìë êìíë êìë, ìê ìëì íëí êì ìëíëê ëìí ì ìë. |
| NVMe | PCIe ëìì ìì ìêëë êì SSD ìííììë, SATA SSDëëì ìì ìêì ìêíë. |
| FUSE | ììì êêìì íìììíìêíí ì ìëìë, ìë ìì ìì ììí ìíëìëí ì ìë. |
ìëìë ìí 3ì ëì ìë
- I/O ëëì "íê êì ëë ëì"ì êë.ìê ììì ëë ëëìë( CPU ), ëë ìê 1ëëìë(ëìí ìëë) ìì êìì ê ìì ìëìëë.
- êëë ëë ìê 10ëë ëìëë( SSD êì), ê ìê ëë ììê 100êëë(ìì íìë) ììí ëë ìêì ìë êëë.
- êëì êì ëëì "ìëë ììì í êëì ëì í ëì ëëíê(íì íìê), ê íêëë ëëë ëë(ìì)"ì êìíë, ì ëìë ëëë êëë íì íìììë êìë ì ìë!