Datomic: banco de dados de sistema de registro de propósito geral
# Contexto do Datomic
- Datomic é um banco de dados de propósito geral para sistemas de registro.
- O estado do banco de dados é representado por triplas
[entity, attribute, value] (EAV), chamadas de datoms.
- O schema controla o tipo e a cardinalidade dos atributos.
- É um banco de dados temporal que modela explicitamente o tempo.
- Cada transação é identificada por um timestamp lógico
t e pelo horário de parede txInstant.
- As transações podem adicionar ou remover datoms.
- Todo datom mantém uma referência à transação.
- O banco de dados é um conjunto em crescimento contínuo dessas tuplas.
# Funcionalidades do Datomic
- O usuário pode solicitar o estado em snapshot do banco de dados em um tempo lógico ou horário de parede.
- É possível ver todo o histórico do banco de dados.
- É possível consultar por meio de API estilo Datalog, API declarativa de navegação em grafos e tipo de dado
Entity no estilo ODM.
- Existem duas versões: Datomic Pro e Datomic Cloud.
# 1.1 Arquitetura
- Datomic Pro é composto por vários serviços cooperativos.
- Transactors executam transações de escrita, mantêm índices e gravam dados no armazenamento.
- Peers são clientes pesados que incluem bibliotecas JVM para enviar transações, executar consultas e fazer cache dos resultados.
- Clients são clientes leves que encaminham transações e consultas para um peer server.
- Cada transação é adicionada ao log em ordem cronológica.
- Os dados são armazenados como árvores persistentes e imutáveis em um armazenamento de dados como Cassandra ou DynamoDB.
- A ordem global das transações é garantida usando operações Sequential CaS.
- Peers se conectam diretamente ao armazenamento e aos transactors.
# 1.2 Modelo de transação
- Datomic tem um modelo de transação único.
- Ele separa rigidamente os caminhos de leitura e escrita.
- As leituras obtêm um estado imutável do banco de dados.
- As transações de escrita são representadas como uma lista ordenada de operações.
- As funções de transação leem o estado do banco de dados e retornam um novo conjunto de operações.
- As funções de transação não retornam valores ao chamador.
- As transações retornam apenas efeitos.
- O NuBank usa Datomic para oferecer serviços financeiros.
# 1.3 Consistência
- Ele anuncia transações ACID e promete com clareza seu modelo de consistência e garantias de durabilidade.
- As transações são armazenadas como uma única escrita atômica.
- Todos os peers veem as transações concluídas até um determinado ponto no tempo.
- Ele garante transações serializáveis.
- É possível sincronizar com o estado mais recente chamando d/sync.
- Foi projetado como um sistema de escrita única, mas vários transactors podem ser executados simultaneamente.
# 2 Projeto de testes
- Foi projetada uma suíte de testes do Datomic usando a biblioteca de testes Jepsen.
- O Datomic Pro 1.0.7075 foi instalado em um cluster de nós Debian Bookworm.
- Tabelas DynamoDB foram provisionadas na AWS.
- Os testes foram executados em vários nós, incluindo Transactors e Peers.
- As operações da suíte de testes foram executadas por meio da API HTTP.
- Foram injetadas várias falhas, incluindo partições de rede e Garbage Collection.
- Serviços systemd foram usados para reiniciar os transactors.
# 2.1 Append em listas
- Foi projetada uma operação de append em listas usando o verificador transacional Elle.
- Cada lista é identificada por uma chave primária.
- São executadas transações com leituras e operações de append.
- O Datomic armazena atributos multivalorados como conjuntos não ordenados.
- Funções de transação são usadas para expressar transações de leitura-escrita.
# 2.2 Append em listas com CaS
- A função db/cas é usada para controlar atualizações concorrentes de atributos.
- O padrão CaS é usado para garantir isolamento por snapshot.
- Cada lista é codificada como uma string de valor único separada por vírgulas.
# 2.3 Consistência interna
- Foram projetadas operações para medir a consistência interna.
- Elas incluem transações que alteram valores de atributos várias vezes ou adicionam e removem fatos.
- Operações CaS são executadas várias vezes.
# 2.4 Aprovação
- Foi projetada uma máquina de estados para simular aprovação e rejeição.
- As funções de aprovação e rejeição verificam cada estado e abortam a transação.
# 3 Resultados
- Não foram encontrados comportamentos que violassem as principais alegações de segurança do Datomic.
- As transações parecem ter sido executadas em ordem total.
- Transações de leitura com (d/sync conn) são consistentes com a ordem em tempo real.
- A consistência interna está de acordo com a documentação do Datomic, mas difere do comportamento típico de bancos de dados.
# 3.1 Consistência interna
- A maioria dos bancos de dados fornece semântica de execução serial dentro de uma transação.
- O Datomic trata todas as operações dentro da transação como execução concorrente.
- As funções de transação observam apenas o estado do banco de dados no início da transação.
- Se houver conflito em um atributo de cardinalidade única, a transação é abortada.
# 3.2 Write skew virtual
- Como as funções de transação são executadas concorrentemente, funções que estão corretas isoladamente podem produzir resultados incorretos quando executadas juntas.
- Se as funções de aprovação e rejeição forem chamadas na mesma transação, aprovação e rejeição podem ocorrer ao mesmo tempo.
- Isso está de acordo com a documentação do Datomic, mas pode surpreender os usuários.
# 3.3 Predicados de entidade
- É possível garantir invariantes do banco de dados usando predicados de entidade.
- Eles oferecem vários tipos de restrições, incluindo tipo, unicidade e predicados arbitrários.
- Predicados de entidade inspecionam o estado completo do banco de dados para decidir se a transação deve ser permitida.
- A adição de predicados de entidade às funções de aprovação e rejeição garante a invariância.
Opinião do GN⁺
- Datomic é um banco de dados temporal que facilita consultar estados passados dos dados, sendo muito útil para sistemas de registro como serviços financeiros.
- O modelo de execução concorrente das funções de transação melhora o desempenho, mas pode não ser familiar para os usuários.
- Com predicados de entidade, é possível implementar facilmente restrições complexas de integridade de dados.
- Seu uso em grandes serviços financeiros como o NuBank comprova sua estabilidade e escalabilidade.
- Como o modelo de transação exclusivo do Datomic exige uma forma de pensar diferente da dos bancos de dados tradicionais, pode haver uma curva de aprendizado.
1 comentários
Comentários do Hacker News
Resumo da coletânea de comentários do Hacker News
Discussão interessante e melhorias na documentação
Entendendo o comportamento das transações do Datomic
O valor do relatório sobre o Datomic
A origem do nome Jepsen
Ajuda para escrever programas em Clojure
Construindo um datastore parecido com o Datomic
O modelo de dados do Datomic
Esclarecimento da documentação do Datomic
As vantagens do design single-threaded
As características das transações do Datomic