A fonte de eventos é apenas para quando as gravações são raras?

9

Estou lendo sobre o fornecimento de eventos e não consigo parar de me perguntar se isso só faz sentido em situações exóticas em que as gravações são muito raras ou é necessária uma auditoria de nível militar.

Um sistema não excepcional com uso significativo pode produzir entre centenas e milhares de gravações por dia, traduzindo, digamos, um milhão ou 2 gravações (portanto, eventos) por ano de operação. Mesclar milhões de objetos (eventos) apenas para obter o estado atual parece uma proposição ridícula, quando comparada a uma leitura direta de um armazenamento tradicional. No entanto, a fonte de eventos está por trás de alguns dos sistemas com melhor desempenho (pense em LMAX).

Então, o que estou perdendo? A restauração do estado do fluxo de eventos é realizada com frequência? Ou é raramente necessário fazer isso e, em vez disso, usar um armazenamento diferente para operações normais (por exemplo, usar o armazenamento de consulta do CQRS) e restaurar os eventos apenas em casos excepcionais (como replicação, auditoria etc.)?

kaqqao
fonte

Respostas:

6

Então, o que estou perdendo?

Tomando um palpite.

A primeira coisa que você pode estar perdendo é que você só precisa recarregar os eventos para o estado que está sendo reconstruído. Se você pode modelar seus limites de transação de maneira limpa, cada objeto pode gravar eventos marcados com seu próprio ID e, em seguida, ler apenas esses eventos. Usando um banco de dados relacional para armazenamento de eventos, haveria uma coluna de identificação indexada para acelerar essa consulta. Usando EventStore, cada objeto teria seu próprio fluxo.

É necessário algum cuidado em seu modelo para fazer isso de forma limpa, pois você deseja ter certeza de que está modificando apenas um único objeto em cada transação e, portanto, precisa tomar cuidado para isolar corretamente cada invariante que está tentando aplicar.

Nos casos em que isso não é rápido o suficiente, você ainda tem a possibilidade de criar instantâneos do seu estado (memorização) e persistir no "armazenamento tradicional". Cada instantâneo é marcado com o número de sequência do último evento usado para criar o instantâneo; ao recarregar, o repositório pega primeiro o instantâneo e aplica novos eventos a ele. (Isso implica uma maneira razoável de capturar os instantâneos mais recentes - os eventos também são marcados com o número de sequência ou você tem uma maneira eficiente de ler o fluxo de eventos para trás até chegar ao ponto de partida.)

Ainda há uma vantagem sobre a abordagem usual aqui, pois seus snapshots podem ser construídos em paralelo com suas gravações, em vez de serem mesclados com eles: basta colocar um ouvinte de evento em algum outro encadeamento / processo e deixá-lo feliz ao escrever à loja de instantâneos em qualquer horário que pareça razoável. Afinal, o instantâneo não precisa ser particularmente oportuno - apenas com frequência suficiente para que o trabalho de reaplicar os eventos mais recentes não estrague seu SLA.

(A captura instantânea complica a migração; qualquer alteração na serialização do modelo invalida o cache da captura instantânea. Naturalmente, você pode reconstruir as capturas instantâneas usando a nova serialização como parte da migração e "recuperar o atraso" quando as alterações forem ativadas.)

A restauração do estado do fluxo de eventos é realizada com frequência?

Sim, ele é. O que normalmente é mostrado nos exemplos do CQRS é que a camada Aplicativo, após garantir que o comando enviado seja bem formado, a camada do aplicativo carregará o objeto de domínio de um repositório, onde a carga é um construtor padrão seguido de uma repetição do fluxo de eventos (ou equivalente, uma chamada para uma fábrica com uma lista de eventos).

Dois outros pensamentos contraditórios.

  1. Pode haver um cache atrás da interface do repositório
  2. A invalidação de cache é um dos dois problemas difíceis.
VoiceOfUnreason
fonte