rqlite, dqlite y Litestream: SQLite distribuido

rqlite, dqlite y Litestream: SQLite distribuido

@programacion

Lo esencial

  • Philip O'Toole creó rqlite en 2014: el primer sistema open source que combinó Raft y SQLite.
  • Canonical lanzó dqlite en 2017 para LXD y MicroK8s, embebido en C con su propia librería Raft.
  • Litestream (2021) no usa consenso: transmite el WAL de SQLite a S3 para recuperación ante desastres.
  • Turso, antes ChiselStrike, forkeó SQLite como libSQL y Supabase lo adquirió en 2026.
  • cr-sqlite agrega CRDTs a SQLite para que varios escritores diverjan y luego fusionen sin líder.

En septiembre de 2014, Philip O'Toole publicó un post corto anunciando rqlite: tomar SQLite, poner un log de Raft delante y replicar cada escritura en un clúster. Ese fin de semana subió el código a GitHub. Doce años después, SQLite distribuido es una categoría con una docena de proyectos, dos adquisiciones y al menos ocho equipos que reinventaron la misma idea con protocolos distintos.

2014: el problema que no tenía buena respuesta

O'Toole trabajaba en jut.io, un sistema en clúster que necesitaba una porción pequeña de almacenamiento relacional. La pregunta de qué nodo debía guardar esos datos no tenía una respuesta limpia. Replicar SQLite con un protocolo de consenso resolvía el problema sin meter una base de datos completa en la arquitectura.

La primera versión de rqlite usó goraft, la misma librería que empleaban InfluxDB y etcd en esa época. A comienzos de 2016, O'Toole la reemplazó por la implementación de Raft de HashiCorp, que rqlite sigue usando hoy. El código vive en github.com/rqlite/rqlite.

rqlite: consistencia fuerte antes que disponibilidad

La decisión de diseño que definió todo lo demás se tomó en 2014 y nunca cambió: rqlite es un sistema CP, en los términos del teorema CAP. Las escrituras pasan por el nodo líder, necesitan el acuerdo de la mayoría del clúster y una minoría aislada por una partición de red deja de aceptar escrituras.

De ahí sale el resto del diseño: la API HTTP, los niveles de consistencia de lectura (none, weak, strong) y los snapshots para no reenviar el log completo a cada nodo nuevo. Para levantar un clúster de tres nodos en Linux o macOS:

curl -L https://github.com/rqlite/rqlite/releases/download/v8.x/rqlite-v8.x-linux-amd64.tar.gz | tar xz
./rqlited -node-id 1 node1
./rqlited -node-id 2 -http-addr localhost:4002 -raft-addr localhost:4003 -join http://localhost:4001 node2
./rqlited -node-id 3 -http-addr localhost:4004 -raft-addr localhost:4005 -join http://localhost:4001 node3

En Windows, PowerShell usa el mismo binario: descargá el .zip de la release, extraelo y arrancá el nodo.

Expand-Archive rqlite-v8.x-win-amd64.zip -DestinationPath .
.\rqlited.exe -node-id 1 node1

Una vez arriba el clúster, una escritura se manda así:

curl -XPOST 'http://localhost:4001/db/execute' -H "Content-Type: application/json" -d '[["INSERT INTO pedidos(cliente, total) VALUES(?, ?)", "maria", 42.50]]'

Si matás el nodo líder, el clúster elige otro y las escrituras siguen entrando apenas los dos nodos restantes confirman el cambio. Esa recuperación automática es lo que justifica meter Raft delante de un archivo SQLite.

dqlite: el mismo principio, empaquetado distinto

Canonical construyó dqlite en 2017 para darle a LXD, y después a MicroK8s, un almacenamiento replicado embebido sin depender de etcd. Mark Shuttleworth llamó a O'Toole para ver si rqlite podía adaptarse a esa necesidad, pero el encaje no funcionó: dqlite nació en Go, se reescribió en C y usa su propia librería de Raft.

La diferencia con rqlite no es de consenso sino de empaquetado. dqlite es una librería que se embebe dentro de otro binario; rqlite es un servidor que se corre aparte. Canonical necesitaba una base de datos dentro de sus productos, O'Toole necesitaba una base de datos al lado del producto de cualquiera. El repositorio está en github.com/canonical/dqlite.

Litestream: la pregunta distinta que cambió el enfoque en 2021

Ben Johnson, que trabajó con O'Toole en InfluxDB, publicó Litestream a comienzos de 2021. No usa consenso: observa el WAL (write-ahead log) de SQLite y lo transmite a S3, dando recuperación ante desastres para una base de datos de un solo nodo a un costo casi nulo. El proyecto está en litestream.io.

La diferencia de enfoque es la pregunta que cada sistema responde. Litestream resuelve qué pasa si la máquina muere. rqlite resuelve qué pasa si la máquina muere y no se puede esperar a restaurar un backup. La primera pregunta es mucho más común; la segunda es la que tiene quien llega a rqlite.

Fly.io contrató a Johnson en 2022 y lanzó LiteFS, que replica SQLite a nivel de sistema de archivos con leases administrados por Consul. Fue el primer intento de convertir SQLite replicado en una función de plataforma en lugar de algo que uno despliega por su cuenta.

Forks y extensiones: CRDTs y un motor propio

En 2022 aparecieron dos enfoques que ni rqlite ni Litestream cubrían. cr-sqlite agrega CRDTs a SQLite como extensión, de modo que varios escritores pueden divergir y después fusionarse sin necesitar un líder. Es la esquina AP del diseño, pensada para aplicaciones local-first donde la consistencia fuerte de rqlite sería un obstáculo.

libSQL, en cambio, forkeó el motor de SQLite directamente. ChiselStrike, después Turso, quería cambiar partes internas que el proyecto SQLite (que no acepta contribuciones externas) no iba a tocar. Sobre ese fork construyeron un servicio con réplicas en el borde de la red; Turso levantó capital de riesgo con esa propuesta y Supabase la adquirió en 2026.

Las tres esquinas del espacio de diseño

Doce años de reinvención dejan un mapa con tres esquinas, y aparecieron en ese orden. Consenso primero, con rqlite y dqlite: un líder, consistencia fuerte y un clúster que tolera perder nodos. Transmisión segunda, con Litestream: un único escritor, recuperación barata y sin clúster. Fusión tercera, con cr-sqlite: múltiples escritores, consistencia eventual y sin coordinación central.

A esas tres esquinas se suma una cuarta categoría que vende SQLite replicado como producto administrado (Cloudflare D1, Durable Objects y el servicio hosteado de Turso). La categoría pasó de ser algo que uno corre a algo que uno compra.

Cuándo conviene cada opción

Elegí rqlite si necesitás un servidor SQL replicado independiente, con una API HTTP simple, y podés tolerar que las escrituras fallen durante una partición minoritaria. Elegí dqlite si estás embebiendo una base de datos dentro de tu propio binario Go o C, como hace Canonical con LXD.

Elegí Litestream si tenés una aplicación de un solo nodo y solo necesitás sobrevivir a la pérdida de esa máquina, sin pagar el costo operativo de un clúster. Elegí LiteFS si ya corrés en Fly.io y querés esa recuperación a nivel de plataforma. Elegí libSQL o Turso si necesitás réplicas geográficas gestionadas y no te importa alejarte del SQLite original.

El gotcha común a rqlite y dqlite: si tu aplicación necesita seguir aceptando escrituras durante una partición de red, ningún sistema CP te lo va a dar. Ahí la respuesta no es exprimir Raft, sino aceptar un modelo AP como cr-sqlite o replantear si de verdad necesitás consistencia fuerte en esa escritura.

Conclusión

El artículo original de Philip O'Toole, Twelve years of distributed SQLite, cierra con una idea simple. El núcleo estuvo bien desde el principio. SQLite como motor de almacenamiento, con la replicación agregada por fuera, fue reinventado por al menos ocho equipos con necesidades distintas y nadie encontró una razón para dejar de hacerlo.

Para quien evalúa estas herramientas en 2026, la pregunta no es cuál gana sino qué pregunta se está respondiendo: coordinación entre nodos, recuperación de un solo nodo o fusión sin coordinación. Las tres siguen vigentes doce años después.

📖 Versión extendida con más detalle: https://elsolitario.org/2026/10/24/sqlite-distribuido-rqlite-dqlite-litestream-y-mas/?utm_source=telegraph&utm_medium=instant_view&utm_campaign=programacion

Report Page