PolarDB oferece duas políticas de balanceamento de carga para distribuir o trabalho entre vários nós somente leitura: Connections-based Load Balancing e Active Request-based Load Balancing.
Políticas de balanceamento de carga
Connections-based Load Balancing: Recomendada para cenários de alto desempenho que não exigem recursos avançados, como níveis de consistência ou divisão de transações.
Active Request-based Load Balancing: Roteia solicitações de leitura automaticamente entre vários nós somente leitura em um endpoint de cluster, com base no número de solicitações ativas. Esta política suporta recursos avançados, como níveis de consistência, divisão de transações e persistência de conexão, além de equilibrar a carga conforme o status em tempo real de cada nó.
Os endpoints de cluster do PolarDB no modo Read-only suportam tanto o Connections-based Load Balancing quanto o Active Request-based Load Balancing. Já os endpoints de cluster no modo Read/Write (Automatic Read/Write Splitting) suportam apenas o Active Request-based Load Balancing.
A tabela a seguir compara as duas políticas.
|
Nome da política |
Diferenças |
Semelhanças |
|
Connections-based Load Balancing |
|
Para um endpoint de cluster no modo Read-only, nenhuma solicitação é encaminhada ao nó primário, independentemente da política de balanceamento de carga utilizada. |
|
Active Request-based Load Balancing |
|
Nó primário aceita solicitações de leitura
Se você defina Primary Node Accepts Read Requests como No, o PolarProxy deixará de enviar solicitações regulares de leitura para o nó primário. No entanto, solicitações de leitura dentro de uma transação que exigem consistência ainda serão enviadas ao nó primário para atender aos requisitos de negócios. Além disso, se todos os nós somente leitura falharem, as solicitações de leitura também serão direcionadas ao nó primário. Caso seus negócios tenham baixos requisitos de consistência, defina o nível de consistência como consistência eventual para reduzir as solicitações de leitura no nó primário. Também é possível utilizar o recurso de divisão de transações para diminuir as solicitações de leitura enviadas ao nó primário antes do início efetivo da transação. Solicitações de broadcast, como SET ou PREPARE, continuam sendo enviadas ao nó primário.
A configuração Primary Node Accepts Read Requests só pode ser ajustada quando o modo Read/Write estiver definido como Read/Write (Automatic Read/Write Splitting). Para obter informações sobre como modifique a configuração Primary Node Accepts Read Requests, consulte Configurar o PolarProxy.
Se a versão do seu PolarProxy for 1.x.x ou 2.5.1 ou posterior, as alterações na configuração Primary Node Accepts Read Requests entrarão em vigor imediatamente.
Caso sua versão do PolarProxy seja 2.x.x e anterior à 2.5.1, as alterações na configuração Primary Node Accepts Read Requests só terão efeito após o restabelecimento das conexões persistentes. Para conexões de curta duração, as mudanças entram em vigor imediatamente.
Divisão de transações
Ao utilizar um endpoint de cluster do PolarDB no modo Read/Write (Automatic Read/Write Splitting), o PolarProxy distribui as solicitações de leitura e escrita entre o nó primário e os nós somente leitura. Para garantir a consistência transacional dentro de uma sessão, o PolarProxy envia todas as solicitações em transação para o nó primário. Por exemplo, alguns drivers de cliente de banco de dados, como JDBC, encapsulam solicitações em transações por padrão. Consequentemente, todas as solicitações da aplicação são enviadas ao nó primário, o que pode resultar em alta carga nesse nó enquanto os nós somente leitura permanecem subutilizados, conforme ilustrado na figura a seguir:
Para resolver essa questão, o PolarDB fornece o recurso de divisão de transações no nível de isolamento Read Committed. Esse recurso envia solicitações de leitura dentro de uma transação para os nós somente leitura, reduzindo a carga no nó primário e mantendo a consistência de leitura/escrita para seus serviços. É possível transferir a pressão de leitura do nó primário para os nós somente leitura e melhorar a estabilidade do nó primário sem alterar o código ou as configurações da sua aplicação. Para obter instruções detalhadas sobre como ative a divisão de transações, consulte Configurar o PolarProxy.
O PolarDB for MySQL oferece dois níveis de divisão de transações: Read request splitting before first write request (padrão, o recurso original de divisão de transações) e Full transaction splitting (read request splitting before and after first write request).
-
Read request splitting before first write request
O PolarProxy envia as solicitações de leitura que antecedem a primeira solicitação de escrita em uma transação para os nós somente leitura, o que reduz a carga no nó primário.
-
Full transaction splitting (read request splitting before and after first write request)
Com a divisão de solicitações de leitura antes da primeira escrita, as leituras que ocorrem após uma escrita ainda são roteadas para o nó primário, podendo causar desequilíbrio de carga. Para solucionar completamente os problemas de balanceamento causados por transações, o PolarDB for MySQL introduziu a divisão completa de transações. Este recurso permite rotear todas as operações de leitura dentro de uma transação para nós somente leitura, garantindo resultados corretos e aliviando ainda mais a pressão sobre o nó primário.
Uma solicitação de leitura após escrita só pode ser roteada para um nó somente leitura se os dados da operação de escrita anterior na transação já tiverem sido sincronizados com esse nó. Se você configure a consistência de sessão, o PolarProxy verifica primeiro se o nó somente leitura da sessão atual sincronizou as escritas anteriores antes de rotear a solicitação de leitura após escrita. Em caso afirmativo, a solicitação vai para o nó somente leitura; caso contrário, é enviada ao nó primário. Da mesma forma, se a consistência global estiver configurada, o PolarProxy verifica se as transações de todas as sessões atuais foram sincronizadas com o nó somente leitura. Se sim, a solicitação é roteada para lá; senão, segue para o nó primário. A divisão completa de transações não suporta consistência eventual.
Versões e limitações
Para utilizar o recurso de divisão completa de transações, seu cluster PolarDB for MySQL deve atender aos seguintes requisitos:
-
**Versão do mecanismo**:
PolarDB for MySQL 5.6, revisão 5.6.1.0.29 ou posterior.
PolarDB for MySQL 5.7, revisão 5.7.1.0.9 ou posterior.
PolarDB for MySQL 8.0.1, revisão 8.0.1.1.18 ou posterior.
PolarDB for MySQL 8.0.2, qualquer revisão.
-
Parâmetro do mecanismo:
O parâmetro
loose_query_cache_typedeve estar definido como OFF. O PolarDB for MySQL 5.6, 5.7 e 8.0.1 usam OFF por padrão. A versão 8.0.2 usa ON por padrão. A alteração desse parâmetro exige a reinicialização do cluster PolarDB.
NotaA divisão de transações é suportada apenas para sessões no nível de isolamento Read Committed e está ativada por padrão.
Devido às restrições de consistência de leitura/escrita, as solicitações de leitura não são roteadas para um nó somente leitura se o nível de consistência dele não atender aos requisitos.
Se a versão do seu PolarProxy for anterior à 2.4.14, apenas a divisão de solicitações de leitura antes da primeira escrita é suportada. Não há suporte para divisão completa de transações.
Caso sua versão do PolarProxy seja 2.4.14 ou posterior e a divisão de transações esteja configurada como divisão completa, será necessário restabelecer as conexões persistentes para que a alteração tenha efeito. Para conexões de curta duração, a mudança entra em vigor imediatamente.
-
-
Desativar a divisão de transações
Quando a divisão de transações está desativada, todas as solicitações dentro de uma transação são roteadas para o nó primário.
Balanceamento de carga baseado em peso
Por padrão, o PolarProxy do PolarDB for MySQL roteia solicitações para o nó com o menor número de solicitações ativas (concorrentes). Essa política geralmente equilibra o tráfego entre os nós de backend com base na carga de cada um. Ela também apresenta bom desempenho quando os nós de backend possuem especificações diferentes. No entanto, as cargas de trabalho de produção e os requisitos de distribuição de tráfego variam.
Para atender melhor a essas necessidades, o PolarDB for MySQL introduziu o balanceamento de carga baseado em peso. É possível configure pesos diferentes para cada nó. Durante o processo de roteamento, tanto o peso quanto o número de solicitações simultâneas são usados como critérios para ajustar dinamicamente a decisão final de roteamento. Atualmente, os pesos podem ser configurados nos dois níveis a seguir:
-
Dimensão global
Esta configuração aplica-se a todos os endpoints.
-
Dimensão do endpoint
O peso na dimensão do endpoint aplica-se apenas ao balanceamento de carga desse endpoint específico e substitui a configuração global. Por exemplo, se você configure primeiro um peso na dimensão global e depois defina um peso separado para um endpoint específico, o balanceamento de carga para esse endpoint seguirá a configuração de nível de endpoint.
Notes
Este recurso requer o PolarProxy 2.8.3 ou posterior.
Como a política de roteamento considera tanto a carga atual do nó quanto o peso definido pelo usuário, a proporção geral de tráfego pode apresentar um leve desvio em relação à proporção configurada. Com o tempo, ela convergirá gradualmente para a proporção definida.
Clusters Serverless não suportam configuração de peso na dimensão do endpoint.
Como funciona
Durante o processo de roteamento de solicitações, o peso final de cada nó é calculado dinamicamente com base no peso configurado e no número atual de solicitações simultâneas no nó. A fórmula simplificada é a seguinte:
Peso dinâmico = Peso configurado / Número de solicitações simultâneas
Quanto maior o peso dinâmico, maior a prioridade do nó. A política de balanceamento de carga por peso dinâmico oferece um método de roteamento flexível. Na prática, o tráfego muda gradualmente de acordo com os pesos configurados, o que pode levar mais tempo do que uma abordagem simples de round-robin ponderado.
Procedimento
Inicialmente, cada nó de backend possui o mesmo peso padrão de 1.
O intervalo configurável para pesos varia de 0 a 100.
Quando um peso é definido como 0, o PolarProxy não roteia solicitações para esse nó em circunstâncias normais. O nó só será selecionado se todos os outros estiverem indisponíveis.
Se um cluster tiver apenas um nó de armazenamento de colunas somente leitura, seu peso pode ser ignorado. Caso o cluster possua múltiplos nós de armazenamento de colunas somente leitura, as solicitações de column-store serão balanceadas com base nos pesos desses nós.
Configure pesos na dimensão global
Faça login no console do PolarDB.
No canto superior esquerdo, selecione a região onde o cluster está implantado.
Localize o cluster desejado e clique em seu ID.
Na página Basic Information, na seção Standard Enterprise Edition ou Dedicated Enterprise Edition, clique em Database Proxy Settings.
-
Na caixa de diálogo Database Proxy Settings, defina um peso para cada nó conforme as necessidades do seu negócio.
A caixa de diálogo exibe a Role de cada nó (nó primário ou somente leitura) e uma caixa de entrada Weight. Uma mensagem no topo indica que as decisões de roteamento são ajustadas dinamicamente com base tanto nos pesos quanto nas solicitações simultâneas. Após concluir a definição dos pesos, clique em OK.
Após configure os pesos, clique em OK.
Configure pesos na dimensão do endpoint
Faça login no console do PolarDB.
No canto superior esquerdo, selecione a região onde o cluster está implantado.
Localize o cluster desejado e clique em seu ID.
Na página Basic Information, na seção Standard Enterprise Edition ou Dedicated Enterprise Edition, clique em Configure no canto superior direito do endpoint de cluster ou endpoint personalizado.
-
Na página Modify Endpoint Settings, na área de nós de serviço, ative a opção Configure Node Weight e defina um peso para cada nó.
Mova o nó alvo, como um nó de armazenamento de colunas somente leitura, da lista Available Nodes para a lista Selected Nodes. Em seguida, defina um peso para o nó selecionado, como
1, e clique em OK. Após defina os pesos, clique em OK.
Dados de teste
Abaixo estão os dados reais de teste após a configuração dos pesos dos nós.
A proporção de peso dos três nós utilizados no teste é de 1:2:3 (o nó primário tem peso 1). Os resultados do teste de estresse atenderam às expectativas (utilizando o conjunto de testes oltp_read_only do Sysbench).

Os dois nós internos, pi-bp1d1mtcobuzv e pcbp14vvpolardbma23957, não participam do roteamento, portanto suas métricas podem ser ignoradas.
Conexões sob demanda
Contexto
Para endpoints que utilizam o Active Request-based Load Balancing, o PolarProxy cria conexões completas por padrão. Depois que uma sessão de cliente é estabelecida através do PolarProxy, ele cria uma sessão (conexão) com todos os nós de banco de dados dentro daquele endpoint, gerando uma relação de conexão 1:N. As solicitações normais de leitura nessa sessão são roteadas para vários nós de banco de dados com base na carga ativa atual, enquanto as solicitações de broadcast (como instruções SET) são enviadas para todos os nós de banco de dados. Quando há muitos nós de banco de dados, a eficiência geral é significativamente reduzida devido à sobrecarga de estabelecimento de conexões e broadcasting.
Como funciona
Com as conexões sob demanda, o PolarProxy estabelece conexões com os bancos de dados de backend apenas conforme necessário. Ele minimiza o número de conexões de backend enquanto atende aos requisitos de consistência e carga de leitura/escrita. Isso reduz a sobrecarga do banco de dados causada pelas conexões de proxy e pela execução de broadcasts. Na maioria dos casos, uma sessão estabelece conexões com, no máximo, um nó primário e um nó somente leitura (assumindo consistência eventual). Isso pode melhorar significativamente o desempenho para conexões de curta duração ou cargas de trabalho com muitas instruções de broadcast.
Conforme mostrado na figura acima, suponha que um cluster PolarDB tenha um nó primário (RW) e três nós somente leitura (RO). Se a consistência não for um fator, a eficiência de roteamento de solicitações e leitura de dados nos três cenários é a seguinte:
-
Conexões completas
Uma única sessão de usuário através do PolarProxy estabelece conexões com todos os quatro nós de banco de dados, e as instruções de broadcast são roteadas para todos os quatro nós.
-
Conexões sob demanda, sessão somente leitura
Uma única sessão de usuário através do PolarProxy estabelece conexão com apenas um nó RO. As solicitações de leitura (incluindo broadcasts) são roteadas apenas para este único nó RO, melhorando significativamente a eficiência de leitura de dados.
-
Conexões sob demanda, sessão de leitura/escrita
Uma única sessão de usuário através do PolarProxy estabelece conexões com apenas um nó RO e um nó RW. As solicitações de broadcast são roteadas apenas para esses dois nós de banco de dados, o que também melhora significativamente a eficiência de leitura de dados.
Casos de uso
Clusters com um grande número de nós RO.
Conexões de curta duração.
Cenários com muitas instruções de broadcast (por exemplo, em cenários de conexão de curta duração com PHP, a primeira instrução de uma sessão costuma ser semelhante a
set names utf8mb4).Cargas de trabalho com muitas consultas que utilizam instruções PREPARE curtas.
Limitações
É necessário o PolarProxy 2.8.34 ou posterior. Para obter instruções sobre como verificar a versão do PolarProxy do seu cluster, consulte Verificar o número da versão.
Ao usar
SHOW PROCESSLISTSpara visualize o número de conexões de banco de dados, o comando pode não exibir o número total de conexões com todos os bancos de dados.Ao utilizar o comando KILL para encerrar uma conexão específica, o comando pode não encerrar a conexão especificada em todos os bancos de dados.
Teste de desempenho
Ambiente de teste
Nós de banco de dados: um nó de leitura/escrita (RW), sete nós somente leitura (RO)
SQL utilizado para teste:
SET NAMES utf8mb4,SELECT 1Ferramenta de teste: Sysbench, com o mesmo número de conexões simultâneas para cada teste
Cenários de teste: O teste abrangeu três cenários: sem pool de conexões, com pool de conexões no nível de sessão e com pool de conexões no nível de transação. Cada teste foi dividido em duas partes: a primeira metade sem conexões sob demanda ativadas e a segunda metade com conexões sob demanda ativadas.
Resultados do teste
-
Resultados do teste de desempenho para o cenário sem pool de conexões:
-
A figura abaixo mostra o consumo de CPU dos nós de banco de dados. Após ative as conexões sob demanda, o consumo de CPU do banco de dados diminuiu em mais de 60%:

-
A figura abaixo mostra a variação no número total de conexões com os nós de banco de dados. Após ative as conexões sob demanda, o número total de conexões diminuiu em mais de 80%:

-
A figura abaixo mostra a variação no QPS geral. Após ative as conexões sob demanda, o QPS geral aumentou em 35%:

-
-
Resultados do teste de desempenho para o cenário com pool de conexões no nível de sessão:
-
A figura abaixo mostra o consumo de CPU dos nós de banco de dados. Após ative as conexões sob demanda, o consumo de CPU do banco de dados diminuiu entre 50% e 60%:

-
A figura abaixo mostra a variação no número total de conexões com os nós de banco de dados. Após ative as conexões sob demanda, o número total de conexões diminuiu em 60%:

-
A figura abaixo mostra a variação no QPS geral. Após ative as conexões sob demanda, o QPS aumentou em 30%:

-
-
Resultados do teste de desempenho para o cenário com pool de conexões no nível de transação:
-
A figura abaixo mostra o consumo de CPU dos nós de banco de dados. Após ative as conexões sob demanda, o consumo de CPU do banco de dados diminuiu em 60%:

-
A figura abaixo mostra a variação no número total de conexões com os nós de banco de dados. Após ative as conexões sob demanda, o número total de conexões diminuiu em 50%:

-
A figura abaixo mostra a variação no QPS geral. Após ative as conexões sob demanda, o QPS aumentou em 260%:

-