O blog da AWS
Tutorial: Consumindo Alterações em Tempo Real do Amazon Aurora MySQL com AWS DMS e Amazon MSK
Por Rubens Devito, Arquiteto de Soluções AWS Brasil
Arquiteturas Baseadas em Eventos
Arquiteturas baseadas em eventos vem sendo cada vez mais comuns em aplicações modernas. Imagine poder reagir em tempo real a certas situações que ocorrem, como detectar uma fraude ou oferecer um produto, ou analisar posteriormente cada ação de um usuário separadamente, para um entendimento melhor do seu comportamento, tudo baseado em eventos gerados pela sua aplicação. Isso pode ser facilmente implementado em camadas superiores da aplicação como APIs (Interface de Programção de Aplicações), por exemplo. Usando serviços como Amazon API Gateway e funções AWS Lambda, APIs podem ser totalmente serverless e sua lógica de negócio só é engatilhada quando um evento específico ocorrer na API, como um POST ou um PUT, por exemplo.
O mesmo conceito pode ser aplicado também na camada de dados. É possível consumir em tempo real mudanças que ocorrem em seu banco de dados. A maneira como isso é feito varia dependendo da tecnologia usada, mas entre o banco e sua aplicação podemos utilizar uma ferramenta de streaming de dados. Por exemplo, o Amazon DynamoDB (banco de dados NoSQL da AWS) oferece o DynamoDB Streams, que replica em tempo real alterações feitas em uma tabela usando o Amazon Kinesis Data Analytics (ferramenta de streaming de dados) para um destino.
Para esse blog post, vamos capturar essas mudanças em tempo real de uma base de dados relacional Amazon Aurora compatível com MySQL usando o AWS Database Migration Service (DMS), e vamos ingerir essas mudanças em um tópico do Apache Kafka. A partir daí, suas aplicações podem consumir esses dados através desse tópico.
AWS DMS é um serviço gerenciado da AWS que migra bancos de dados para a AWS de maneira rápida e segura. Com o AWS DMS migrações podem ser homogêneas (PostgreSQL para PostgreSQL, por exemplo) ou heterogêneas (Oracle para PostgreSQL, por exemplo), consulte a documentação de origens de dados e destinos suportados pelo AWS DMS. Além disso, o AWS DMS suporta replicação contínua em alta disponibilidade de uma base dados para dentro da AWS. Tudo isso sem que sua base de dados de origem fique indisponível.
O Apache Kafka é uma ferramenta open source utilizada para ser um meio escalável de inserção massiva de um fluxo de dados contínuo (streaming), possibilitando aplicações (ou consumidores) a processarem o dado próximo ao tempo real. Não somente isso, o Apache Kafka pode ser um ponto único de comunicação para vários destinos ao mesmo tempo.
Vamos utilizar neste blog o Amazon Managed Streaming for Apache Kafka (MSK). O MSK é um serviço totalmente gerenciado que facilita a criação e o gerenciamento de clusters de Apache Kafka em alta disponibilidade na AWS. Tarefas mais complexas como manter um cluster de Zookeeper, substituir nós em falhas do cluster e criptografar a comunicação com o Kafka são algumas das facilidades que o MSK trás para seus clientes.
A Arquitetrura
Podemos dividir em 3 partes os eventos:
- Evento de manipulação de dados (DML) ocorre no Aurora MySQL (insert, update e delete);
- AWS DMS detecta a mudança e a captura;
- Dado é inserido em um tópico do Apache Kafka (MSK) pelo AWS DMS;
O tempo total somando as 3 etapas deve ser de poucos segundos.
Prepare o Aurora MySQL para replicar os dados
Para executar a replicação é necessário que você tenha já uma base de dados Amazon Aurora compatível com MySQL e nesta base você habilitar a criação de logs.
A primeira etapa é habilitar o Amazon Aurora compatível com MySQL para ser usado como endpoint de origem para o DMS. Como vamos replicar em tempo real, Change Data Capture (CDC), precisamos habilitar o binlog:
1. Habilite backups automáticos do Aurora, caso já não esteja habilitado;
2. Certifique que o binlog fique retido por um tempo. Por padrão, bancos de dados MySQL gerenciado na AWS, como RDS e Aurora, deletam esses logs assim que possível. Estenda esse tempo para que os logs continuem disponíveis. Por exemplo, o comando a seguir retêm o binlog por 24 horas:
call mysql.rds_set_configuration(‘binlog retention hours’, 24)
3. Edite dois parâmetros do DB cluster parameter group:
binlog_format, altere para ROW binlog_checksum altere para NONE
4. Confira se o Aurora MySQL está usando o Parameter Group com essas novas alterações;
5. Caso você possua Read Replica, habilite também backups para essas réplicas;
Pronto, o seu Aurora MySQL está preparado para replicar o CDC para o DMS.
Criar o DMS para replicar os dados
O próximo passo será configurar a instância de replicação do DMS, que ficará entre o Aurora MySQL e o Apache Kafka. Mas para que essa instância consiga se conectar no Kafka, precisamos atender 2 pré-requisitos:
1. DMS e Kafka precisam estar na mesma Amazon VPC;
2. DMS e Kafka precisam usar o mesmo Security Group;
Portanto, antes de iniciarmos a configuração, crie um Security Group na VPC onde o DMS e o Kafka ficarão. Para esse tutorial, o Security Group foi configurado para aceitar todo o tráfego inbound da rede da VPC. Em um cenário de produção, restrinja a portas específicas de acordo com suas necessidades de negócio. Em seguida, permita tráfego na porta 3306 do Security Group do Aurora para aceitar tráfego oriundo (inbound) deste novo Security Group.
Após a criação do Security Group, podemos iniciar nossa configuração. Vamos criar um Subnet Group específico para essa instância do DMS e logo em seguida, criar a instância com o novo Subnet Group:
OBS: só continue o tutorial se os dois pré-requisitos acima foram completados.
1. Dentro do DMS, no menu do lado esquerdo, clique em Subnet Groups;
2. Clique em Create subnet group;
3. Em Subnet group configuration:
a. Em Name, dê um nome a subnet group;
b. Em Description, dê uma descrição;
c. Em VPC, selecione a VPC a ser utilizada. Lembre-se que o Kafka deve estar nessa VPC também;
4. Em Add subnets, selecione as subnets da VPC;
5. Clique em Create subnet group;
Agora vamos criar a instância:
1. Dentro do DMS, no menu do lado esquerdo, clique em Replication instances;
2. Clique em Create replication instance;
3. Em Replication instance configuration:
a. Em Name, dê um nome a instância;
b. Em Description, dê uma descrição para sua instância;
c. Em Instance Class, selecione o tamanho da instância desejada. Para teste uma t2.medium deve servir. Para demais ambientes, a sugestão é no mínimo uma c4.large;
d. Em VPC, selecione a VPC. Lembrando que ela deverá ficar na mesma VPC do Kafka;
4. Em Advanced security and network configuration:
a. Em Replication subnet group, selecione o subnet group recém criado;
b. Em VPC security group, selecione o Security Group recém criado;
5. Clique em Create;
Crie o Apache Kafka para receber os dados
Agora vamos criar o endpoint de destino do DMS, que será um tópico do Apache Kafka. Nesse blog post vamos usar o Amazon MSK, mas você pode também usar um Apache Kafka em EC2. Caso o segundo cenário seja o seu, você pode pular essa parte e ir direto para a criação dos endpoints do DMS.
1. Dentro do MSK, clique em Create Cluster;
2. Em Choose cluster creation method selecione a opção Create cluster with custom settings;
3. Em General:
a. Em Cluster name dê um nome para o cluster;
b. Em Apache Kafka Version selecione 2.1 (recommended);
4. Em Networking:
a. Selecione a VPC onde o Kafka irá rodar. Note aqui que o MSK/Kafka deve ficar na mesma VPC do DMS;
b. Selecione o número de AZs desejadas e suas respectivas subnets. Para ambientes em produção, o recomendado é 3;
5. Em Brokers:
a. Em Broker instance type selecione o tamanho do broker desejado. Para ambientes de teste pequeno, use t3, para demais ambientes, selecione no mínimo a m5.large;
b. Em Number of brokers per Availability Zone, selecione a quantidade desejada. Idealmente, para ambientes produtivos, é ter ao menos um broker por AZ;
6. Em Encryption, selecione Both TLS encrypted and plaintext traffic allowed. Em ambientes de produção, idealmente a primeira opção seria habilitada, permitindo tráfego somente criptografado;
7. Finalmente, clique em Create Cluster;
A criação do cluster pode demorar uns 15 minutos. Enquanto isso vamos criar os endpoints do DMS.
Crie o endpoint do Amazon DMS de origem
1. Dentro do DMS, no menu do lado esquerdo, clique em Endpoints;
2. Clique em Create endpoint;
3. Em Endpoint type:
a. selecione Source endpoint, e em seguida, selecione Select RDS DB instance;
b. Selecione o Amazon Aurora MySQL;
4. Em Endpoint configuration:
a. Em Endpoint identifier, dê uma identificação para o endpoint;
b. Em User name, coloque o nome do usuário admin do banco;
c. Em Password, coloque a senha do usuário admin do banco;
5. Finalmente, clique em Create endpoint;
Agora vamos testar a conexão entre o DMS e o Aurora:
1. Uma vez o Endpoint criado, volte para o menu Endpoints;
2. Selecione o Endpoint do Aurora e clique em Actions > Test connection;
3. Clique em Run test;
Provavelmente seu teste falhou. Isso porque o Security Group do Aurora MySQL não está aceitando tráfego do Security Group do DMS. Portanto, edite o Security Group do seu Aurora MySQL para aceitar conexões na porta 3306 oriundas (inbound) de um Security Group do DMS e rode o teste novamente.
Continue esse tutorial somente se o seu teste de conectividade tiver sucesso (status – successful).
Crie o endpoint do DMS de destino
Antes de criarmos o endpoint para o Kafka, precisamos editar uma configuração no cluster para permitir que o DMS crie tópicos automaticamente para você.
1. Dentro do MSK, clique no seu cluster;
2. Encontre a área Configuration e clique em Edit;
3. Clique em Create configuration;
4. Em General:
a. Em Configuration Name, dê um nome para essa configuração;
5. Em Configuration properties for revision 1, edite a primeira linha para:
a. create.topics.enable=true;
6. Clique em Create;
7. Retorne para o mesmo local do passo 2) e certifique-se que seu cluster está usando a nova configuração;
Agora sim vamos criar o endpoint de destino do DMS, que será um tópico do Apache Kafka:
- Dentro do MSK, em Cluster summary, clique em View client information e copie todas as informações;
2. Dentro do DMS, no menu do lado esquerdo, clique em Endpoints;
3. Clique em Create endpoint;
4. Em Endpoint type selecione Target endpoint;
5. Em Endpoint configuration:
a. Em Endpoint identifier, dê uma identidade para o endpoint;
b. Em Target engine, selecione kafka;
c. Em Broker, copie um endpoint de um broker do seu Kafka do passo 1) e cole aqui, com o final :9092. Por exemplo: b-1.exemplokafka.1abcde2.c3.kafka.us-east-2.amazonaws.com:9092;
6. Clique em Create endpoint;
Uma vez o endpoint criado, teste a conectividade da mesma maneira que foi feito com o Aurora MySQL. Só continue o tutorial se o teste tiver sucesso (status – successful).
Crie as tasks do DMS
Agora vamos criar as tasks do DMS que vão copiar as informações da origem (Aurora MySQL) para o destino (Apache Kafka). Neste exemplo vamos criar duas tasks, uma para fazer full load, e outra para fazer a replicação (CDC):
1. Dentro do DMS, no menu do lado esquerdo, clique em Database migration tasks;
2. Clique em Create task;
3. Em Task configuration:
a. Em Task identifier, dê uma identificação para task;
b. Em Replication instance, selecione a instância do DMS;
c. Em Source endpoint, selecione o endpoint do Aurora MySQL;
d. Em Target Endpoint, selecione o endpoint do Apache Kafka;
e. Em Migration Type, selecione e Migrate existing data;
4. Em Task settings:
a. Em Editing mode, selecione Wizard;
b. Em Target table preparation mode, selecione as opções que lhe forem mais adequadas. Nesse exemplo a opção Do nothing foi usada;
c. Verifique outras opções caso queira alterar como tamanho do lob, número de tabelas a serem carregadas em paralelo. Para esse exemplo, todas essas configurações foram deixadas no padrão;
5. Em Table mappings:
a. Em Editing mode, selecione Wizard;
b. Em Selection rules, clique em Add new selection rule
i. Em Schema, selecione Enter a schema;
ii.Selecione as opções que forem mais adequadas para o seu caso. Nesse exemplo, todas as opções foram deixadas no padrão;
6. Clique em Create task;
Uma vez a task criada, aguarde para que o Status dela fique em Load complete.
Teste a replicação
Podemos verificar também dentro do Apache Kakfa quando o load foi concluído. Para isso você precisa ter o Apache Kafka client instalado.
Para saber os tópicos que existem dentro do Kafka, você precisará utilizar o endpoint do Zookeeper. Copie o endpoint do Zookeeper do View client information. Copie a informação que está abaixo do ZooKeeper connect. Repare que é possível que você tenha mais de um endpoint. Você pode escolher qualquer um para descobrir os tópicos existentes.
Agora execute o seguinte comando em um client:
bin/kafka-topics.sh --list <endpoint do zookeeper>:2181
Copie o resultado.
Agora vamos de fato listar os dados carregados no tópico. Lembre-se de usar o broker do Kafka configurado no DMS:
bin/kafka-console-consumer.sh --topic <SEU-TOPICO-AQUI> --from-beginning --bootstrap-server <broker-configurado-no-dms>:9092
Os dados do seu banco de dados devem ser listados aqui. Mantenha esse comando rodando.
Agora vamos criar uma task no DMS para executar a replicação:
1. Dentro do DMS, no menu do lado esquerdo, clique em Database migration tasks;
2. Clique em Create task;
3. Em Task configuration:
a. Em Task Identifier, dê uma identidade para a task;
b. Em Replication instance, selecione a instancia do DMS;
c. Em Source database endpoint, selecione o endpoint do Aurora;
d. Em Target database endpoint, selecione o endpoint do Kafka;
e. Em Migration Type, selecione Replicate data changes only;
4. Em Task Settings:
a. Em Editing mode, selecione Wizard;
b. Em CDC start mode, selecione Specify start time, e coloque o horário atual (em UTC);
5. Clique em Create task;
Aguarde para que o status da task fique como Replication ongoing.
Faça uma atualização (insert, delete ou update) no seu banco e veja ela aparecer automaticamente no tópico do Kakfa.
Próximos Passos
Agora que você viu como replicar em tempo real seu banco de dados para o Kafka, você pode começar a desenvolver microserviços que consumirão esses tópicos. Lembrando que você pode criar replicações diferentes para tópicos diferentes, e pode colocar várias aplicações para consumir um mesmo tópico. Dessa maneira, você tem uma comunicação distribuída e em tempo real, entre o que ocorre no seu banco dados e suas aplicações.
Potencialmente esse caso de uso pode ser usado também para alimentar Data Lakes, uma vez que o Amazo DMS suporta o Amazon S3 como destino, ou até mesmo fazer análise em tempo real do dado em replicação, pois o Amazon DMS também suporta o Amazon Kinesis como destino.
Por fim, você pode adaptar esse tutorial para outros motores de bancos de dados, como os oferecidos pelo Amazon RDS (MySQL, PostgreSQL, Oracle, SQL Server e MariaDB), bancos de dados NoSQL ou até mesmo um banco de dados rodando on-premises. Basta seguir os pré-requisitos de cada banco listado na documentação do AWS DMS.
Escalabilidade
Um tópico do Kafka pode ter mais de uma partição e é desta forma que podemos aumentar a quantidade de processos de escrita no tópico, e também de leitura com vários consumidores por exemplo. Se um tópico tiver uma única partição ele permitira que apenas um processo o consuma, e à medida que você precise de maior vazão de dados é interessante usar o particionamento pois pode usar dezenas ou centenas de consumidores.
O AWS DMS suporta esta configuração habilitando um mapa de parâmetros (mapping parameters) informando uma chave de particionamento (partition-key) que será usado para operações em paralelo com ‘ParallelApplyThreads’, podendo utilizar o formato ‘schema-table-type’, ‘primary-key’ ou ainda utilizar campos específicas de cada tabela como chave de particionamento.
Conclusão
Nesse tutorial vimos como é possível criar uma arquitetura baseada em eventos também para a camada de dados usando o Amazon Aurora MySQL como origem, Apache Kafka em Amazon MSK como destino e o AWS DMS replicando as informações entre eles. Dessa maneira, você pode reagir em tempo real a mudanças que ocorrem em seu banco de dados, e começar a modernizar a comunicação entre as diferentes camadas de seus sistemas.
Sobre o autor
Rubens Devito é Arquiteto de Soluções na AWS Brasil.
Se você tem perguntas sobre a AWS ou algum projeto que queira discutir, preencha este formulário e um representante entrará em contato com você.