Continuo voltando a este controle de qualidade. E não encontrei as respostas existentes sutis o suficiente, por isso estou adicionando esta.
TL; DR. Sim ou Não, dependendo do uso da fonte de eventos.
Existem dois tipos principais de sistemas de origem de eventos, dos quais estou ciente.
Processadores de eventos a jusante = Sim
Nesse tipo de sistema, os eventos acontecem no mundo real e são registrados como fatos. Como um sistema de armazém para acompanhar paletes de produtos. Basicamente, não há eventos conflitantes. Tudo já aconteceu, mesmo que estivesse errado. (Ou seja, o palete 123456 foi colocado no caminhão A, mas foi programado para o caminhão B.) Posteriormente, os fatos são verificados quanto a exceções por meio de mecanismos de relatório. Kafka parece bem adequado para esse tipo de aplicativo de processamento de eventos downstream.
Nesse contexto, é compreensível o motivo pelo qual a Kafka a defende como uma solução de Event Sourcing. Porque é bem parecido com o modo como já é usado, por exemplo, fluxos de cliques. No entanto, as pessoas que usam o termo Event Sourcing (em oposição ao Stream Processing) provavelmente estão se referindo ao segundo uso ...
Fonte de verdade controlada por aplicativo = Não
Esse tipo de aplicativo declara seus próprios eventos como resultado de solicitações de usuários passando pela lógica de negócios. Kafka não funciona bem nesse caso por dois motivos principais.
Falta de isolamento da entidade
Esse cenário precisa da capacidade de carregar o fluxo de eventos para uma entidade específica. O motivo comum para isso é criar um modelo de gravação transitório para a lógica de negócios usar para processar a solicitação. Fazer isso é impraticável em Kafka. O uso de tópico por entidade pode permitir isso, exceto que não é um iniciador quando pode haver milhares ou milhões de entidades. Isso ocorre devido aos limites técnicos no Kafka / Zookeeper.
Um dos principais motivos para usar um modelo de gravação transitório dessa maneira é tornar as alterações da lógica de negócios baratas e fáceis de implantar.
Em vez disso, é recomendável usar o tópico por tipo para o Kafka, mas isso exigiria o carregamento de eventos para cada entidade desse tipo apenas para obter eventos para uma única entidade. Como você não pode dizer por posição de log quais eventos pertencem a qual entidade. Mesmo usando Snapshots para iniciar a partir de uma posição de log conhecida, esse pode ser um número significativo de eventos para agitar.
Falta de detecção de conflitos
Em segundo lugar, os usuários podem criar condições de corrida devido a solicitações simultâneas contra a mesma entidade. Pode ser bastante indesejável salvar eventos conflitantes e resolvê-los após o fato. Portanto, é importante ser capaz de evitar eventos conflitantes. Para dimensionar o carregamento de solicitações, é comum usar serviços sem estado, enquanto evita conflitos de gravação usando gravações condicionais (somente gravações se o último evento da entidade for #x). Simulação simultânea otimista. Kafka não suporta simultaneidade otimista. Mesmo que o apoiasse no nível do tópico, seria necessário ir até o nível da entidade para ser eficaz. Para usar o Kafka e evitar eventos conflitantes, você precisará usar um gravador com estado e serializado no nível do aplicativo. Este é um requisito / restrição arquitetural significativo.
Outras informações
Atualizar por comentário
O comentário foi excluído, mas a pergunta era algo como: o que as pessoas usam para armazenamento de eventos?
Parece que a maioria das pessoas lança sua própria implementação de armazenamento de eventos em um banco de dados existente. Para cenários não distribuídos, como back-ends internos ou produtos independentes, está bem documentado como criar um armazenamento de eventos baseado em SQL. E existem bibliotecas disponíveis no banco de dados de vários tipos. Também existe o EventStore , criado para esse fim.
Em cenários distribuídos, vi algumas implementações diferentes. O projeto Panther do Jet usa o Azure CosmosDB , com o recurso Alterar Feed para notificar os ouvintes. Outra implementação semelhante que ouvi na AWS está usando o DynamoDB com seu recurso Streams para notificar os ouvintes. A chave da partição provavelmente deve ser a identificação do fluxo para melhor distribuição de dados (para diminuir a quantidade de provisionamento em excesso). No entanto, uma repetição completa entre fluxos no Dynamo é cara (leitura e custo). Portanto, esse impl também foi configurado para o Dynamo Streams despejar eventos no S3. Quando um novo ouvinte fica online, ou um ouvinte existente deseja uma repetição completa, ele lê o S3 para recuperar o atraso.
Meu projeto atual é um cenário de vários inquilinos, e eu montei o meu em cima do Postgres. Algo como o Citus parece apropriado para escalabilidade, particionando por tentativa + fluxo.
Kafka ainda é muito útil em cenários distribuídos. É um problema não trivial expor os eventos de cada serviço a outros serviços. Uma loja de eventos não é construída para isso normalmente, mas é exatamente isso que Kafka faz bem. Cada serviço tem sua própria fonte interna de verdade (pode ser o armazenamento de eventos ou não), mas ouve Kafka para saber o que está acontecendo "fora". O serviço também pode postar eventos em Kafka para informar o "exterior" de coisas interessantes que o serviço fez.