Si le trafic des requêtes se concentre sur une seule instance Hologres, vous risquez de la surcharger et de compromettre sa disponibilité en cas de défaillance. En indiquant plusieurs endpoints d'instances secondaires en lecture seule dans une seule URL de connexion JDBC, Hologres répartit aléatoirement le trafic entre les instances et tente automatiquement d'autres endpoints si l'un devient inaccessible.
Cette fonctionnalité est disponible à partir de Hologres V1.3.
Fonctionnement
Une instance principale Hologres peut être associée à plusieurs instances secondaires en lecture seule. Les instances partagent le stockage, mais leurs ressources de calcul sont isolées, formant ainsi un déploiement à haute disponibilité (HA) avec séparation lecture/écriture. Pour plus d'informations, consultez Instances principales et secondaires avec séparation lecture/écriture (stockage partagé).
Lorsque vous indiquez plusieurs endpoints dans l'URL de connexion, JDBC adopte deux comportements :
Répartition aléatoire : lorsque
loadBalanceHosts=true, JDBC sélectionne aléatoirement parmi les endpoints répertoriés et distribue les connexions entre les instances.Basculement séquentiel : si une tentative de connexion à un endpoint échoue, JDBC tente automatiquement l'endpoint suivant dans l'URL. JDBC ne signale une erreur de connexion que si tous les endpoints répertoriés sont inaccessibles.
JDBC détermine si une instance est principale ou secondaire en lecture seule en vérifiant le paramètre Grand Unified Configuration (GUC) in_hot_standby : off signifie qu'il s'agit d'une instance principale, tandis que on indique une instance secondaire en lecture seule. Ce mécanisme permet à targetServerType de router les connexions selon le rôle de l'instance.

Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Plusieurs instances secondaires en lecture seule Hologres associées à une instance principale. Consultez Configurer des instances principales et secondaires utilisant un stockage partagé
Le pilote PostgreSQL JDBC version 42.3.2 ou ultérieure. Consultez JDBC
Configurer l'équilibrage de charge dans l'URL de connexion
Indiquez tous les endpoints des instances dans l'URL de connexion, séparés par des virgules. L'exemple suivant présente la configuration recommandée pour un équilibrage de charge aléatoire avec un cache d'endpoints de 10 secondes :
jdbc:postgresql://<Endpoint1>:<Port1>,<Endpoint2>:<Port2>,<Endpoint3>:<Port3>/<DBNAME>?user=<AccessKey ID>&password=<AccessKey secret>&targetServerType=any&loadBalanceHosts=true&hostRecheckSeconds=10
Le tableau suivant décrit chaque paramètre.
| Paramètre | Description |
|---|---|
Endpoint |
L'adresse réseau de l'instance Hologres. Retrouvez cette information sur la page Instance Details de la console Hologres. |
Port |
Le port de l'instance Hologres. Retrouvez cette information sur la page Instance Details de la console Hologres. |
DBNAME |
Le nom de la base de données à laquelle se connecter. |
user |
Votre AccessKey ID. Retrouvez-le sur la page AccessKey Management. |
password |
Votre AccessKey secret. Retrouvez-le sur la page AccessKey Management. |
targetServerType |
Contrôle les types d'instances qui acceptent les connexions. Valeurs prises en charge : any se connecte à n'importe quel endpoint répertorié. Les valeurs suivantes nécessitent Hologres V2.0.10 ou une version ultérieure : master (instance principale uniquement), slave (instances secondaires en lecture seule uniquement), preferSlave (instances secondaires en lecture seule en priorité ; bascule vers l'instance principale si la connexion à une instance secondaire en lecture seule échoue). |
loadBalanceHosts |
Contrôle l'ordre de connexion. true : sélectionne aléatoirement parmi les endpoints répertoriés pour répartir la charge entre les instances. false (par défaut) : tente les endpoints dans l'ordre indiqué. Définissez ce paramètre sur true pour la plupart des scénarios d'équilibrage de charge. |
hostRecheckSeconds |
Durée de mise en cache de la liste des endpoints accessibles par JDBC, en secondes. Par défaut : 10. Pour modifier la durée du cache, ajustez la valeur du paramètre hostRecheckSeconds. |
Pour obtenir la liste complète des options de configuration PostgreSQL JDBC, consultez la documentation JDBC .
Exemples
Équilibrage de charge aléatoire entre trois instances secondaires en lecture seule
Connectez-vous à trois instances secondaires en lecture seule avec une répartition aléatoire (loadBalanceHosts=true, targetServerType=any). Lorsqu'une instance est indisponible, JDBC tente automatiquement les autres 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();
}
}
}
Interrogation alternée entre une instance principale et une instance secondaire en lecture seule
Envoyez 100 requêtes réparties entre une instance principale et une instance secondaire en lecture seule. Avec loadBalanceHosts=true, JDBC répartit aléatoirement les connexions, de sorte que le nombre de connexions sur les deux instances devrait être approximativement égal après l'exécution des requêtes.
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++;
}
}
}
Pour vérifier la répartition, consultez le nombre de connexions sur chaque instance dans le tableau de bord de surveillance. Les comptes doivent être approximativement égaux. Pour plus de détails, consultez Afficher les métriques de surveillance.
Métriques de surveillance pour l'instance hgpostcn-cn-wxxxxxxxx04.

Métriques de surveillance pour l'instance hgpostcn-cn-wxxxxxxxx05.
