7 puntos por xguru 2024-08-09 | 1 comentarios | Compartir por WhatsApp
  • rqlite es una base de datos relacional distribuida, ligera y de código abierto, escrita en Go
  • Está construida sobre el protocolo de consenso Raft y usa SQLite como motor de almacenamiento
  • Ya comenzó el desarrollo de la versión 9.0, cuyo objetivo es reducir el uso de disco en aproximadamente 50%
  • Esta meta se logrará mediante una refactorización de diseño de alto nivel que elimine la causa principal del consumo de disco en rqlite

¿Qué ocupa actualmente la mayor parte del uso de disco?

  • Log de Raft:
    • Un registro de los cambios realizados en el sistema
    • Este log es el núcleo del sistema de consenso Raft
  • Base de datos SQLite activa:
    • La base de datos en vivo que rqlite usa para ofrecer lecturas y escrituras
    • Una vez que las sentencias SQLite se confirman correctamente en el log de Raft, se aplican a la base de datos SQLite activa
  • Snapshot de la base de datos SQLite activa:
    • Para evitar que el log de Raft crezca sin límite, el subsistema Raft dentro de rqlite crea y guarda periódicamente una copia puntual de la base de datos SQLite activa
    • A esta copia se le llama snapshot
    • Cuando se genera un snapshot, rqlite puede recortar el log de Raft
    • Esta copia en snapshot se usa para restaurar el nodo cuando se reinicia, o se envía a otro nodo cuando ese nodo necesita “ponerse al día” con el estado del clúster rqlite existente
    • La creación de snapshots y el recorte del log son conceptos clave en los sistemas basados en Raft

Diseño de alto nivel para rqlite 9.0

  • La estrategia principal para reducir el uso de disco es eliminar la necesidad de almacenar una copia en snapshot de la base de datos SQLite activa dentro del sistema Raft
  • El log de Raft se recorta periódicamente gracias a la generación de snapshots y deja de crecer después de cierto punto, pero la base de datos SQLite activa sigue creciendo a medida que se escriben más datos
  • Y como la copia en snapshot de la base de datos SQLite tiene casi el mismo tamaño que la base de datos SQLite activa, también crece de tamaño
  • Por lo tanto, si se puede eliminar la copia en snapshot, rqlite usará 50% menos disco
  • Sin embargo, un nodo de rqlite necesita una copia en snapshot en ciertos momentos. Eso no se puede evitar.
  • Entonces, ¿cómo se puede omitir la copia y aun así cubrir la necesidad de generar y restaurar snapshots?
  • Para entender cómo evitar almacenar una copia adicional durante el proceso de snapshot, es importante saber que rqlite ejecuta la base de datos SQLite subyacente en modo Write-Ahead Log (WAL)
  • En el diseño propuesto para la versión 9.0, el archivo activo de la base de datos SQLite (sin contar el archivo WAL relacionado) y la copia en snapshot del sistema Raft son lógicamente iguales
  • Aprovechando este hecho, se puede eliminar la necesidad de guardar una copia en snapshot separada en el sistema Raft

Nuevo enfoque para la generación de snapshots

  • Generación de snapshots y checkpoint del WAL:
    • En el momento de crear un snapshot, rqlite hace checkpoint del Write-Ahead Log (WAL) de la base de datos SQLite activa
    • Todas las escrituras posteriores se envían a un nuevo archivo WAL, por lo que el archivo principal de SQLite permanece sin cambios desde el momento en que se generó el snapshot
    • Como resultado, hasta que ocurra el siguiente snapshot, el archivo principal de SQLite representa el estado puntual que necesita el almacenamiento de snapshots de Raft
    • Este enfoque permite usar el archivo SQLite combinado con el archivo WAL para operaciones normales de lectura y escritura, mientras que el archivo principal de SQLite, sin cambios, actúa como el conjunto de datos para el almacenamiento de snapshots de Raft
    • ¡Ya no se necesita una copia adicional!
  • Escritura de referencias en el almacenamiento de snapshots:
    • En lugar de copiar el archivo SQLite completo, rqlite escribe una referencia, como un checksum, en el almacenamiento de snapshots
    • Esta referencia puede usarse para verificar, cada vez que se necesiten los datos del snapshot, que el archivo principal de SQLite coincide con lo que el almacenamiento de snapshots está referenciando
      • (Esta verificación protege contra bugs, errores operativos o corrupción de disco, aunque no es estrictamente necesaria)
  • Restauración desde snapshots:
    • Como se mencionó antes, todas las escrituras posteriores al proceso de snapshot se envían al archivo WAL, por lo que el archivo principal de SQLite queda listo para usarse en el proceso de restauración desde snapshots, ya sea al reiniciar un nodo o al enviar el snapshot a otro nodo
    • Es decir, el archivo principal de SQLite (ignorando el archivo WAL relacionado) se mantiene lógicamente idéntico a lo que se habría escrito en el almacenamiento de snapshots de Raft si rqlite realmente hubiera creado una copia duplicada
  • A este nuevo diseño se le llama “snapshots por referencia”

Mejoras adicionales

  • Los snapshots por referencia también traerán varias otras mejoras importantes
  • Generación de snapshots más rápida: como se escribe una cantidad mínima de datos en el almacenamiento de snapshots de Raft, el proceso de snapshot será mucho más rápido
    • Estará compuesto por el tiempo del checkpoint del WAL de SQLite (normalmente muy corto) y el tiempo de cálculo del checksum
    • Ya no será necesario copiar grandes volúmenes de datos de SQLite al almacenamiento de snapshots cada vez que se genere uno
    • La ventaja de snapshots más rápidos se vuelve clara al saber que las escrituras a rqlite se bloquean durante el proceso de snapshot
  • Reinicios más rápidos: incluso los nodos con varios GB de datos SQLite se reiniciarán mucho más rápido
    • Actualmente, al reiniciar, rqlite tiene que restaurar el archivo activo de la base de datos SQLite desde una copia en el almacenamiento de snapshots de Raft
    • Pero con este nuevo diseño, al iniciar, el archivo activo de la base de datos SQLite ya estará en la ubicación correcta
    • En el mejor de los casos, rqlite solo tendrá que comparar el checksum del almacenamiento de snapshots con el checksum de la base de datos SQLite activa
    • Los sistemas de varios GB deberían reiniciarse en cuestión de segundos

Próximos pasos

  • El paso a rqlite 9.0 será un avance importante en la optimización de la eficiencia de rqlite
  • Se espera que, al implementar snapshots por referencia, se reduzca significativamente el uso de disco, se acelere la generación de snapshots y se mejoren los tiempos de reinicio de los nodos
  • Aún hay muchos detalles que deben resolverse correctamente, como la gestión del WAL de SQLite, una actualización fluida desde versiones anteriores y la elección del checksum
  • Por eso, vale la pena seguir atentos a futuras actualizaciones mientras avanza esta gran versión