O blog da AWS

Como o BTG Pactual aumentou performance e reduziu custos através de CQRS com DynamoDB e Amazon Aurora

Por Ricardo Mantovani, BTG, IT Director – Database Team, Raphael Barros, BTG, IT Analyst – IT Credit Team e Roberto Fernandes da Silva, AWS – Solutions Architect

Neste artigo exploramos como as equipes de Engenharia de Confiabilidade de Banco de Dados (DBRE – Database Reliability Engineer) e de desenvolvimento conseguiram reduzir os custos de banco de dados aplicando padrões de design de arquitetura de microsserviços. Este artigo aborda a implementação do CQRS(Command Query Responsibility Segregation) no Amazon DynamoDB e no Amazon Aurora PostgreSQL, dois serviços que fazem parte do portfólio de bancos de dados especializados da AWS.

As equipes de desenvolvimento do BTG atuam de forma descentralizada, tendo autonomia para utilizar todo o conjunto de serviços da AWS na construção de seus produtos. Apesar dessa autonomia, o BTG conta com times especializados, como o de arquitetura de banco de dados, cujo objetivo é educar as equipes sobre os melhores casos de uso para cada serviço, oferecer soluções reutilizáveis apoiando o banco em decisões estratégicas relacionadas aos bancos de dados.

Ambos os times sintonizados com a cultura do BTG Pactual que se baseia em uma parceria meritocrática e uma mentalidade semelhante à de uma startup. Essa abordagem nos inspira a procurar constantemente soluções inovadoras para atender as variadas necessidades dos nossos clientes. O BTG age com independência e agilidade, em um ambiente que valoriza a ausência de burocracia e adota uma estrutura organizacional horizontal.

Cenário dos squads de arquitetura de banco de dados e IT Credit:

O time de banco de dados atua como referência para questões de confiabilidade de banco de dados, comunicando-se de forma aberta e compartilhando conhecimento. Fornecem orientações para garantir a confiabilidade em todas as fases de desenvolvimento e operação dos sistemas.

Além de compartilhar conhecimento e apoiar o BTG nas decisões estratégicas sobre o tema, criam automações e ferramentas reutilizazeis para bancos de dados, ampliando as funcionalidades dos produtos AWS e soluções opensource. Entre as ferramentas podemos citar o particionamento e expurgo automatizados que utilizam o Amazon S3 como uma camada adicional de armazenamento. Estas soluções são adotadas por diversos times de desenvolvimento graças a modularidade e robustez. O time não apenas administra banco de dados, mas se destaca pela criação de soluções para as outras equipes.

O time de IT Credit é responsável pela arquitetura, desenvolvimento, e manutenção do sistema que controla todo o ciclo de vida de todos os contratos de crédito do banco, incluindo desembolsos, pagamentos, posição (valor) do contrato dia a dia e outros inúmeros controles. O sistema também é responsável pela distribuição dessas informações em tempo real para os outros sistemas do banco.

Com a abertura do mercado para o varejo e a entrada de novos negócios, o volume de transações aumentou mais de 450% (comparando os três primeiros trimestres de 2022 e 2023) e continua aumentando dia a dia. Nosso sistema processa diariamente, em média, mais de 30 milhões de transações com diversos propósitos. Diante do desafio de lidar com alta volumetria de dados, empenhamo-nos na busca pelos melhores padrões de projeto, com prioridade na utilização das ferramentas disponíveis na AWS.

Figura 1. Gráfico com a volumetria de operações realizadas no banco de dados em Ago/23

Desafio

Durante o comitê de arquitetura, nos deparamos com um desafio relacionado a área de IT Credit do banco BTG. Nesse contexto, a equipe de desenvolvimento estava utilizando o DynamoDB, uma escolha motivada pela necessidade de lidar com operações de escrita e leitura em larga escala. Além disso, a equipe enfrentava diariamente um grande volume de eventos que requeriam processamento e posterior arquivamento, visando a distribuição através de diversas aplicações e painéis de controle.

A principal razão que impulsionou a revisão do padrão de design do microsserviço originou-se do desafio substancial relacionado ao volume significativo de operações de leitura e escrita no DynamoDB. Embora tenhamos obtido êxito nas operações de escrita, nos deparamos com a necessidade de executar diversos tipos de consultas muitas das quais não foram previstas na modelagem das tabelas, outro fator importante foi o volume de dados necessários para resolver estas consultas.

Figura 2. Arquitetura baseada apenas em DynamoDB

Uma consideração crucial ao optar por um Banco de Dados NoSQL, como o DynamoDB, é a necessidade de compreender previamente os padrões de acesso, a fim de realizar uma modelagem adequada. Devido à necessidade de analisar nossos dados, implementamos consultas complexas, incluindo agregações. Como solução principal, optamos por criar índices secundários no DynamoDB. Embora tenhamos alcançado o resultado desejado com essa abordagem, a implementação resultou em um aumento significativo no custo de gravação pois envolvia a escrita nos índices secundários criados para suportar as consultas. Com o tempo, começamos a enfrentar problemas de throttling devido à sobrecarga das partições no DynamoDB, revelando-se um desafio decorrente da falta de padrões de acesso bem definidos para o cenário em questão.

Explorando o Amazon DynamoDB, encontramos um banco de dados NoSQL transacional, no formato chave-valor, projetado para fornecer desempenho constante independente da escala. Em cada partição de uma tabela no DynamoDB, a capacidade é de 3.000 unidades de leitura, 1.000 unidades de escrita considerando registros de 1KB, ou uma combinação linear dessas duas operações. Quando o tráfego direcionado a uma partição ultrapassa esse limite, ocorre o chamado throttling das requisições, o que, por conseguinte, impõe restrições às operações.

No nosso cenário, enfrentávamos um desafio no âmbito analítico, resultando no alcance dos limites da partição do DynamoDB. Isso, por sua vez, gerava problemas para os usuários que dependiam dessa parte específica da aplicação.

Solução

O CQRS, sigla para “Command Query Responsibility Segregation”, um padrão de arquitetura de software com a finalidade de separar de maneira distintiva as operações de leitura (queries) e de escrita (commands) entre micros serviços e bancos de dados separados.

Dentro do contexto do CQRS, as operações de leitura são direcionadas a um modelo de leitura otimizado (read model), meticulosamente planejado para fornecer de maneira eficaz os dados necessários para as consultas. Em contraste, as operações de escrita encontram seu lugar em um modelo de escrita (write model), que gerencia as regras de negócio complexas e as atualizações no estado do sistema.

Isso viabiliza a otimização do desempenho do sistema nas operações de leitura, visto que o modelo de leitura pode ser planejado para prontamente atender às consultas mais frequentes, sem estar sobrecarregado com a lógica de escrita. Adicionalmente, proporciona maior flexibilidade, uma vez que estas podem ser tratadas de forma segregada e especializada.

Figura 3. Arquitetura orientada a banco de dados com propósito

Adotamos a integração nativa entre o DynamoDB Streams e o AWS Lambda. Essa integração facilita a elaboração de fluxos de trabalho automatizados, capazes de reagir imediatamente às mudanças nos dados do DynamoDB. Sempre que ocorre uma modificação em um elemento da tabela, seja adição, atualização ou remoção, o DynamoDB Streams registra o evento e o direciona ao AWS Lambda. Nesse ponto, o Lambda é acionado para executar uma função personalizada, permitindo o processamento dos dados do evento, a tomada de decisões fundamentadas nas alterações e a realização de ações pertinentes em tempo real.

Para acomodar as leituras escolhemos o banco de dados Aurora PostgreSQL devido à sua arquitetura otimizada e distribuída. O Amazon Aurora é reconhecido por proporcionar um desempenho, particularmente em cenários de cargas de trabalho intensas e alto tráfego.

Seguindo a abordagem ágil, adotamos um processo colaborativo. Enquanto a equipe de desenvolvimento se concentrava na implementação do lambda e do algoritmo para o envio de eventos ao Aurora, o time de especialistas em banco de dados estava dedicado à instalação e configuração de automações personalizadas.

A arquitetura acima nos permite aproveitar a escalabilidade do DynamoDB para lidar com escritas e a flexibilidade do Amazon Aurora para lidar com consultas, ainda falando sobre leitura implementamos uma estratégia de rotacionamento de partição e expurgo para o Amazon S3 devido a necessidades de conformidade e preparando o banco para outros casos de uso como analytics e machine learning, isto foi possível devido às extensões do Amazon Aurora.

Figura 4. Arquitetura com retenção de Longo Prazo (Arquitetura Final)

Resultados

Ao analisar os prós e contras da nova arquitetura, adotando o padrão CQRS, ficou evidente que alcançamos diversas vantagens. Entre os pontos positivos, destacam-se a redução dos custos em comparação a arquitetura anterior, melhor desempenho ao manter a escrita no DynamoDB e distribuir a leitura horizontalmente através do Amazon Aurora. Além disso, a adoção do padrão CQRS possibilitou o uso da linguagem SQL para consultas, conferindo maior autonomia e facilidade na geração de análises sobre os dados.

No entanto, é importante considerar alguns desafios. As dificuldades incluem a consistência eventual que o padrão CQRS exige, juntamente com um ligeiro aumento na complexidade do desenvolvimento dos microsserviços.

Diariamente, registramos alguns milhões de transações de escrita entre elas inserts e updates no DynamoDB. No Amazon Aurora, gerenciamos cerca de 52.449.619 inserções e 27.710.612 atualizações, resultando em um total diário de 45 GB em cada partição de dados individual.

Ao eliminar os índices secundários no DynamoDB e transferir as operações de leitura para o Aurora, conseguimos encolher uma tabela de 3.3TB em 73%. Com a redução da sobrecarga de escrita, a otimização da leitura e a diminuição dos custos de backup do DynamoDB, ao mesmo tempo que incluímos o custo do Amazon Aurora, obtivemos uma economia global de 65% nos gastos.

Figura 5. Redução do tamanho do banco de dados após remoção dos índices secundários

Em relação aos erros de throttling, tivemos uma diminuição de mais 80% no primeiro mês após a implementação do CQRS, removendo 90% dos índices da tabela. Zeramos as ocorrências de throttling dois meses depois, com a remoção dos últimos índices secundários no DynamoDB, atingindo assim o objetivo inicial do projeto.

Figura 6. Redução na ocorrência de throttling após remoção dos índices secundários

A redução do custo também foi verificada com a implantação da nova estratégia. Apesar do aumento gradual da volumetria no sistema, tivemos uma redução inicial de 65%. Conseguimos alcançar uma redução de custos ainda maior, de 50%, ao implementar nossa automação de particionamento e expurgo automático para o S3. Isso inclui a transferência de partições para o S3 para retenção de longo prazo, resultando não apenas em economia, mas também em melhorias de desempenho e saúde do sistema. Essa automação é uma extensão do PostgreSQL criada com pg_tle da AWS e estendendo ferramentas como pg_partman, pg_cron e AWS_S3, permitindo-nos personalizar funcionalidades conforme nossas necessidades.

Figura 7. Redução no custo do DYNAMO + AURORA mesmo com o aumento da volumetria

Outro ganho expressivo foi a redução do tempo médio de processamento das integrações. Antes da implementação do novo padrão tínhamos um tempo médio de processamento de 1,5 segundos para cada integração, após a melhoria tivemos uma redução média de 50%, reduzindo o tempo para 0,7 segundos.

Conclusão

Modernização é um caminho em constante evolução que nos permite aproveitar ao máximo os padrões de design, soluções reutilizáveis para desafios comuns enfrentados pelos desenvolvedores ao projetar software. Esses padrões desempenham um papel fundamental na criação de sistemas escaláveis, flexíveis e fáceis de manter.

Um outro conceito importante é o de bancos de dados com propósitos, pois desempenha um papel vital na arquitetura de microsserviços. Essa abordagem envolve a seleção cuidadosa e a implementação de uma variedade de tipos de bancos de dados, alinhados com as necessidades específicas de um aplicativo ou sistema. A premissa fundamental dessa estratégia é tirar o máximo proveito das vantagens inerentes a cada tipo de banco de dados, com o intuito de melhorar o desempenho e otimizar a gestão de custos.

Neste post, focamos exclusivamente em um único microsserviço, um padrão de design específico, e dois bancos de dados com propósitos diferentes.

Após uma implementação bem-sucedida do padrão CQRS, utilizando o Amazon DynamoDB e o Amazon Aurora PostgreSQL, conseguimos replicar com êxito esse padrão em vários outros microsserviços na área de IT Credit. Além disso, ele provou ser passível de reutilização e também foi utilizado por várias outras Squads de desenvolvimento.

A modernização do sistema de crédito é um exemplo que destaca a importância de abraçar a mudança e aproveitar serviços que agilizam a implementação de soluções modernas e resilientes.

Sobre os autores

Ricardo Mantovani é IT Director na BTG Pactual, com mais de 25 anos de experiência na área de banco de dados, desenvolvimento de software, arquiteturas de soluções escaláveis, distribuídas, nativas da nuvem e orientadas a eventos. Entusiasta opensource, especialista PostgreSQL e tendo um histórico de desenvolvimento de soluções empresariais, bem como experiência em várias startups, incluindo a experiência como sócio em uma startup do setor financeiro.

https://www.linkedin.com/in/ricardodsmantovani/

Raphael Barros é Associate Director na BTG Pactual, com mais de 18 anos de experiência em desenvolvimento de software. Ao longo de sua carreira, ele trabalhou no desenvolvimento e na arquitetura de aplicações onpremises, híbridas e native cloud, sempre entregando produtos seguros, escaláveis e resilientes

https://br.linkedin.com/in/raphael-marques-de-barros

Roberto Fernandes da Silva é um arquiteto sênior da AWS, com mais de 18 anos de experiência na área de tecnologia. Atua como trusted advisor no segmento financeiro, apoiando clientes nas decisões em torno de nuvem e tecnologia, nos últimos anos tem trabalhado com fundação/operação para nuvens e containers.
https://www.linkedin.com/in/roberto-fernandes-da-silva/

Sobre os revisores

Felipe Bortoletto é um arquiteto de soluções na AWS. Trabalha na Amazon desde 2017, em 2019 ele participou do programa Tech U que proveu o conhecimento e pratica necessário para ser promovido para arquiteto de soluções. Atualmente está trabalhando com o mercado financeiro e se especializando em segurança.

https://www.linkedin.com/in/felipebortto/

Lucas Ferrari Lucas Ferrari é um arquiteto de soluções especialista em banco de dados da AWS, onde ajuda os clientes a projetarem e implementarem soluções de banco de dados na nuvem. Trabalha com banco de dados desde 2008 e suas especializações principais são Dynamodb e Aurora.

https://www.linkedin.com/in/lucas-rodrigues-ferrari/