O blog da AWS

Modernize bancos de dados legados usando o Event Sourcing e CQRS com o AWS DMS

Ao migrar de monolitos para microsserviços, você geralmente precisa propagar os mesmos dados do monolito para vários repositórios de dados posteriores. Isso inclui bancos de dados criados especificamente para servir microsserviços como parte de um projeto de decomposição, o Amazon Simple Storage Service (Amazon S3) para hidratar um data lake ou como parte de uma arquitetura long-running command query responsibility segregation (CQRS), na qual as leituras e gravações são segregadas para separar as solicitações de gravação altamente transacionais das solicitações de leitura analítica.

O event sourcing facilita todos esses casos de uso ao fornecer uma série ordenada e imutável de eventos que representam o estado do sistema de origem

Tomemos, por exemplo, um aplicativo que rastreia a produção de ferramentas (widgets). Um exemplo de implementação de event sourcing e uma arquitetura CQRS nesse sistema é mostrado no diagrama a seguir.

CQRS data flow diagram

Os comandos (writes) da aplicação são instruções que alteram o estado do repositório de dados Online Transactional Processing (OLTP). O event stream então envia eventos à medida que eles ocorrem para um event store. Finalmente, esses eventos são reproduzidos em sistemas downstream (que processam etapas seguintes ao evento) , como um banco de dados OLAP (Online Analytical Processing), bancos de dados de propósito específico (purpose-built) para apoiar microsserviços ou um data lake.

Há várias maneiras de implementar essa arquitetura na AWS. Uma abordagem é usar um event bus (barramento de eventos) como o Amazon Managed Streaming for Apache Kafka (Amazon MSK) para enviar os eventos aos consumidores (para obter mais informações, consulte Capture changes from Amazon DocumentDB via AWS Lambda and publish them to Amazon MSK). A desvantagem disso é que exige que o sistema que emite os eventos conheça o — você precisa alterar a aplicação para capturar todos os eventos e enviá-los ao event bus ou event stream. Isso pode ser complexo e propenso a erros, além de diminuir os esforços de desenvolvimento para sair do monolito. Além disso, ele adiciona trabalho a todos os recursos que estão sendo desenvolvidos enquanto a refatoração ocorre para garantir que os novos serviços emitam eventos.

É aqui que podemos usar o AWS Database Migration Service (AWS DMS). O AWS DMS permite que você migre de qualquer fonte de dados suportada para qualquer destino compatível, tanto de forma única quanto contínua. É a parte contínua que é importante aqui: o change data capture (CDC) não é apenas adequado para migração, mas também para hidratar event stores como parte de uma arquitetura event-sourcing. Neste post, exploramos dois padrões para implementar essa abordagem. A primeira abordagem usa somente o AWS DMS. A segunda abordagem usa o AWS DMS em conjunto com o Amazon MSK.

Visão geral da solução

O primeiro padrão usa uma implementação somente do AWS DMS. Criamos uma tarefa do AWS DMS para replicar do banco de dados monolítico (fonte) para o event store, neste caso o Amazon Simple Storage Service (Amazon S3). Em seguida, o AWS DMS usa esse event store intermediário como ponto de partida para a replicação em outros bancos de dados. Essa abordagem é ótima quando não há exigência de consistência forte. Exemplos podem ser um banco de dados de relatórios e análises que exige apenas uma visão agregada diária dos dados ou uma auditoria retrospectiva dos dados em que a replicação em tempo real não é esperada. Esse padrão é mostrado no diagrama a seguir.

O segundo padrão usa o AWS DMS como conector para extrair os dados da fonte sem precisar fazer alterações no sistema de origem, mas usa o Kafka (neste caso, o Amazon MSK) como event store e para transmitir para os consumidores do downstream. Isso tem a vantagem de normalmente ser mais rápido do que o método no primeiro padrão e permite que as aplicações consumam diretamente do stream. Esse padrão é mostrado no diagrama a seguir.

Architecture diagram for MSK solution

Pré-requisitos

Para testar a solução, você precisa ter uma conta da AWS. Você também precisa de permissões do AWS Identity and Access Management (IAM) para criar recursos do AWS DMS, Amazon MSK, AWS Lambda e Amazon DynamoDB.

Implantação dos exemplos

Para exemplos de cada solução, fornecemos templates do AWS Serverless Application Model (AWS SAM) que você pode implantar em sua própria conta. Você também pode usar esses exemplos como referência para suas próprias implementações.

Para implantar o template  do AWS SAM, clone o repositório do GitHub e siga as instruções no repositório:

git clone git@github.com:aws-samples/aws-dms-event-sourcing-cqrs.git

Solução 1: somente AWS DMS

Começamos explorando a solução mais simples, somente com o AWS DMS. Com o template de exemplo implantado, navegue até o console do AWS DMS e verifique se duas tarefas foram criadas.

A primeira é a carga total inicial e o CDC contínuo do banco de dados de origem, neste caso, uma instância Amazon Relational Database Service (Amazon RDS) for PostgreSQL. Essa tarefa carrega os dados no bucket do S3 do event store de destino.

A segunda task é o event store (Amazon S3) para a task do DynamoDB. Em nosso cenário de exemplo, estamos decompondo nosso monolito em microsserviços e escolhendo o banco de dados de propósito específico para o trabalho. O primeiro microsserviço que decompomos, nossa função “get widgets”, é migrado para o DynamoDB. Essa tarefa gerencia a hidratação inicial e a replicação contínua de nosso event store nesse novo microsserviço.

Execute as tarefas de replicação

Depois que alguns dados de amostra forem gerados (1—2 minutos), você poderá executar as tasks de replicação. Conclua as seguintes etapas:

  1. No console do AWS DMS, localize a primeira task, que é a carga inicial e a replicação contínua para o Amazon S3.
  2. Confirme se a task está no estado Ready.
  3. Selecione a tarefa e, no menu Actions, escolha Restart/Resume para executar a task.
  4. Enquanto a primeira task estiver em execução, repita essas etapas para executar a segunda task, que é a carga inicial e a replicação contínua para o DynamoDB.
  5. Escolha cada task para ver seu progresso e verificar se os registros foram transferidos.

Neste exemplo de aplicação, uma regra agendada do Amazon EventBridge invoca uma função Lambda a cada minuto para gravar um novo registro na origem, simulando o tráfego de produção chegando no nosso monolito existente. Isso forma a parte “command” de nossa segregação de command e query — durante a fase de migração e teste, as gravações continuam persistindo no data store legado, com as leituras sendo servidas a partir do novo armazenamento de dados de microsserviços.

A captura de tela a seguir confirma que os dados estão sendo replicados para o Amazon S3.

dms first task running state

Depois de alguns segundos, vemos que a tarefa está replicando os dados do event store para o DynamoDB, conforme mostrado na captura de tela a seguir.

dms second task running state

Verifique os dados no Amazon S3

Vamos acompanhar esses dados por meio dos vários componentes envolvidos, começando pelo event store. Podemos usar esse log imutável e append-only, dos eventos em nosso sistema para hidratar futuros microsserviços de downstream ou executar funções de análise no local.

  1. No console do Amazon S3, navegue até o bucket criado pela pilha do AWS CloudFormation. Há duas pastas no bucket: uma pasta de carregamento inicial e uma pasta CDC.
  2. Escolha a pasta CDC e observe os arquivos que contêm os eventos transmitidos do sistema de origem.

results in S3 bucket

  1. Baixe um dos arquivos CSV e abra-o em seu editor de texto preferido.
  2. Confirme se as inserções provenientes do sistema de origem estão presentes aqui (representadas pela letra ‘I’ na primeira coluna).

Se nossas entidades fossem mutáveis, também veríamos eventos do tipo update (U) e delete (D) presentes

A captura de tela a seguir mostra um exemplo de arquivo de evento.

export of csv results

Validar dados no DynamoDB

Para visualizar os dados no DynamoDB, siga as seguintes etapas:

  1. No console do DynamoDB, navegue até Explore items e selecione a tabela criada pela pilha do CloudFormation.
  2. Na seção Scan/Query items, selecione Scan e escolha Run.
  3. Confirme se todos os widgets do sistema de origem estão sendo replicados por meio do event store para o data store de microsserviços.

Agora, nosso novo microsserviço consome os eventos diretamente do DynamoDB, e qualquer nova funcionalidade que consuma esses eventos é desenvolvida com base no novo data store sem adicionar mais código ao monolito.

results in dynamodb

Benefícios da solução

Por que ter duas etapas em vez de replicar diretamente da origem para o destino?

Em primeiro lugar, o event store foi projetado para ser a fonte canônica da verdade dos eventos gerados em nosso sistema. Mesmo quando posteriormente tivermos migrado  do monolito, ainda usamos o event store como o núcleo do nosso sistema. Essa fonte de verdade significa que vários consumidores posteriores podem se hidratar a partir desse único armazenamento de dados, por exemplo, vários microsserviços que podem precisar acessar subconjuntos dos mesmos dados com padrões de acesso diferentes (pense em uma pesquisa por valor-chave de um único widget versus uma pesquisa difusa em uma variedade de widgets).

Em segundo lugar, o mais comum desses padrões de acesso adicionais é analytics. Alguns sistemas têm um serviço de geração de relatórios dedicado com um data warehouse e um star-schema cuidadosamente desenhado, mas, para algumas cargas de trabalho de analytics, isso pode não ser necessário. Ter acesso aos dados brutos em um formato semiestruturado no Amazon S3 para serem consumidos para análise ad hoc por uma ferramenta de consulta, como o Amazon Athena, ou para ingestão em uma plataforma de visualização e inteligência de negócios, como o Amazon QuickSight, pode ser suficiente. A arquitetura event-sourcing tem essa funcionalidade incorporada.

Solução 2: AWS DMS e Amazon MSK

Agora, exploramos a solução usando o AWS DMS e o Amazon MSK. Como mencionamos no início deste post, isso está mais próximo da replicação em tempo real. Portanto, para aplicativos que exigem uma visão mais atualizada dos dados, isso é mais apropriado. Ainda há alguma latência porque a replicação é assíncrona, portanto, o aplicativo ainda deve tolerar uma consistência eventual.

Execute a task de replicação

Para iniciar a task de replicação contínua, conclua as seguintes etapas:

  1. Implante o template do CloudFormation a partir do repositório de exemplo. Siga as instruções no repositório para saber como implantar o modelo.
  2. O template levará cerca de 15 minutos para ser implantado. Depois que o modelo for implantado, aguarde de 1 a 2 minutos para que alguns dados de amostra sejam gerados.
  3. No console do AWS DMS, inicie a task criada pelo modelo. Essa task executa a carga total e a replicação contínua.
  4. Selecione a task para verificar se as linhas estão sendo replicadas agora.

msk dms task status

Esses dados estão sendo replicados em um tópico do Kafka em um cluster MSK. Em seguida, temos dois consumidores desse tópico; o primeiro é nossa tabela do DynamoDB. Para hidratar isso, temos uma função Lambda lendo os dados do Kafka e gravando-os no DynamoDB. Se navegarmos até o console do DynamoDB, agora há linhas em nossa nova tabela, conforme mostrado na captura de tela a seguir.

results in dynamodb

O segundo consumidor do tópico é um conector MSK Connect. Para nosso conector, estamos usando o plug-in Confluent S3 Sink. Para obter mais detalhes sobre como configurar o Amazon MSK usando esse plug-in, consulte  estes Exemplos. Esse conector fornece um serviço gerenciado para replicar o fluxo de eventos em nosso bucket de armazenamento de eventos do S3. Se navegarmos até o console do Amazon S3 e abrirmos o bucket criado pelo modelo, veremos que temos os eventos brutos do Kafka sendo transmitidos diretamente para o bucket.

results in s3 bucket

A partir daqui, poderíamos usar esse event stream da mesma forma descrita anteriormente. Podemos fornecer a área de preparação para um processo de extração, transformação e carregamento (ETL), facilitar a análise local por meio do Athena e do QuickSight ou hidratar ainda mais consumidores, como microsserviços adicionais.

Benefícios da solução

Por que não usar essa solução como padrão em vez da solução exclusiva do AWS DMS? Embora a implementação usando o Amazon MSK tenha menor latência, ela introduz o custo adicional de executar um cluster MSK perpetuamente, junto com a complexidade dessa parte móvel adicional. Para operações mais sofisticadas ou sensíveis à latência, essa é uma compensação válida. Para alguns aplicativos, como relatórios e análises, em que uma eventual consistência de segundos é aceitável, a solução somente do AWS DMS pode apresentar uma solução mais simples e econômica.

Limpeza

Vários dos serviços discutidos nesta postagem se enquadram no nível gratuito da AWS, portanto, você só incorre em cobranças por esses serviços depois de exceder os limites de uso do nível gratuito. Você pode encontrar preços detalhados nas páginas de preços do Lambda, DynamoDB, Amazon RDS e Amazon MSK.

Para evitar cobranças inesperadas, você deve excluir todos os recursos não utilizados. Se você implantou o template de exemplo do AWS SAM, exclua o CloudFormation Stack por meio do console do AWS CloudFormation.

Conclusão

Neste post, exploramos duas maneiras de implementar um sistema event-sourced usando o AWS DMS. Event Sourcing e CQRS estão se tornando cada vez mais comuns à medida que mais empresas os implementam para se livrar de soluções legadas e monolíticas e projetar soluções preparadas para o futuro. A parte principal de ambas as soluções é event store imutável e append-only, no Amazon S3. Isso forma a base a partir da qual novos microsserviços, soluções de analytics e padrões de acesso alternativos são fornecidos.

Mas talvez o mais importante de tudo seja que ele prepara a arquitetura para o futuro. O melhor armazenamento de dados para seu aplicativo hoje pode não ser o melhor armazenamento de dados para seu aplicativo daqui a 5 ou 10 anos. Ter portabilidade de dados e a capacidade de reproduzir esses eventos em qualquer armazenamento de dados no futuro oferece uma enorme flexibilidade. Ele também permite criar data lakes ou arquiteturas de data mesh a partir do event store local de cada serviço, oferecendo maior capacidade de descoberta e, portanto, maior valor aos seus dados.

Experimente a solução hoje mesmo clonando o repositório de exemplo. Compartilhe suas ideias nos comentários sobre essas e quaisquer outras implementações do CQRS e event sourcing na AWS.

 

Este artigo foi traduzido do Blog da AWS em Inglês.


Sobre o autor

Josh Hart é arquiteto sênior de soluções na Amazon Web Services. Ele trabalha com clientes de ISV no Reino Unido para ajudá-los a criar e modernizar seus aplicativos SaaS na AWS.

 

 

 

 

Tradutor

Michael Costa é arquiteto de soluções na Amazon Web Services Brasil, com mais de 20 anos de experiência em computação e especialista no projeto e desenvolvimento de sistemas