В сентябре 2014 года была опубликована заметка о запуске rqlite. Идея была проста: взять SQLite, поставить лог Raft спереди и реплицировать каждую запись в кластер так, чтобы потеря узла не означала потерю данных. Исходный код появился на GitHub в выходной день. По всей видимости, это была первая open-source система, объединившая Raft и SQLite. Никто больше этого не делал, и на протяжении нескольких лет никто не пытался.
Сегодня «распределённый SQLite» — это категория с дюжиной проектов, несколько из них получили венчурное финансирование, двое из них были приобретены. Поскольку люди, пишущие о этой категории, обычно начинают историю с 2021 года, стоит рассказать версию, которая начинается в 2014. Я был там все эти годы.
2014: rqlite
Потребность была конкретной. Кластеризованной системе, над которой велась работа в jut.io, требовалось небольшое хранилище реляционных данных, и вопрос о том, какой узел его держать, не имел хорошего ответа. Репликация SQLite с консенсус-протоколом решала эту проблему. На работе пошли другим путём, но разработка rqlite продолжилась — задача была общей, а решение компактным. Первая версия использовала goraft, ту же библиотеку, что применяли InfluxDB и etcd в то время (вскоре после этого я присоединился к InfluxDB как основной разработчик). В начале 2016 года она была заменена на реализацию Raft от Hashicorp, которую rqlite использует и по сей день.
Наиболее значимое решение по дизайну было принято тогда и не менялось. rqlite — это система CP. Записи идут через лидера, большинство должно подтвердить, и разделённое меньшинство отказывает в записях. Всё остальное — HTTP API, уровни консистентности чтения, снимки состояния — следовало из этого.
До 2014 года и параллельно
Две вещи стоит упомянуть ради честности. Expensify репликировала SQLite внутри собственной инфраструктуры годами, используя протокол в стиле Paxos; они выпустили это как Bedrock в 2016 году. ActorDB, система на Erlang, которая давала каждому «актору» собственную базу SQLite, реплицируемую Raft, появилась примерно в то же время, что и rqlite. Ни один из них не получил широкого распространения вне своих организаций, но оба показывают, что идея была в воздухе. rqlite сделал её standalone, general-purpose, open-source — вещь, которую мог запустить кто угодно.
2017: dqlite
Canonical построила dqlite, чтобы дать LXD и позже MicroK8s встроенное реплицируемое хранилище без запуска etcd. Марк Шаттлворт даже позвонил и обсудил, можно ли адаптировать rqlite, но это никогда полностью не подошло. dqlite начался на Go и был переписан на C с собственной библиотекой Raft. Это проект, наиболее похожий на rqlite по целям, главное отличие — в упаковке: dqlite — это библиотека, которую встраивают, rqlite — это сервер, который запускают. Потребность Canonical была в базе внутри их продуктов, а моя — в базе рядом с продуктом любого.
2021: Litestream и смена подхода
Бен Джонсон (с которым работал в InfluxDB) выпустил Litestream в начале 2021 года. Litestream вообще не использует консенсус. Он наблюдает за SQLite WAL и транслирует его в S3, давая аварийное восстановление для однопользовательской базы SQLite почти без затрат. Аргумент был в том, что большинству приложений не нужен кластер — они используют одну машину и нуждаются в способе восстановления, если она отказывает. Это было верно для многих приложений, и движение «SQLite достаточно» следующих лет с посты и доклады на конференциях многое ему обязано.
Litestream и rqlite отвечают на разные вопросы. Litestream: что если машина отказывает? rqlite: что если машина отказывает и я не могу ждать восстановления? Первый вопрос более распространён, второй — тот, ради которого люди приходят к rqlite.
Fly.io нанял Бена в 2022 году и выпустил LiteFS, который реплицирует SQLite на уровне файловой системы с арендами от Consul. Это была первая попытка сделать реплицируемый SQLite функцией платформы вместо того, чтобы развёртывать его. И в финальном повороте Litestream вдохновил подход rqlite версии 8.0 к обработке SQLite WAL.
2022: форки и расширения
Два проекта в 2022 году взяли подходы, которые ни rqlite, ни Litestream не применили. cr-sqlite добавил CRDT в SQLite как расширение, позволяя нескольким писателям расходиться и сливаться без лидера. Это угол AP пространства дизайна, подходящий для local-first приложений, где гарантии CP из rqlite были бы помехой.
libSQL форкнул сам SQLite. ChiselStrike, позже Turso, хотел менять вещи внутри движка, которые проект SQLite, не принимающий внешние взносы, не менял бы. На базе форка они построили облачный сервис с репликами на краю сети. Turso привлекла венчурные деньги и в 2026 году Supabase приобрела их.
Примерно в то же время появился SQLite Cloud, предлагающий хостированный SQLite, реплицируемый с Raft. Это проект, ближайший к оригинальному дизайну rqlite, завёрнутый в облачный сервис.
2022 и далее: платформы
Cloudflare объявила D1 в 2022 году — SQLite как бессерверную базу на краю их сети, позже поместив хранилище SQLite внутри Durable Objects. Это реплицируемый SQLite как управляемый продукт от компании, которой не нужно объяснять, как он работает. Сервис Turso имеет ту же форму. Категория перешла от «вещи, которую вы запускаете» к «вещи, которую вы покупаете».
Что показывают эти двенадцать лет
Три вещи, по моему мнению.
Ядро было правильным. SQLite как движок хранилища с добавленной снаружи репликацией был переизобретён по крайней мере восемью командами с разными потребностями и протоколами. Никто не нашёл причины перестать это делать.
Пространство дизайна имеет три угла, и они появились в порядке. Консенсус сначала (rqlite, dqlite): один лидер, сильная консистентность, кластер. Потоковая трансляция во-вторых (Litestream): один писатель, дешёвое восстановление, без кластера. Слияние в-третьих (cr-sqlite и части local-first движения): много писателей, итоговая консистентность. Каждый правильный для своего вопроса, и большинство споров — это споры между пользователями о том, какой вопрос задаётся.
А деньги пошли платформам. rqlite, dqlite и Litestream — open source и бесплатны. Проекты, привлёкшие капитал или приобретённые, — это те, что превратили реплицируемый SQLite в сервис с счётом. Это обычная судьба инфраструктурных идей, и я не против. Но стоит записать, что идея была open source восемь лет, прежде чем кто-то начал её продавать.
rqlite ещё здесь. Он делает то же самое, что делал в 2014 году, только намного лучше, и это всё ещё то, к чему обращаются, когда хотят отказоустойчивую реляционную базу, которую можно запустить самостоятельно, полностью понять и не платить никому. Двенадцать лет спустя я доволен своим местом в этой истории.