Hacker News

Twelve years of distributed SQLite

분산 SQLite의 12년

rqlite 개발자가 2014년부터 이어진 분산 SQLite 프로젝트의 역사를 되짚으며 합의, WAL 스트리밍, 데이터 병합이라는 세 설계 방향을 구분합니다. 각 방식은 장애 복구와 일관성, 다중 쓰기 중 무엇을 해결하려는지에 따라 쓰임이 달라집니다.

에디터 노트

분산 SQLite의 세 갈래를 장애 뒤 복구, 중단 없는 복구, 다중 작성자 병합으로 나눈 설명은 각 기술을 고를 기준을 구체화합니다. 특히 Litestream과 rqlite가 다른 장애 상황을 겨냥한다는 구분은 두 도구를 단순한 대체재로 보지 않게 합니다. 다만 역사 서술은 rqlite 창립자의 회고입니다. Expensify와 ActorDB를 함께 적어 선행 사례를 인정하지만, 댓글의 dqlite 사용자는 '500 database locked' 오류를 겪었다고 말합니다. 이 한 사례가 dqlite 전반의 신뢰성을 판정하진 않으며, 본문에도 프로젝트별 성능 비교나 운영 기준은 없습니다. 따라서 설계 방향과 프로젝트 계보를 설명하는 자료로 읽는 것이 적절합니다.

AI 요약

분산 SQLite는 SQLite 앞에 복제 계층을 더해 여러 노드에서 데이터를 유지하는 방식입니다. rqlite 개발자는 2014년 프로젝트를 공개한 뒤 이 분야가 합의 기반 클러스터에서 WAL 스트리밍과 병합 방식으로 확장되고, 관리형 서비스로 이어진 과정을 정리합니다.

2014년, rqlite

저자는 2014년 9월 rqlite를 공개했습니다. 당시 회사에서 일하던 클러스터 시스템에 소규모 관계형 저장소가 필요했지만 어느 노드에 둘지 정하기 어려웠고, SQLite 앞에 Raft 로그를 두어 쓰기를 복제하는 방식으로 해결했습니다. 첫 버전은 InfluxDB와 etcd도 사용하던 goraft를 썼습니다. 2016년 초 HashiCorp Raft로 바꿨고, 현재도 이를 사용합니다.

rqlite의 설계 원칙은 CP 시스템입니다. 쓰기는 리더를 거쳐야 하며 과반수 노드가 승인해야 합니다. 네트워크가 분리된 소수 노드는 쓰기를 거부합니다. 저자는 HTTP API와 읽기 일관성 수준, 스냅샷 처리도 이 원칙에 맞춰 설계했다고 설명합니다. 다만 자신이 최초로 Raft와 SQLite를 결합한 오픈소스 시스템을 만들었다고 단정하지 않고, Expensify가 자체 인프라에서 Paxos 계열 프로토콜로 SQLite를 복제해 왔으며 2016년 Bedrock을 공개한 사실과 비슷한 시기 등장한 Erlang 기반 ActorDB를 함께 언급합니다.

2017년, dqlite

Canonical은 LXD와 이후 MicroK8s에 etcd를 별도로 실행하지 않고 임베디드 복제 저장소를 제공하려고 dqlite를 만들었습니다. 프로젝트는 Go로 시작한 뒤 자체 Raft 라이브러리를 사용하는 C 구현으로 바뀌었습니다. 저자는 rqlite와 dqlite의 목적은 비슷하지만 배포 방식이 다르다고 설명합니다. dqlite는 제품에 넣는 라이브러리이고 rqlite는 별도로 실행하는 서버입니다.

2021년, Litestream과 다른 복구 방식

Ben Johnson이 2021년 초 공개한 Litestream은 합의 프로토콜이나 클러스터를 사용하지 않습니다. SQLite의 WAL을 감시해 S3로 전송하므로 단일 노드 데이터베이스를 저렴하게 백업하고 복구할 수 있습니다. 저자는 많은 애플리케이션이 클러스터보다 단일 머신의 장애 복구를 원한다는 Johnson의 주장이 타당했다고 봅니다. 두 프로젝트가 답하는 질문은 다릅니다. Litestream은 머신이 고장 난 뒤 복구하면 되는 경우를, rqlite는 복구를 기다릴 수 없는 경우를 겨냥합니다.

Fly.io는 2022년 Johnson을 영입하고 Consul 임대(lease)를 이용해 파일시스템 수준에서 SQLite를 복제하는 LiteFS를 출시했습니다. 저자는 이를 복제 SQLite를 직접 배포하는 도구가 아니라 플랫폼 기능으로 제공하려는 첫 시도로 설명합니다. Litestream의 WAL 처리 방식은 rqlite 8.0에도 영향을 줬습니다.

2022년 이후, 병합과 관리형 플랫폼

cr-sqlite는 SQLite 확장 기능으로 CRDT를 추가했습니다. 리더 없이 여러 쓰기가 서로 다른 상태로 진행된 뒤 병합할 수 있어, 강한 일관성을 제공하는 rqlite와 달리 로컬 우선 애플리케이션에 맞는 AP 설계를 취합니다. libSQL은 SQLite 자체를 포크한 프로젝트입니다. Turso의 전신인 ChiselStrike는 SQLite 내부를 바꾸고 엣지 복제 서비스를 제공하려고 포크를 만들었습니다. 글은 Turso가 투자받은 뒤 2026년 Supabase에 인수됐다고 전합니다. SQLite Cloud는 Raft 기반 복제 SQLite를 클라우드 서비스로 제공하며, 저자는 설계상 rqlite와 가장 가까운 프로젝트로 꼽습니다.

Cloudflare는 2022년 엣지 네트워크에서 서버리스 SQLite를 제공하는 D1을 발표했고, 이후 Durable Objects에도 SQLite 저장소를 넣었습니다. 저자는 이 시기에 분산 SQLite가 직접 설치하는 도구에서 비용을 내고 사용하는 플랫폼 제품으로 옮겨갔다고 정리합니다.

저자가 정리한 세 가지 설계

저자는 12년 동안 합의, 스트리밍, 병합이라는 세 방향이 차례로 나타났다고 봅니다. rqlite와 dqlite는 리더와 강한 일관성을 갖춘 클러스터를 만들고, Litestream은 단일 쓰기 노드의 저비용 복구를 제공하며, cr-sqlite는 다중 작성자의 변경을 나중에 병합합니다. 각 방식은 서로 다른 문제에 답하므로 어느 방식이 더 나은지를 둘러싼 논쟁은 사용자가 해결하려는 문제가 다른 데서 생긴다고 설명합니다. 오픈소스 프로젝트가 먼저 나왔고, 투자와 인수는 복제를 서비스로 판매한 플랫폼에 집중됐다는 점도 덧붙입니다.

Hacker News 반응

  • @esafak — 시점이 딱 맞습니다. 작은 클러스터에서 dqlite를 쓰는데 더 견고한 것으로 옮기려 합니다. 이 상황에는 무엇을 권하시나요?
    • @oblio — 어떤 문제를 겪으셨나요?
    • @esafak — '500 database locked' 오류가 많이 납니다. https://github.com/canonical/dqlite/issues/908
  • @a3nz3g — 분산 SQLite 아이디어는 좋지만 벤치마크가 있나요? 어떤 사용 사례에서 장점이 있나요?
  • @chasil — 이걸 자세히 살펴본 적은 없는데, 대다수 클러스터 데이터베이스 아키텍처보다 훨씬 단순해 보입니다. https://rqlite.io/
    • @qaq — 제어 계층에 쓰고 있는데 지금까지는 꽤 만족합니다.
  • @feverzsj — SQLite의 hctree도 있습니다.
  • @tra3 — 최신 Rails가 SQLite를 프로덕션 옵션으로 권한다고 알고 있습니다. 동시 접근이 어떻게 되는지 이해가 안 됩니다. 알아볼 때가 됐네요.
    • @npn — WAL이나 wal2가 도움이 될 수 있습니다.
  • @brooksbp — 끝부분에서 저자가 누가 청사진을 그렸는지 역사가 확실히 기록하도록 애쓰는 대목 전까지는 재미있게 읽었습니다.

원문: Philip O'Toole / 번역·요약: Trawling