Normalização de dados em banco de dados distribuído, microsserviços e ERP

Olá Habr!

Esta pequena nota nasceu no processo de discussão do artigo “Monólitos Distribuídos ...” e, como o tópico requer uma reflexão mais aprofundada, decidi publicá-lo no meu blog. O autor do artigo realmente descreve um banco de dados distribuído, provando que o Log de Eventos é a única estrutura de armazenamento correta. Os argumentos são aproximadamente da seguinte maneira:

  • Como o evento é sempre localizado no espaço / tempo, ele pode armazenar todos os dados em si (às vezes na forma de links para eventos anteriores), o que torna o evento serializável, aumenta a localidade, reduz a conectividade etc.
  • Depois que um evento ocorre, ele não muda mais (quaisquer refinamentos são documentados por outros eventos), o que reduz o tráfego de replicação.
  • O formato de armazenamento de eventos pode ser mais ou menos unificado e desatado de uma área de assunto específica.
  • Os logs de eventos podem ser divididos / mesclados com relativa facilidade, você pode armazenar diferentes tipos de eventos em diferentes nós, ou seja, em essência, estamos falando de um banco de dados distribuído.
  • Os eventos são ordenados por tempo e essa sequência também reflete um relacionamento causal (o evento atual não pode ser referenciado posteriormente).
  • Ao gravar um evento, não é necessário atualizar outros dados de maneira transacional (de fato, é necessário, mas em um número limitado de casos, por exemplo, o saldo do assinante no sistema de cobrança deve ser instantaneamente relevante, é necessário atualizar os contadores de links etc.).
  • Os relatórios podem ser criados diretamente a partir do log de eventos, sem a necessidade de converter os dados em um formulário normalizado.

Em relação ao último ponto, vários testes de desempenho (inclusive no meu blog) mostram que no hardware moderno, o processamento de um bilhão de eventos (fatos) com um algoritmo de passagem única com memória de curto prazo leva minutos, o que é bastante aceitável para geração de relatórios. E como é fácil paralelizar o processamento de eventos de vários tipos que não são conectados por links - o tempo de geração de relatórios pode ser reduzido para dezenas de segundos, sem a sobrecarga de normalizar dados / indexação / coleta de estatísticas / depuração e sugestões de consultas - como é o caso dos RDBMSs regulares. Portanto, criar relatórios com base nesses dados não me assusta. No entanto, considere o problema de maneira mais ampla.

Um aplicativo de negócios típico pode ser representado como uma cadeia de transformação de dados:
"Entrada => modelo => saída". Qualquer esquema de armazenamento é um compromisso entre três extremos:

  • Armazenamos os dados no formato de saída. É assim que uma variedade de fachadas de lojas e OLAPs funciona, onde o tempo de resposta é importante. Os contras são conhecidos - demanda excessiva de memória e baixa taxa de atualização (geralmente em lote).
  • Armazenamos dados no formato do modelo de domínio, simplificando assim os algoritmos de cálculo. Existem muitas desvantagens - é necessária uma transformação dupla de dados (de entrada para modelo e de modelo para saída), os custos de transação aumentam, é difícil fornecer armazenamento distribuído, alterar o esquema é caro etc. No entanto, esta é a opção mais popular.
  • Armazenamos os dados no formato de entrada (na verdade, o que o autor do artigo oferece é um log de eventos). Nesse caso, os custos de transação são mínimos, os dados são facilmente divididos e mesclados, um esquema de armazenamento simples, claro e estável. Lucro! É verdade que você precisa aprender a programar novamente.

Em relação à minha área de interesse (sistemas de informações corporativas), um evento é um documento principal e o livro de referência pode ser considerado um evento anterior. Eu já descrevi a estrutura da tabela de um ERP ocidental típico no artigo “NoERP ou um novo visual ...” , onde propus abolir a normalização excessiva de dados (com exceção dos registros de balanços instantâneos) e reescrever a maioria dos cálculos / relatórios em ciclos de passagem única, nos quais os principais serão processados ​​diretamente documentos. Não repetirei os argumentos, tudo está exposto no artigo, mas o esquema que propus praticamente coincidiu com a tese do autor do primeiro artigo, a saber, que o log de eventos são os dados. É bom quando alguém pensa nessa direção.

É claro que essa abordagem parece um passo atrás em comparação aos DBMSs inteligentes modernos, mas no mundo dos highloids às vezes é necessário abandonar ferramentas populares / abstratas / universais - em favor de uma programação imperativa brutal e eficaz, que, além disso, não requer licenciamento caro para os nós / kernels / usuários.

Gostaria de dizer separadamente sobre o método de organização de relacionamentos no log de eventos - deve ser bidirecional, ou seja, cada evento deve armazenar um contador de referência para si mesmo. Isso é necessário para a implementação de algoritmos de passagem única - passamos de eventos antigos para novos, ao mesmo tempo armazenamos em cache todos os eventos com um número diferente de zero de links recebidos na memória e o excluímos do cache somente após o processamento de todos os referentes. A presença do contador de referência reduz desagradável o desempenho transacional - por exemplo, se o diretório da contraparte for usado em cada documento, o contador de referência na contraparte deverá ser atualizado sempre que um documento for adicionado, às vezes em um nó diferente. No entanto, esse local pode ser otimizado universalmente, evitando transações distribuídas em todos os outros casos.

Na verdade, no nível da ideia, é tudo por enquanto, ainda espero um projeto específico (por exemplo, com base em recebimentos ou faturas) e, se essa oportunidade aparecer, apresentarei um relatório sobre os resultados.

Source: https://habr.com/ru/post/pt453646/


All Articles