Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Configuration du client Lettuce (Valkey et Redis OSS)
Cette section décrit les options de configuration recommandées pour Java et Lettuce, ainsi que leur application aux ElastiCache clusters.
Les recommandations de cette section ont été testées avec la version 6.2.2 de Lettuce.
Rubriques
TTL du cache DNS de Java
La machine virtuelle Java (JVM) met en cache les recherches de nom DNS. Lorsque la JVM convertit un nom d'hôte en adresse IP, elle met l'adresse IP en cache pendant une période spécifiée, connue sous le nom de time-to-live(TTL).
Le choix d'une valeur TTL est un compromis entre la latence et la réactivité au changement. Avec une valeur plus courte TTLs, les résolveurs DNS détectent plus rapidement les mises à jour du DNS du cluster. Cela peut permettre à votre application de réagir plus rapidement aux remplacements ou à d'autres flux de travail auxquels votre cluster est soumis. Toutefois, si la TTL est trop faible, le volume de requêtes augmente, ce qui peut accentuer la latence de votre application. Bien qu'il n'y ait pas de valeur TTL correcte, lorsque vous la configurez, vous pouvez déterminer le délai d'attente maximal avant qu'une modification prenne effet.
Comme ElastiCache les nœuds utilisent des entrées de nom DNS susceptibles de changer, nous vous recommandons de configurer votre JVM avec un TTL faible de 5 à 10 secondes. Ainsi, lorsque l’adresse IP d’un nœud change, votre application peut recevoir et utiliser la nouvelle adresse IP de la ressource en interrogeant l’entrée DNS.
Dans certaines configurations Java, la durée de vie par défaut de la JVM est définie de façon à ce que la JVM n'actualise jamais les entrées DNS tant qu'elle n'est pas redémarrée.
Pour plus de détails sur la façon de définir la durée de vie de votre JVM, consultez Comment définir la durée de vie de la JVM.
Version de Lettuce
Nous recommandons Lettuce version 6.2.2 ou ultérieure.
Points de terminaison
Lorsque vous utilisez des clusters activés en mode cluster, définissez redisUri
sur le point de terminaison de configuration du cluster. La recherche DNS pour cet URI renvoie une liste de tous les nœuds disponibles dans le cluster et est résolue de manière aléatoire vers l'un d'entre eux lors de l'initialisation du cluster. Pour plus de détails sur le fonctionnement de l'actualisation topologique, reportez-vous à la section dynamicRefreshResourcessuivante de cette rubrique.
SocketOption
Activez KeepAlive
Assurez-vous de définir le Délai de connexion
ClusterClientOption: options client activées en mode cluster
Activez AutoReconnect
Configurez CommandTimeout
Définissez nodeFilter
Par exemple, une fois qu'un basculement est terminé et que le cluster démarre le processus de restauration, alors que la topologie du cluster est actualisée, la carte des nœuds de bus du cluster indique brièvement que le nœud inférieur est listé en tant que nœud FAIL, avant qu'il ne soit entièrement supprimé de la topologie. Pendant cette période, le client Lettuce considère qu'il s'agit d'un nœud sain et s'y connecte en permanence. Cela provoque un échec une fois que les nouvelles tentatives sont épuisées.
Par exemple :
final ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder() ... // other options .nodeFilter(it -> ! (it.is(RedisClusterNode.NodeFlag.FAIL) || it.is(RedisClusterNode.NodeFlag.EVENTUAL_FAIL) || it.is(RedisClusterNode.NodeFlag.HANDSHAKE) || it.is(RedisClusterNode.NodeFlag.NOADDR))) .validateClusterNodeMembership(false) .build(); redisClusterClient.setOptions(clusterClientOptions);
Note
Il est préférable d'utiliser le filtrage des nœuds lorsqu'il est DynamicRefreshSources défini sur true. Sinon, si la vue topologique provient d'un seul nœud source problématique, qui constate la défaillance d'un nœud primaire d'une partition, elle filtrera ce nœud primaire et les emplacements ne seront donc pas couverts. Le fait d'avoir plusieurs nœuds de départ (lorsque DynamicRefreshSources c'est vrai) réduit le risque de ce problème, car au moins certains nœuds de départ devraient avoir une vue topologique mise à jour après un basculement avec le nœud principal récemment promu.
ClusterTopologyRefreshOptions: Options permettant de contrôler l'actualisation de la topologie du cluster du client activé en mode cluster
Note
Les clusters en mode cluster désactivé ne prennent pas en charge les commandes de découverte de clusters et ne sont pas compatibles avec toutes les fonctionnalités de découverte de topologie dynamique de clients.
Le mode cluster désactivé ElastiCache n'est pas compatible avec LettuceMasterSlaveTopologyRefresh
. Au lieu de cela, pour le mode cluster désactivé, vous pouvez configurer un StaticMasterReplicaTopologyProvider
et fournir les points de terminaison de lecture et d'écriture du cluster.
Pour plus d'informations sur la connexion à des clusters en mode cluster désactivé, veuillez consulter Trouver les points de terminaison d'un cluster Valkey ou Redis OSS (mode cluster désactivé) (console).
Si vous souhaitez utiliser la fonctionnalité de découverte de topologie dynamique de Lettuce, vous pouvez créer un cluster en mode cluster activé avec la même configuration de partitions que votre cluster existant. Toutefois, pour les clusters en mode cluster activé, nous vous recommandons de configurer au moins 3 partitions avec au moins 1 réplica pour prendre en charge un basculement rapide.
Activez enablePeriodicRefresh
Lorsque cette option est activée, vous pouvez réduire la latence associée à l'actualisation de la topologie du cluster en ajoutant cette tâche à une tâche en arrière-plan. Bien que l'actualisation de la topologie soit effectuée en arrière-plan, elle peut être quelque peu lente pour les clusters comportant de nombreux nœuds. Cela est dû au fait que tous les nœuds sont interrogés afin de connaître leurs vues et d'obtenir la vue de cluster la plus récente. Si vous gérez un cluster de grande taille, vous souhaiterez peut-être augmenter la période.
Activez enableAllAdaptiveRefreshTriggers
Activez closeStaleConnections
Activez dynamicRefreshResources
L'actualisation dynamique interroge tous les nœuds détectés pour la topologie du cluster et tente de choisir la vue de cluster la plus précise. S'il est défini sur false, seuls les nœuds de départ initiaux sont utilisés comme sources pour la détection de la topologie, et le nombre de clients est obtenu uniquement pour les nœuds de départ initiaux. Lorsqu'il est désactivé, si le point de terminaison de la configuration du cluster est résolu en un nœud défaillant, la tentative d'actualisation de la vue du cluster échoue et entraîne des exceptions. Ce scénario peut se produire, car il faut un certain temps pour que l’entrée d’un nœud défaillant soit supprimée du point de terminaison de configuration du cluster. Par conséquent, le point de terminaison de la configuration peut toujours être résolu de manière aléatoire et brève en un nœud défaillant.
Cependant, lorsqu'il est activé, nous utilisons tous les nœuds de cluster reçus depuis la vue du cluster pour demander leur vue actuelle. Étant donné que nous éliminons les nœuds défaillants de cette vue, l'actualisation de la topologie sera réussie. Toutefois, lorsque dynamicRefreshSources c'est vrai, Lettuce interroge tous les nœuds pour obtenir la vue du cluster, puis compare les résultats. L'opération peut donc être coûteuse pour les clusters comportant un grand nombre de nœuds. Nous vous suggérons de désactiver cette fonctionnalité pour les clusters comportant de nombreux nœuds.
final ClusterTopologyRefreshOptions topologyOptions = ClusterTopologyRefreshOptions.builder() .enableAllAdaptiveRefreshTriggers() .enablePeriodicRefresh() .dynamicRefreshSources(true) .build();
ClientResources
Configurez DnsResolver
Configurez reconnectDelay
ClientResources clientResources = DefaultClientResources.builder() .dnsResolver(new DirContextDnsResolver()) .reconnectDelay( Delay.fullJitter( Duration.ofMillis(100), // minimum 100 millisecond delay Duration.ofSeconds(10), // maximum 10 second delay 100, TimeUnit.MILLISECONDS)) // 100 millisecond base .build();
Délais
Utilisez une valeur de délai de connexion inférieure à celle de votre commande. Lettuce utilise l'établissement d'une connexion différée. Ainsi, si le délai d'expiration de la connexion est supérieur à celui de la commande, vous pouvez connaître des échecs persistants après une actualisation de la topologie, si Lettuce essaie de se connecter à un nœud défectueux et si le délai de la commande est toujours dépassé.
Utilisez un délai de commande dynamique pour différentes commandes. Nous vous recommandons de définir le délai de commande en fonction de la durée attendue de la commande. Par exemple, utilisez un délai plus long pour les commandes qui itèrent sur plusieurs clés, comme les scripts FLUSHDB, FLUSHALL, KEYS, SMEMBERS ou Lua. Utilisez des délais plus courts pour les commandes à clé unique, telles que SET, GET et HSET.
Note
Les délais configurés dans l'exemple suivant concernent les tests qui ont exécuté des commandes SET/GET avec des clés et des valeurs d'une longueur maximale de 20 octets. Le temps de traitement peut être supérieur lorsque les commandes sont complexes ou que les clés et les valeurs sont plus grandes. Vous devez définir les délais en fonction du cas d'utilisation de votre application.
private static final Duration META_COMMAND_TIMEOUT = Duration.ofMillis(1000); private static final Duration DEFAULT_COMMAND_TIMEOUT = Duration.ofMillis(250); // Socket connect timeout should be lower than command timeout for Lettuce private static final Duration CONNECT_TIMEOUT = Duration.ofMillis(100); SocketOptions socketOptions = SocketOptions.builder() .connectTimeout(CONNECT_TIMEOUT) .build(); class DynamicClusterTimeout extends TimeoutSource { private static final Set<ProtocolKeyword> META_COMMAND_TYPES = ImmutableSet.<ProtocolKeyword>builder() .add(CommandType.FLUSHDB) .add(CommandType.FLUSHALL) .add(CommandType.CLUSTER) .add(CommandType.INFO) .add(CommandType.KEYS) .build(); private final Duration defaultCommandTimeout; private final Duration metaCommandTimeout; DynamicClusterTimeout(Duration defaultTimeout, Duration metaTimeout) { defaultCommandTimeout = defaultTimeout; metaCommandTimeout = metaTimeout; } @Override public long getTimeout(RedisCommand<?, ?, ?> command) { if (META_COMMAND_TYPES.contains(command.getType())) { return metaCommandTimeout.toMillis(); } return defaultCommandTimeout.toMillis(); } } // Use a dynamic timeout for commands, to avoid timeouts during // cluster management and slow operations. TimeoutOptions timeoutOptions = TimeoutOptions.builder() .timeoutSource( new DynamicClusterTimeout(DEFAULT_COMMAND_TIMEOUT, META_COMMAND_TIMEOUT)) .build();