From 87480ce170895f841c40930ce24a7a026646ae14 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Sun, 27 Sep 2026 14:11:19 +0100 Subject: Measure what moving saves off the owner would buy (084) Nothing a thread can give: with writes saturated the device's one line of syncs is the bottleneck, so zeroing the tail or compacting on another thread only queues that device work behind the commits, and the owner's idle gap is shorter than one journal commit. Built without compaction the store is no faster; without compaction and without tail growth durable posts gain 1.4% and the p99 drops 24% (17.4 to 13.3 ms). New blocks are the tail latency, so the way to it is a store that rewrites its space in place, a ring cleaned forward instead of compacted into new files. --- docs/research/084-parallel-syncs.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'docs/research') diff --git a/docs/research/084-parallel-syncs.md b/docs/research/084-parallel-syncs.md index 43c24df..3f55e85 100644 --- a/docs/research/084-parallel-syncs.md +++ b/docs/research/084-parallel-syncs.md @@ -1,6 +1,7 @@ -# 084 — 소유자를 키로 나누면: 이 장치는 동기화를 한 줄로 세운다 +# 084 — 소유자를 키로 나누면, 저장을 다른 스레드로 넘기면: 이 장치는 동기화를 한 줄로 세운다 -2026-09-27. [로드맵](../roadmap.md) 중기 2 "키 해시 기반 단일 소유자 파티셔닝(쓰기 병목 선형 확장)"을 할지 정한 것. +2026-09-27. [로드맵](../roadmap.md) 중기 2 "키 해시 기반 단일 소유자 파티셔닝(쓰기 병목 선형 확장)"과 단기 2 "저장과 +적용의 겹치기(디스크 쓰기를 전용 I/O 스레드로)"를 할지 정한 것. 둘 다 같은 사실에 걸린다. 착수 기준: @@ -45,3 +46,30 @@ Raspberry Pi 5, SD 카드의 ext4, 4 KiB 커밋, 3초씩, 순서를 돌려 가 - 멀티코어는 읽기에 쓴다. 연결 스레드가 스냅숏으로 보기를 답한다(`--threads auto`, [080](080-snapshot-reads.md)). - 이 장치에서 쓰기를 더 늘리는 길은 동기화의 비용 자체다. 커밋 경로에서 꼬리 늘리기와 압축을 빼면 처리량은 5–8% 늘고 p99는 반이 된다([081](081-tail-records.md) 다음 결정). + +## 저장을 다른 스레드로(단기 2) + +쓰기가 포화일 때 병목은 기기의 동기화 한 줄이다. 커밋 말고 기기가 하는 일, 곧 꼬리에 0을 써 두고 새 크기를 저널에 +커밋하는 일과 압축(살아 있는 노드를 새 파일에 쓰고 동기화, 이름 바꾸기, 디렉터리 동기화)을 다른 스레드로 넘겨도 그 일의 +기기 시간은 사라지지 않는다. 커밋의 동기화와 같은 줄에 서서 그 커밋을 늦출 뿐이다. 소유자가 기다리는 틈(라운드의 25%, +약 1.1 ms, [081](081-tail-records.md))도 저널 커밋 한 번보다 짧다. 적용을 동기화와 겹쳐 가릴 수 있는 몫은 4%다(081). + +그래서 스레드를 늘리는 대신, 그 일을 없앴을 때의 몫을 쟀다. 저장소를 셋으로 빌드해 번갈아 잰 것이다. 그대로, 압축을 뺀 것, +압축을 빼고 꼬리를 만들 때 64 MiB를 써 두어 측정 중에는 늘리지 않는 것이다([variants.py](../../research/experiments/013-parallel-syncs/variants.py), +[원시 결과](../../research/experiments/013-parallel-syncs/2026-09-27-store-variants-ext4-linux-aarch64.jsonl)). 점수판 내구성 POST +64연결, 4초씩 여섯 라운드의 중앙값이다. + +| 저장소 | posts/s | p99 | +|---|---:|---:| +| 그대로 | 22,230 | 17.4 ms | +| 압축 없음 | 21,528 | 18.4 ms | +| 압축 없음, 꼬리 늘리기 없음 | 22,544 | 13.3 ms | + +압축만 빼서는 달라지지 않는다. 꼬리 늘리기까지 빼면 처리량은 +1.4%(앞선 탐색에서는 +5.5%)이고 p99가 24% 준다. 꼬리 +지연을 만드는 것은 새 블록이다. 256 KiB마다 0을 쓰고, 그 크기와 블록을 저널에 커밋하는 동기화다. 0을 크게 한꺼번에 +쓰면 드물어지는 대신 한 번이 길어진다. 압축은 새 파일을 만들 때마다 꼬리를 새로 써야 해서 둘은 따로 떼어 볼 수 없다. + +결정: 저장을 넘길 스레드는 만들지 않는다. 남은 몫(p99 −24%, 처리량 몇 %)을 얻는 길은 공간을 제자리에서 다시 쓰는 +저장소다. 파일을 한 번 0으로 채워 두고 커밋을 고리처럼 돌려 쓰며, 살아 있는 노드를 앞으로 옮기는 청소가 압축을 대신한다. +그러면 커밋은 늘 이미 있는 블록을 덮어쓰고(가장 싼 동기화), 새 파일과 이름 바꾸기도 없다. 저장소 형식을 바꾸는 일이라 +따로 설계한다. -- cgit v1.2.3