Datomic: una base de datos de propósito general para sistemas de registro
# Antecedentes de Datomic
- Datomic es una base de datos de propósito general para sistemas de registro.
- El estado de la base de datos se representa con triples
[entity, attribute, value] (EAV), llamados datoms.
- El esquema controla el tipo y la cardinalidad de los atributos.
- Es una base de datos temporal que modela explícitamente el tiempo.
- Cada transacción se identifica con una marca de tiempo lógica
t y un tiempo de reloj de pared txInstant.
- Las transacciones pueden agregar o eliminar datoms.
- Todos los datoms conservan una referencia a la transacción.
- La base de datos es un conjunto en crecimiento continuo de estas tuplas.
# Funciones de Datomic
- Los usuarios pueden solicitar el estado instantáneo de la base de datos en un tiempo lógico o de reloj de pared.
- Se puede ver el historial completo de la base de datos.
- Se puede consultar mediante una API estilo Datalog, una API declarativa de recorrido de grafos y un tipo de dato
Entity estilo ODM.
- Existen dos versiones: Datomic Pro y Datomic Cloud.
# 1.1 Arquitectura
- Datomic Pro está compuesto por varios servicios que cooperan entre sí.
- Los Transactors ejecutan transacciones de escritura, mantienen índices y escriben datos al almacenamiento.
- Los Peers son clientes pesados que incluyen una librería JVM para enviar transacciones, ejecutar consultas y cachear resultados.
- Los Clients son clientes livianos que reenvían transacciones y consultas a un peer server.
- Cada transacción se agrega al log en orden cronológico.
- Se almacena como un árbol persistente e inmutable en un almacén de datos como Cassandra o DynamoDB.
- Garantiza un orden global de transacciones usando operaciones Sequential CaS.
- Los Peers se conectan directamente al almacenamiento y a los transactors.
# 1.2 Modelo de transacciones
- Datomic tiene un modelo de transacciones distintivo.
- Separa estrictamente la ruta de lectura y la de escritura.
- La lectura obtiene un estado inmutable de la base de datos.
- Las transacciones de escritura se representan como una lista ordenada de operaciones.
- Las funciones de transacción leen el estado de la base de datos y devuelven un nuevo conjunto de operaciones.
- Las funciones de transacción no devuelven valores al invocador.
- Las transacciones solo devuelven efectos.
- NuBank usa Datomic para ofrecer servicios financieros.
# 1.3 Consistencia
- Anuncia transacciones ACID y promete de forma clara un modelo de consistencia y garantías de durabilidad.
- Las transacciones se almacenan como una única escritura atómica.
- Todos los peers ven las transacciones completadas hasta cierto punto en el tiempo.
- Garantiza transacciones serializable.
- Se puede sincronizar el estado más reciente llamando a d/sync.
- Fue diseñado como un sistema de escritura única, aunque pueden ejecutarse varios transactors al mismo tiempo.
# 2 Diseño de pruebas
- Se diseñó una suite de pruebas para Datomic usando la biblioteca de pruebas Jepsen.
- Se instaló Datomic Pro 1.0.7075 en un clúster de nodos con Debian Bookworm.
- Se aprovisionó una tabla de DynamoDB en AWS.
- Las pruebas se ejecutaron en distintos nodos, incluidos Transactors y Peers.
- Las operaciones de la suite de pruebas se realizaron a través de la API HTTP.
- Se inyectaron varias fallas, incluyendo particiones de red y Garbage Collection.
- Se reiniciaron transactors usando servicios systemd.
# 2.1 Append a listas
- Se diseñó una operación de append a listas usando el verificador transaccional Elle.
- Cada lista se identifica con una clave primaria.
- Se ejecutan transacciones que incluyen lecturas y operaciones de append.
- Datomic almacena los atributos multivaluados como conjuntos no ordenados.
- Se usan funciones de transacción para expresar transacciones de lectura-escritura.
# 2.2 Append a listas usando CaS
- La función db/cas controla las actualizaciones concurrentes de atributos.
- Se usa el patrón CaS para garantizar aislamiento de snapshot.
- Cada lista se codifica como un string de valor único separado por comas.
# 2.3 Consistencia interna
- Se diseñaron operaciones para medir la consistencia interna.
- Incluyen transacciones que cambian varias veces el valor de un atributo, o que agregan y eliminan hechos.
- También realizan varias operaciones CaS.
# 2.4 Aprobación
- Se diseñó una máquina de estados que simula aprobación y rechazo.
- Las funciones de aprobación y rechazo verifican su estado correspondiente y abortan la transacción.
# 3 Resultados
- No se encontró un comportamiento que violara las principales afirmaciones de seguridad de Datomic.
- Las transacciones parecen haberse ejecutado en un orden total.
- Las transacciones de lectura con (d/sync conn) coinciden con el orden en tiempo real.
- La consistencia interna coincide con la documentación de Datomic, aunque difiere del comportamiento habitual de las bases de datos.
# 3.1 Consistencia interna
- La mayoría de las bases de datos ofrecen semántica de ejecución serial dentro de una transacción.
- Datomic trata todas las operaciones dentro de una transacción como si se ejecutaran de forma concurrente.
- Las funciones de transacción solo observan el estado de la base de datos al inicio de la transacción.
- Si ocurre un conflicto en un atributo de cardinalidad única, la transacción se aborta.
# 3.2 Write skew virtual
- Como las funciones de transacción se ejecutan concurrentemente, funciones que por separado son correctas pueden producir resultados incorrectos cuando se ejecutan juntas.
- Si las funciones de aprobación y rechazo se llaman dentro de la misma transacción, pueden ocurrir ambas al mismo tiempo.
- Esto coincide con la documentación de Datomic, pero puede sorprender a los usuarios.
# 3.3 Predicados de entidad
- Los predicados de entidad pueden usarse para garantizar invariantes de la base de datos.
- Ofrecen varias restricciones, incluidas tipo, unicidad y predicados arbitrarios.
- Los predicados de entidad inspeccionan el estado completo de la base de datos para decidir si permiten una transacción.
- Se agregan predicados de entidad a las funciones de aprobación y rechazo para garantizar las invariantes.
La opinión de GN⁺
- Datomic es una base de datos temporal, y poder consultar fácilmente estados pasados de los datos la hace muy útil para sistemas de registro como los servicios financieros.
- El modelo de ejecución concurrente de las funciones de transacción mejora el rendimiento, pero puede no resultar familiar para los usuarios.
- Con predicados de entidad, se pueden implementar fácilmente restricciones complejas de integridad de datos.
- Se usa en grandes servicios financieros como NuBank, lo que valida su estabilidad y escalabilidad.
- El modelo de transacciones único de Datomic exige una forma de pensar distinta a la de las bases de datos tradicionales, por lo que puede haber una curva de aprendizaje.
1 comentarios
Opiniones de Hacker News
Resumen de comentarios de Hacker News
Debate interesante y mejoras en la documentación
Comprender el comportamiento transaccional de Datomic
El valor del informe sobre Datomic
El origen del nombre Jepsen
Ayuda para escribir programas en Clojure
Construcción de un datastore similar a Datomic
El modelo de datos de Datomic
Aclaraciones en la documentación de Datomic
Ventajas de un diseño de hilo único
Características transaccionales de Datomic