1 pontos por GN⁺ 2024-05-17 | 1 comentários | Compartilhar no WhatsApp

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

 
GN⁺ 2024-05-17
Comentários do Hacker News

Resumo da coletânea de comentários do Hacker News

  • Discussão interessante e melhorias na documentação

    • A discussão durante o processo foi muito interessante. Também foi surpreendente que o Jepsen não tenha encontrado bugs críticos. Foi um resultado útil esclarecer a documentação e os comportamentos anormais pretendidos. Foi um exercício valioso que trouxe confiança para operar um banco usando Datomic.
  • Entendendo o comportamento das transações do Datomic

    • Foi a primeira vez que li um relatório do Jepsen em profundidade, e gostei da explicação clara sobre o comportamento das transações do Datomic. Percebi que eu não entendia bem as diferenças em relação a bancos de dados SQL. A estrutura das transações do Datomic e a mudança nos nomes dos elementos chamaram atenção.
  • O valor do relatório sobre o Datomic

    • É um relatório muito detalhado e uma excelente análise de um bom banco de dados. Também é bom ver que a documentação ficou mais clara e foi atualizada. Houve também a ideia de que seria bom se a Apple encomendasse uma análise do Jepsen sobre o FoundationDB.
  • A origem do nome Jepsen

    • O nome Jepsen vem da cantora Carly Rae Jepsen. Acho que é um nome perfeito para pesquisa em sistemas distribuídos.
  • Ajuda para escrever programas em Clojure

    • Como sempre, é um trabalho excelente. Gosto de ler esse tipo de material para aprender sobre esses sistemas e captar pequenas informações que ajudam a escrever programas em Clojure.
  • Construindo um datastore parecido com o Datomic

    • Estou construindo recentemente um datastore parecido com o Datomic, então esse relatório parece útil. Também gostei da análise do MongoDB, e recomendo conferir as análises de Redis, RethinkDB e outros.
  • O modelo de dados do Datomic

    • O modelo de dados do Datomic é intuitivo se você já está acostumado com triple store/RDF. No entanto, isso não é mencionado com frequência na documentação nem nas discussões online. Fico curioso se isso acontece porque as pessoas não estão familiarizadas com esses conceitos, ou porque a associação com a web semântica pode causar confusão.
  • Esclarecimento da documentação do Datomic

    • O Jepsen esclareceu as situações de violação de imutabilidade, mas a abordagem do Datomic parece ter se concentrado em esclarecer a documentação. Parece que a equipe do Datomic considera essas violações como erro do usuário.
  • As vantagens do design single-threaded

    • A decisão de projeto de processar gravações em uma única thread foi eficaz. O Datomic é fruto de um ótimo design, e eu gostaria de voltar a usá-lo.
  • As características das transações do Datomic

    • Não usei muito o Datomic, mas não me surpreende que as transações sejam basicamente processamento em lote. Ele opera em uma única thread, então há menos condições de corrida e, por projeto, é mais lento, porém seguro.