Cenários de uso comuns
Escalabilidade da aplicação
Tratamento de conexões em aplicações orientadas por eventos e sem servidor
As aplicações orientadas por eventos e sem servidor, como APIs e serviços web respaldados pelo AWS Lambda, geralmente precisam atender a um grande número de solicitações de curta duração de clientes. Esse padrão de uso pode causar rotatividade de conexão do lado do banco de dados, sem a possibilidade de implementar o grupo de conexões do lado da aplicação. O desempenho do banco de dados pode se degradar devido unicamente ao número de conexões simultâneas ou o banco de dados pode exceder o respectivo limite de conexão, provocando erros do lado do cliente.
Nesses cenários, o RDS Proxy pode oferecer os seguintes benefícios:
-
Ele reduz o custo de estabelecer conexões entre o banco de dados e o proxy e oferece agrupamento e multiplexação de conexões para converter um grande número de conexões de clientes em um número bem menor de conexões de banco de dados de backend. Isso ajuda a reduzir a sobrecarga de conexão e a contenção no banco de dados, especialmente em mecanismos de banco de dados como o PostgreSQL, no qual o custo de estabelecer e manter conexões é relativamente alto.
-
Ele pode lidar com surtos de conexão de uma maneira mais tranquila. Por exemplo, quando um banco de dados excede o respectivo limite de conexão, ele exibe imediatamente um erro para o cliente. Quando o RDS Proxy precisa tomar uma conexão emprestada do grupo, mas o grupo já está no limite, o proxy pode esperar que uma conexão fique disponível. Esse recurso pode melhorar a experiência do cliente ao transformar erros graves em um pequeno aumento na latência de consulta.
-
Com o tamanho configurável do grupo de conexões, também é possível usar o RDS Proxy como um mecanismo de controle de utilização ou redução de carga. Se o número de conexões exceder os limites especificados, o RDS Proxy esperará que uma conexão fique disponível dentro de um tempo-limite configurável. Isso pode ser útil nos casos em que o banco de dados atende a várias workloads e você deseja limitar a pressão que uma workload específica pode criar no banco de dados.
Tratamento de conexões em aplicações distribuídas baseadas em contêiner
Uma arquitetura de aplicação distribuída baseada em contêiner pode ter centenas ou até milhares de contêineres, cada em que cada um executa uma cópia do código da aplicação. Mesmo que os contêineres individuais sejam capazes de fazer o agrupamento de conexões, esses grupos são específicos ao contêiner e, portanto, muito pequenos. O número de contêineres multiplicado pelo tamanho de cada minigrupo de contêineres pode vir a exceder os limites de conexão em bancos de dados do Amazon RDS ou Aurora.
Nessa situação, a capacidade do RDS Proxy de realizar o agrupamento de conexões (reutilizar conexões) e a multiplexação (atender vários clientes usando uma conexão de backend) é muito valiosa. Você ainda pode usar o grupo de conexões dentro de cada contêiner para reduzir a rotatividade entre os threads da aplicação e o RDS Proxy, mas o proxy pode ajudar a diminuir o número de conexões de banco de dados de backend a um nível gerenciável.
Aumentar a utilização de réplicas de leitura
Os bancos de dados com alto volume de leitura podem exigir várias réplicas de leitura para atender ao tráfego somente leitura. As aplicações podem usar sua própria lógica para escolher a qual réplica se conectar ou, mais comumente, usam um mecanismo de escalonamento circular baseado em DNS, como o endpoint de leitor de cluster do Aurora. No entanto, uma abordagem baseada em DNS pode levar à utilização desigual da réplica devido ao armazenamento em cache do DNS. Por exemplo, os clientes podem se “fixar” em uma réplica específica, não reconhecer novas réplicas que estão sendo adicionadas ao cluster ou tentar se conectar a réplicas que não existem mais.
Quando você usa um endpoint somente leitura do RDS Proxy, o proxy roteia as conexões de clientes entre todas as réplicas disponíveis usando uma lógica de “conexões menos pendentes”. O RDS Proxy não balanceia a carga do tráfego com base nas métricas do banco de dados, como utilização de CPU, mas tenta igualar o número de conexões de clientes em cada réplica, que é ponderado pelo limite de conexão do banco de dados. Por exemplo, se você tiver três réplicas do Aurora em execução com uma configuração max_connections de 500, 500 e 1.000 (respectivamente), o proxy tentará enviar aproximadamente o dobro do número de conexões à terceira réplica em comparação com as outras duas.
É possível usar endpoints de leitor do RDS Proxy com clusters do Aurora ou implantações de cluster de banco de dados multi-AZ do Amazon RDS com dois modos de espera legíveis. Não é possível usar endpoints de leitor do proxy em implantações de instâncias de banco de dados do Amazon RDS com réplicas de leitura.
Aprimorar a eficiência da conexão
Quando se introduz um proxy entre as aplicações-cliente e o banco de dados, o objetivo geralmente é aumentar a eficiência do tratamento de conexões e, ao mesmo tempo, considerar o custo de latência de um salto de rede adicional por meio do proxy. Uma camada intermediária adicional pode parecer insensato para melhorar a eficiência da conexão, pois qualquer conexão que tenha sido aberta diretamente no banco de dados estará aberta no proxy. As etapas de handshake de protocolo são as mesmas nos dois casos; portanto, se você ainda está gastando recursos em handshakes de conexão, talvez não esteja claro de onde provêm as melhorias de eficiência.
O proxy não necessariamente torna o estabelecimento de conexões mais barato. Em vez disso, ele move a maior parte dos encargos do tratamento de handshake da camada do banco de dados para a camada do proxy. Ao pagar pelos recursos do banco de dados, queremos que esses recursos sejam destinados ao trabalho do banco de dados e não a custos indiretos auxiliares. Isso se torna particularmente importante ao usar conexões criptografadas. Embora os custos indiretos de transmissão de dados criptografados por meio de uma conexão existente não sejam significativos, os custos indiretos iniciais de configuração de uma conexão criptografada são consideráveis. Em ambientes que geram centenas ou milhares de conexões por segundo, esse esforço extra pode aumentar rapidamente. Talvez não seja aconselhável gastar esse tempo de CPU em recursos de banco de dados (relativamente caros), mas transferi-los para a camada de proxy (comparativamente barata).
Com relação à latência introduzida por um salto de rede adicional, a importância disso depende de quão “loquaz” é a aplicação e de quantas instruções ela executa por “conversa” com o banco de dados. No RDS Proxy, normalmente se observa uma latência adicional bem abaixo de 10 milissegundos, mas isso não necessariamente causará um impacto visível nas aplicações. Por exemplo:
-
É improvável que uma workload em que os tempos de execução de consulta sejam da ordem de dezenas ou centenas de milissegundos (ou mais) perceba a sobrecarga do proxy, pois isso representa uma pequena fração do tempo total da consulta.
-
Uma aplicação que executa consultas com latência abaixo de 10 milissegundos ou inferior a um milissegundo pode notar a diferença porque a sobrecarga de consulta (um salto de rede adicional por consulta) é substancial em comparação com o tempo de execução da consulta. Talvez isso não seja um problema se uma sessão de cliente envolver apenas algumas consultas e a sobrecarga cumulativa ainda for pequena.
Se a latência adicional em sua situação for perceptível e indesejável, você deverá compará-la com os outros benefícios do uso de um proxy (agrupamento, multiplexação e tratamento de failover).
Alta disponibilidade
Os bancos de dados multi-AZ executados no Amazon RDS e no Aurora (exceto no Aurora DSQL) usam mecanismos de failover para restaurar a disponibilidade em caso de problemas com a instância do banco de dados primário. Os failovers também são usados como parte de fluxos de trabalho operacionais, como ajuste de escala da computação para a instância primária. Um failover envolve uma alteração de DNS que move o endpoint do banco de dados primário (com capacidade de leitura/gravação) da instância primária anterior para a recém-promovida. Essa alteração de DNS deve ser observada e reconhecida pelas aplicações-cliente, para que elas possam acompanhar a instância primária sem atraso.
Algumas aplicações podem ter dificuldade para reconhecer as alterações de DNS em tempo hábil devido ao armazenamento em cache de DNS no sistema operacional ou no nível da aplicação. Embora seja uma prática recomendada resolver problemas de armazenamento em cache de DNS no nível da aplicação, isso nem sempre é viável devido à complexidade da aplicação ou ao custo da inserção de alterações.
Nesse cenário, o RDS Proxy oferece uma forma eficaz para evitar atrasos de failover relacionados a DNS. Os endpoints de leitura/gravação e os endpoints opcionais somente leitura fornecidos pelo RDS Proxy são “estáveis” no sentido de que os endereços IP por trás desses endpoints não mudam quando as instâncias de banco de dados trocam suas funções. O RDS Proxy rastreia continuamente a topologia do banco de dados de backend e abstrai as alterações de função das instâncias dos clientes.
Há formas alternativas de lidar com problemas de armazenamento em cache de DNS, como usar drivers avançados inerentemente capazes de detectar a topologia do banco de dados sem depender de DNS. No entanto, pode ser mais fácil implantar um único proxy na frente do banco de dados em vez de inserir alterações no código e novos drivers no nível da aplicação.
Disponibilidade de leitura
Além de melhorar a experiência do cliente durante failovers do banco de dados, o RDS Proxy também contribui para a disponibilidade da aplicação em caso de problemas de réplica de leitura. Isso é feito de duas maneiras:
-
Se uma réplica de leitura ficar indisponível, mas houver outras réplicas disponíveis no cluster, o proxy poderá rotear novas conexões para as réplicas disponíveis. Os clientes não precisam se preocupar com atrasos de propagação de DNS ou armazenamento em cache de DNS.
-
No caso de uma conexão de cliente existente multiplexada, o proxy pode enviar consultas subsequentes dessa conexão a uma réplica diferente que esteja disponível. Nessa situação, o cliente talvez nem perceba que uma réplica de backend enfrentou um problema. Ao usar essa técnica, o RDS Proxy garante que a nova réplica não fique trás da anterior em termos de atraso na replicação. Dessa forma, as consultas subsequentes enviadas pelo cliente não verão dados que possam ser considerados obsoletos.
Usar vários proxies com um único destino
É uma prática recomendada usar um único proxy do RDS por banco de dados de destino, como uma instância do Amazon RDS ou um cluster do Aurora. Isso funciona bem na maioria dos cenários, mantém a configuração simples e torna a experiência do cliente mais previsível. Em comparação, o uso de vários proxies exige um alinhamento cuidadoso da configuração em todos os proxies para evitar comportamentos inesperados. Por exemplo, é necessário garantir que o tamanho conjunto de todos os grupos de proxies não ultrapasse os limites de conexão do único banco de dados de destino.
Você ainda pode explorar a ideia de usar vários proxies em determinadas situações. As seções a seguir discutem os cenários mais comuns e descrevem os prós e os contras de uma abordagem de proxy único versus uma abordagem de vários proxies.
Disponibilidade do proxy
A infraestrutura do RDS Proxy é altamente disponível e intencionalmente implantada em várias zonas de disponibilidade (AZs). A capacidade do proxy é distribuída em vários nós com monitoramento contínuo da integridade e ajustada automaticamente com base no tamanho da instância provisionada ou nas configurações máximas de ACU do seu banco de dados Sem Servidor v2. Devido ao design multi-AZ distribuído do proxy, não é necessário executar vários proxies na frente dos clusters do Amazon RDS ou do Aurora para ter alta disponibilidade.
Aliás, usar vários proxies na frente de um único banco de dados de destino significa que a pilha de aplicações agora é responsável por detectar e reagir aos problemas, em vez de depender dos mecanismos robustos incorporados no proxy. Consequentemente, o uso de vários proxies por motivo de alta disponibilidade é altamente desaconselhável, pois é provável que isso gere mais problemas do que soluções.
Lidar com vários grupos de clientes
Cada proxy oferece um endpoint de leitura/gravação e (opcionalmente) endpoints adicionais de leitura/gravação ou somente leitura. Quando um único proxy é usado para lidar com vários grupos de clientes ou várias workloads, essas workloads podem vir a interferir. Por exemplo, uma workload pode monopolizar o grupo de conexões até o ponto em que não haja mais conexões livres suficientes para lidar com outras workloads. O uso de proxies separados para isolar workloads pode ser uma solução atrativa, mas você pode considerar outras opções primeiro:
-
O banco de dados em si pode oferecer alternativas mais simples à execução de vários proxies. Por exemplo, se o problema for causado por determinados usuários que estão monopolizando o grupo, você poderá usar o sistema de permissões do banco de dados para limitar o número de conexões simultâneas que esses usuários podem abrir.
-
Da mesma forma, os tempos-limite de consulta no nível do banco de dados e os tempos-limite de inatividade podem resolver problemas com conexões órfãs ou consultas descontroladas.
-
Se o problema for causado pela duração da consulta ou da transação ou pelo consumo de recursos por consulta, em vez do número de conexões simultâneas, o uso de proxies adicionais não ajudará porque o proxy não impõe limites ao peso da consulta ou da transação. Se não for possível resolver o problema na origem, você poderá usar o programador de eventos do banco de dados para executar um código que detecte e encerre a atividade dos clientes com base em condições arbitrárias, em vez de mover esses clientes problemáticos para um proxy separado.
Se você decidir usar vários proxies na frente do mesmo destino, o tamanho total de todos os grupos de conexão não deverá exceder os recursos do banco de dados de destino. Por exemplo, a soma de MaxConnectionsPercent de todos os proxies deve ser menor que 100; do contrário, os proxies poderão tentar abrir mais conexões do que o banco de dados está configurado para lidar.
Cada proxy é cobrado separadamente, e a taxa de cobrança depende do tamanho dos recursos subjacentes do banco de dados e não da atividade da workload. Considere o custo de execução de vários proxies versus o custo de implementação de soluções alternativas, se houver.
Controlar grupos de leitura e gravação independentemente
Cada proxy oferece um endpoint de leitura/gravação e (opcionalmente) endpoints adicionais de leitura/gravação ou somente leitura, mas os limites e os tempos-limite são configurados para todo o proxy de destino e não individualmente para cada endpoint de proxy.
Por exemplo, você pode ter um cluster do Aurora para gerenciar um grande volume de consultas somente leitura usando várias réplicas de leitura e o endpoint de leitor do proxy, mas você quer limitar o número de conexões de leitura/gravação para reduzir a pressão de recursos sobre o gravador único. Como a configuração MaxConnectionsPercent é definida para todo o proxy de destino (cluster), não é possível limitar o número de conexões com o endpoint de leitura/gravação sem afetar também os limites do endpoint somente leitura.
Há várias maneiras de abordar esse desafio:
Você pode iniciar réplicas de leitura adicionais no cluster e reduzir proporcionalmente a configuração MaxConnectionsPercent do proxy. Isso preserva o tamanho total do grupo de conexões somente leitura e reduz o número máximo de conexões permitidas no gravador. No entanto, isso também aumenta o custo do cluster e se torna progressivamente menos eficaz quanto mais réplicas você tiver.
Você pode usar grupos de parâmetros no nível da instância para configurar os limites de conexão do banco de dados (como max_connections no Aurora MySQL ou no PostgreSQL) para as réplicas de leitura separadamente do gravador. Entretanto, você deve evitar usar a configuração assimétrica de parâmetros porque as réplicas podem ser promovidas a uma função de gravador durante um failover. Portanto, a diferenciação inicial dos parâmetros não será permanente. Você pode pensar em alterar as configurações de prioridade de failover no nível da instância para influenciar quais réplicas são selecionadas para promoção durante os failovers e usar isso como um mecanismo flexível de exclusão de failover, tornando a configuração assimétrica mais previsível. Contudo, as prioridades de failover servem apenas como dicas e não são uma garantia firme do comportamento de failover. Portanto, as configurações de várias instâncias com configurações assimétricas são desaconselhadas, pois exigem monitoramento contínuo e podem gerar um comportamento inesperado se um failover for direcionado a uma instância que você não escolheu.
Nesse cenário, usar vários proxies pode ser a maneira mais ordenada de gerenciar grupos de leitura e gravação separadamente. Você pode criar dois proxies para o único banco de dados de destino e, em seguida, configurar as aplicações para usarem o endpoint de gravador do primeiro proxy e o endpoint somente leitura do segundo proxy. Um proxy processa somente workloads de gravação, o outro lida somente com workloads de leitura e MaxConnectionsPercent (assim como outras configurações) pode ser configurado de forma independente para cada proxy. Essa solução envolve um custo adicional para executar o segundo proxy, mas é mais simples e previsível do que as alternativas anteriores.