Quando o tráfego de consultas se concentra em uma única instância do Hologres, há risco de sobrecarga e perda de disponibilidade caso essa instância falhe. Ao listar vários endpoints de instâncias secundárias somente leitura em uma única URL de conexão JDBC, o Hologres distribui o tráfego de consultas aleatoriamente entre as instâncias e tenta automaticamente outros endpoints quando um deles se torna inacessível.
Esse recurso está disponível a partir do Hologres V1.3.
Como funciona
Uma instância primária do Hologres pode ter várias instâncias secundárias somente leitura associadas. Essas instâncias compartilham armazenamento, mas possuem recursos de computação isolados, formando uma implantação de alta disponibilidade (HA) com separação de leitura e escrita. Para mais informações, consulte Instâncias primárias e secundárias com separação de leitura e escrita (armazenamento compartilhado).
Ao listar múltiplos endpoints na URL de conexão, o JDBC oferece dois comportamentos:
Distribuição aleatória: Com
loadBalanceHosts=true, o JDBC seleciona aleatoriamente os endpoints listados e distribui as conexões entre as instâncias.Failover sequencial: Se a tentativa de conexão com um endpoint falhar, o JDBC tenta automaticamente o próximo endpoint da URL. O sistema reporta falha de conexão apenas se todos os endpoints listados estiverem inacessíveis.
O JDBC determina se uma instância é primária ou secundária somente leitura ao verificar o parâmetro Grand Unified Configuration (GUC) in_hot_standby: off indica instância primária; on indica instância secundária somente leitura. Esse mecanismo permite que targetServerType direcione o tráfego com base na função da instância.

Pré-requisitos
Antes de começar, verifique se você possui:
Várias instâncias secundárias somente leitura do Hologres associadas a uma instância primária. Consulte Configure instâncias primárias e secundárias com armazenamento compartilhado
Driver JDBC do PostgreSQL versão 42.3.2 ou posterior. Consulte JDBC
Configure o balanceamento de carga na URL de conexão
Liste todos os endpoints das instâncias na URL de conexão, separados por vírgulas. O exemplo a seguir mostra a configuração recomendada para balanceamento de carga aleatório com cache de endpoint de 10 segundos:
jdbc:postgresql://<Endpoint1>:<Port1>,<Endpoint2>:<Port2>,<Endpoint3>:<Port3>/<DBNAME>?user=<AccessKey ID>&password=<AccessKey secret>&targetServerType=any&loadBalanceHosts=true&hostRecheckSeconds=10
A tabela a seguir descreve cada parâmetro.
|
Parâmetro |
Descrição |
|
|
Endereço de rede da instância do Hologres. Obtenha essa informação na página Instance Details no console do Hologres. |
|
|
Porta da instância do Hologres. Disponível também na página Instance Details do console do Hologres. |
|
|
Nome do banco de dados ao qual se conectar. |
|
|
Seu AccessKey ID. Disponível em Gerencie AccessKey. |
|
|
Seu AccessKey secret. Também obtido em Gerencie AccessKey. |
|
|
Define quais tipos de instância aceitam conexões. Valores suportados: |
|
|
Controla a ordem de conexão. |
|
|
Tempo, em segundos, durante o qual o JDBC mantém em cache a lista de endpoints acessíveis. Padrão: |
Para a lista completa de opções de configuração do JDBC para PostgreSQL, consulte a documentação do JDBC .
Exemplos
Balanceamento de carga aleatório entre três instâncias secundárias somente leitura
Conecte-se a três instâncias secundárias somente leitura com distribuição aleatória (loadBalanceHosts=true, targetServerType=any). Caso uma instância fique indisponível, o JDBC tentará automaticamente os demais endpoints.
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class hatest {
public static void main(String[] args) {
// Read-only secondary instance 1
String endpoint1 = "hgpostcn-cn-wxxxxxxxx01-cn-shanghai.hologres.aliyuncs.com:80";
// Read-only secondary instance 2
String endpoint2 = "hgpostcn-cn-wxxxxxxxx02-cn-shanghai.hologres.aliyuncs.com:80";
// Read-only secondary instance 3
String endpoint3 = "hgpostcn-cn-wxxxxxxxx03-cn-shanghai.hologres.aliyuncs.com:80";
String dbname = "postgres";
String jdbcUrl = "jdbc:postgresql://" + endpoint1 + "," + endpoint2 + "," + endpoint3 + "/" + dbname;
Properties properties = new Properties();
properties.setProperty("user", "xxxx");
properties.setProperty("password", "xxxx");
// any: connect to any listed endpoint regardless of instance role
properties.setProperty("targetServerType", "any");
// true: randomly select from listed endpoints to distribute load
properties.setProperty("loadBalanceHosts", "true");
// Cache reachable endpoints for 10 seconds before rechecking
properties.setProperty("hostRecheckSeconds", "10");
try {
Class.forName("org.postgresql.Driver");
Connection connection = DriverManager.getConnection(jdbcUrl, properties);
PreparedStatement preparedStatement = connection.prepareStatement("show hg_frontend_endpoints;");
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
ResultSetMetaData rsmd = resultSet.getMetaData();
int columnCount = rsmd.getColumnCount();
Map map = new HashMap();
for (int i = 0; i < columnCount; i++) {
map.put(rsmd.getColumnName(i + 1).toLowerCase(), resultSet.getObject(i + 1));
}
System.out.println(map);
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
Distribuição entre instância primária e secundária somente leitura
Envie 100 consultas distribuídas entre uma instância primária e uma instância secundária somente leitura. Com loadBalanceHosts=true, o JDBC distribui as conexões aleatoriamente. Assim, a contagem de conexões em ambas as instâncias deve ser aproximadamente igual após a execução das consultas.
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class hatest {
public static void main(String[] args) {
int x = 1;
while (x <= 100) {
// Primary instance
String endpoint1 = "hgpostcn-cn-wxxxxxxxx04-cn-hangzhou.hologres.aliyuncs.com:80";
// Read-only secondary instance
String endpoint2 = "hgpostcn-cn-wxxxxxxxx05-cn-hangzhou.hologres.aliyuncs.com:80";
String dbname = "postgres";
String jdbcUrl = "jdbc:postgresql://" + endpoint1 + "," + endpoint2 + "/" + dbname;
Properties properties = new Properties();
properties.setProperty("user", "xxx");
properties.setProperty("password", "xxx");
// any: connect to any listed endpoint regardless of instance role
properties.setProperty("targetServerType", "any");
// true: randomly select from listed endpoints to distribute load
properties.setProperty("loadBalanceHosts", "true");
// Cache reachable endpoints for 10 seconds before rechecking
properties.setProperty("hostRecheckSeconds", "10");
try {
Class.forName("org.postgresql.Driver");
Connection connection = DriverManager.getConnection(jdbcUrl, properties);
PreparedStatement preparedStatement = connection.prepareStatement("show hg_frontend_endpoints;");
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
ResultSetMetaData rsmd = resultSet.getMetaData();
int columnCount = rsmd.getColumnCount();
Map map = new HashMap();
for (int i = 0; i < columnCount; i++) {
map.put(rsmd.getColumnName(i + 1).toLowerCase(), resultSet.getObject(i + 1));
}
System.out.println(map);
}
} catch (Exception exception) {
exception.printStackTrace();
}
x++;
}
}
}
Para verificar a distribuição, confira a contagem de conexões de cada instância no painel de monitoramento. Os valores devem ser aproximadamente iguais. Consulte Visualize métricas de monitoramento para mais detalhes.
Métricas de monitoramento da instância hgpostcn-cn-wxxxxxxxx04.

Métricas de monitoramento da instância hgpostcn-cn-wxxxxxxxx05.
