Removing fsync from our local storage engine
TL;DR Highlight
FractalBits가 fsync 없이 SSD 전용 KV 스토리지 엔진을 구현해 동일 조건 대비 약 65% 높은 쓰기 성능을 달성한 설계 방법을 공유했다. fsync의 메타데이터 오버헤드를 피하기 위해 사전 할당, O_DIRECT, SSD 원자 쓰기 단위 정렬 저널을 조합한 구조가 핵심이다.
Who Should Read
고성능 로컬 스토리지나 KV 엔진을 직접 구현 중인 시스템 개발자, 또는 기존 오브젝트 스토리지(MinIO 등)의 쓰기 지연 문제를 파악하고 싶은 인프라 엔지니어.
Core Mechanics
- fsync는 파일 데이터뿐 아니라 inode, 디렉터리 엔트리, extent map, 파일시스템 저널 커밋까지 전부 플러시한다. 실제로 수 KB짜리 write 하나가 내부적으로 수십 배 규모의 I/O를 유발할 수 있다.
- fsync 호출 한 번의 지연시간은 SSD 기준으로 수백 마이크로초에서 수 밀리초에 이른다. 게다가 동시 I/O, 파일시스템 저널 상태, SSD의 GC(가비지 컬렉션) 활동에 따라 tail latency가 중앙값 대비 몇 배씩 튀는 게 문제다.
- 주요 스토리지 시스템들의 fsync 전략을 비교해보면: MinIO는 데이터와 메타데이터 모두 fdatasync/fsync, etcd는 Raft 안전성을 위해 모든 엔트리에 fsync, Postgres는 WAL 커밋 시 fsync + group commit으로 지연 분산, Kafka는 기본적으로 fsync를 아예 안 쓰고 복제(replication)에만 의존한다.
- 이 엔진의 핵심 전제조건은 세 가지다: SSD 전용 배포, 수백 바이트~수백 KB 범위의 값 크기, 단일 키 단위의 원자적 write 의미론(쓰기가 완전히 보이거나 완전히 안 보이거나). 이 조건 중 하나라도 벗어나면 설계를 처음부터 다시 해야 한다.
- 엔진은 index, journal, data area 세 컴포넌트로 구성된다. index는 키→값 위치 매핑이며 주로 메모리에 상주하고, journal은 index와 data area 할당 상태 변경을 기록하는 crash-consistency 경계이며, data area는 실제 값을 저장한다.
- fsync 없이 crash-consistency를 유지하는 핵심 기법은 고정 크기 사전 할당(pre-allocated) 파일 + 사전 제로화(pre-zeroed extents) 조합이다. 런타임에 새 파일을 생성하거나 파일 크기를 변경하지 않아서 inode/디렉터리 엔트리 변경이 발생하지 않는다.
- O_DIRECT 쓰기를 SSD의 원자적 쓰기 단위(atomic-write unit)에 맞게 정렬해서 저널 커밋을 수행한다. 이렇게 하면 저널 블록 하나가 '완전히 기록되거나 전혀 기록되지 않는' 원자성이 보장돼 fsync 없이도 복구 일관성을 확보할 수 있다.
- AWS i8g.2xlarge 로컬 NVMe 환경에서 4KB 랜덤 쓰기 벤치마크 결과, 이 엔진은 190,985 obj/s를 기록했고 ext4 + O_DIRECT + fsync 조합은 116,041 obj/s였다. 약 65% 성능 향상이다.
Evidence
- O_DIRECT만으로는 충분하지 않다는 회의적인 의견이 많았다. O_DIRECT는 OS 페이지 캐시를 우회할 뿐이고, 드라이버 메모리나 드라이브 내부의 비내구성 캐시에 데이터가 남아있을 수 있어서 '커밋 성공'을 반환할 수 없다는 지적이다. 실질적인 durability 보장을 위해서는 ATA/NVMe FUA(Force Unit Access) 명령이 전송되어야 한다는 의견이 제기됐다.
- WAL 블록 순서 보장 문제도 지적됐다. fsync 없이는 이전 WAL 블록이 현재 블록보다 먼저 디스크에 쓰였다는 보장이 없고, SSD는 내부적으로 쓰기를 재정렬할 수 있어서 전원 손실 시 로그에 '구멍(hole)'이 생겨 잘못된 복구가 일어날 수 있다는 우려가 나왔다.
- O_DSYNC를 O_DIRECT와 함께 쓰면 더 정확하다는 대안 제시도 있었다. O_DSYNC는 필요한 경우 디스크 쓰기에 FUA를 추가해서 내구성을 확보하므로, 이 엔진의 설계에 추가하면 durability 보장이 명확해진다는 의견이었다.
- 유사한 S3 호환 단일 노드 스토리지(hs5)를 만든 개발자가 댓글을 달았는데, 자신은 데이터와 메타데이터 durability를 위해 제대로 fsync를 사용하지만 옵션으로 끌 수 있게 해뒀다고 했다. 그는 WAL에 체크섬과 시퀀스 번호를 써서 잘못된 데이터 커밋을 방지하고 있으며, WAL만 fsync를 비활성화하는 모드를 추가하는 건 좋은 생각이 아닐 것 같다고 했다.
- 글쓴이(Author)가 직접 댓글에서 'fsync 전체 부정이 아니다'라고 명확히 선을 그었다. 이 설계는 SSD 전용 배포, 사전 할당 파일, O_DIRECT, 단일 키 원자성, 디바이스 쓰기 보장이라는 전제조건이 모두 충족될 때만 성립하며, 그 외 환경에는 적용하면 안 된다고 밝혔다.
How to Apply
- SSD 전용 단일 노드 KV 스토리지를 직접 구현하는 경우, 고정 크기 파일을 미리 할당(fallocate)하고 내용을 제로화해두면 런타임에 inode나 extent map 변경이 발생하지 않아 fsync의 메타데이터 오버헤드를 없앨 수 있다.
- O_DIRECT 쓰기를 사용할 때 SSD의 atomic-write unit 크기(보통 4KB 또는 512B)에 맞춰 저널 커밋 블록을 정렬하면, FUA나 fsync 없이도 단일 블록 단위의 원자적 쓰기를 활용해 crash-consistency를 확보할 수 있다.
- 기존 코드에서 MinIO나 RocksDB 기반으로 쓰기 지연이 크다면, 각 시스템의 fsync 동작(MinIO의 fdatasync, RocksDB WAL의 sync_log_entry_cache 설정 등)을 먼저 프로파일링해서 병목이 메타데이터 동기화인지 확인한 후 설계 변경 여부를 판단하는 게 좋다.
- O_DIRECT만으로 durability를 보장했다고 착각하지 않도록, 실제 운영 환경에서는 O_DSYNC를 함께 사용하거나 NVMe FUA 명령이 실제로 발행되는지 확인하는 테스트를 포함시켜야 한다. 그렇지 않으면 드라이브 내부 캐시에서 전원이 끊길 경우 데이터 유실이 발생한다.
Terminology
Related Papers
Claude Code sends 33k tokens before reading the prompt; OpenCode sends 7k
동일한 모델과 작업 환경에서 Claude Code와 OpenCode의 실제 토큰 사용량을 API 레벨에서 측정한 결과, Claude Code가 시스템 프롬프트 오버헤드만으로 OpenCode 대비 4.7배 더 많은 토큰을 소비한다는 것을 확인했다.
Mesh LLM: distributed AI computing on iroh
사무실, 집, 클라우드에 흩어진 GPU들을 하나의 OpenAI 호환 API로 묶어주는 분산 LLM 실행 시스템으로, 비싼 API 비용 없이 큰 모델을 직접 운영할 수 있다.
Show HN: Frugon – Find which LLM calls a cheaper model could handle (local, MIT)
내 LLM API 비용이 어디서 새는지 로컬에서 분석해주는 오픈소스 CLI 도구로, 비싼 모델 대신 저렴한 모델로 전환 가능한 호출을 골라낸다.
Jamesob's guide to running SOTA LLMs locally
2천 달러짜리 RTX 3090 한 장부터 4만 달러짜리 RTX PRO 6000 4장 셋업까지, 로컬에서 최신 LLM을 직접 돌리는 방법을 하드웨어 선택·구성·실행 설정까지 통째로 정리한 실전 가이드다.
Faster embeddings: how we rebuilt the ONNX path in Manticore
Manticore Search가 기존 SentenceTransformers/Candle 백엔드를 ONNX Runtime으로 교체해 텍스트 임베딩 생성 속도를 평균 14배 향상시켰다. 별도 모델 서비스 없이 DB 내부에서 직접 임베딩을 처리하는 구조에서 INSERT 속도가 곧 임베딩 속도이기 때문에 이 개선은 실질적인 ingest 처리량 향상으로 직결된다.
Asymmetric Quantization: Near-Lossless Retrieval with 97% Storage Reduction
멀티벡터 검색 모델의 문서 벡터를 1비트 이진값으로 압축하고 쿼리 벡터만 int8로 유지하는 비대칭 양자화 기법으로, 스토리지를 97% 줄이면서 검색 품질 손실을 0.61점(NDCG@10 기준)에 그치게 만든 실제 프로덕션 적용 사례다.