Konfiguration des Salat-Clients (Valkey und Redis) OSS - Amazon ElastiCache

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Konfiguration des Salat-Clients (Valkey und Redis) OSS

In diesem Abschnitt werden die empfohlenen Konfigurationsoptionen für Java und Lettuce sowie deren Anwendung auf Cluster beschrieben. ElastiCache

Die Empfehlungen in diesem Abschnitt wurden mit Lettuce Version 6.2.2 getestet.

Java-Cache DNS TTL

Die virtuelle Java-Maschine (JVM) speichert DNS Namenssuchvorgänge im Cache. Wenn der einen Hostnamen in eine IP-Adresse JVM auflöst, speichert er die IP-Adresse für einen bestimmten Zeitraum im Cache, der als () bezeichnet wird. time-to-liveTTL

Die Wahl des TTL Werts ist ein Kompromiss zwischen Latenz und Reaktionsfähigkeit auf Veränderungen. Je kürzerTTLs, desto schneller erkennen DNS Resolver Aktualisierungen im Cluster. DNS Dadurch kann Ihre Anwendung schneller auf Ersetzungen oder andere Workflows reagieren, denen Ihr Cluster unterzogen wird. Wenn der Wert jedoch zu niedrig TTL ist, erhöht sich das Abfragevolumen, was die Latenz Ihrer Anwendung erhöhen kann. Es gibt zwar keinen korrekten TTL Wert, aber es lohnt sich, bei der Festlegung Ihres TTL Werts zu berücksichtigen, wie lange Sie es sich leisten können, auf das Wirksamwerden einer Änderung zu warten.

Da ElastiCache Knoten DNS Namenseinträge verwenden, die sich ändern können, empfehlen wir Ihnen, Ihren JVM mit einem Tiefstwert TTL von 5 bis 10 Sekunden zu konfigurieren. Dadurch wird sichergestellt, dass Ihre Anwendung, wenn sich die IP-Adresse eines Knotens ändert, die neue IP-Adresse der Ressource empfangen und verwenden kann, indem sie den DNS Eintrag erneut abfragt.

Bei einigen Java-Konfigurationen TTL ist die JVM Standardeinstellung so eingestellt, dass DNS Einträge erst aktualisiert werden, wenn der neu gestartet JVM wird.

Einzelheiten zum Einstellen Ihres JVM TTL finden Sie unter So legen Sie den JVM TTL fest.

Lettuce-Version

Wir empfehlen die Verwendung der Lettuce-Version 6.2.2 oder höher.

Endpunkte

Wenn Sie Cluster verwenden, für die der Cluster-Modus aktiviert ist, legen Sie den redisUri auf den Endpunkt der Cluster-Konfiguration fest. Die DNS Suche danach URI gibt eine Liste aller verfügbaren Knoten im Cluster zurück und wird während der Cluster-Initialisierung nach dem Zufallsprinzip in einen von ihnen aufgelöst. Weitere Informationen zur Funktionsweise der Topologieaktualisierung finden Sie weiter unten in dynamicRefreshResourcesdiesem Thema.

SocketOption

Aktivieren. KeepAlive Durch die Aktivierung dieser Option wird die Notwendigkeit verringert, während der Befehlslaufzeit ausgefallene Verbindungen zu behandeln.

Stellen Sie sicher, dass Sie das Verbindungs-Timeout entsprechend Ihren Anwendungsanforderungen und Ihrer Workload festlegen. Weitere Informationen finden Sie im Abschnitt „Timeouts“ weiter unten in diesem Thema.

ClusterClientOption: Client-Optionen mit aktiviertem Clustermodus

Aktiviert AutoReconnect, wenn die Verbindung unterbrochen wird.

Eingestellt CommandTimeout. Weitere Einzelheiten finden Sie im Abschnitt „Timeouts“ weiter unten in diesem Thema.

Legt fest nodeFilter, dass ausgefallene Knoten aus der Topologie herausgefiltert werden. Lettuce speichert alle Knoten, die in der Ausgabe „Clusterknoten“ gefunden werden (einschließlich Knoten mit dem FAIL StatusPFAIL/), in den „Partitionen“ des Clients (auch bekannt als Shards). Während der Erstellung der Cluster-Topologie wird versucht, eine Verbindung mit allen Knoten der Partition herzustellen. Dieses Verhalten von Lettuce, bei dem ausgefallene Knoten hinzugefügt werden, kann Verbindungsfehlern (oder Warnungen) verursachen, wenn Knoten aus einem beliebigen Grund ersetzt werden.

Wenn beispielsweise ein Failover abgeschlossen ist und der Cluster den Wiederherstellungsprozess startet, während der aktualisiert clusterTopology wird, gibt es in der Clusterbus-Knotenübersicht einen kurzen Zeitraum, in dem der ausgefallene Knoten als Knoten aufgeführt wird, bevor er vollständig aus der FAIL Topologie entfernt wird. Während dieser Zeit betrachtet der Lettuce-Client ihn als fehlerfreien Knoten und stellt kontinuierlich eine Verbindung zu ihm her. Dies führt zu einem Fehler, nachdem alle Wiederholungsversuche durchgeführt wurden.

Beispielsweise:

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);
Anmerkung

Die Knotenfilterung wird am besten verwendet, wenn sie auf true DynamicRefreshSources gesetzt ist. Andernfalls wird der Primärknoten eines Shards herausgefiltert, wenn die Topologieansicht von einem einzelnen problematischen Seed-Knoten übernommen wird, der diesen primären Knoten als ausgefallen ansieht. Dies führt dazu, dass die Slots nicht abgedeckt werden. Wenn mehrere Seed-Knoten vorhanden sind (wenn wahr), verringert DynamicRefreshSources sich die Wahrscheinlichkeit, dass dieses Problem auftritt, da zumindest einige der Seed-Knoten nach einem Failover mit dem neu hochgestuften Primärknoten über eine aktualisierte Topologieansicht verfügen sollten.

ClusterTopologyRefreshOptions: Optionen zur Steuerung der Aktualisierung der Clustertopologie auf dem Client mit aktiviertem Clustermodus

Anmerkung

Cluster mit deaktivierten Cluster-Modus unterstützen die Befehle zur Cluster-Ermittlung nicht und sind nicht mit allen Funktionen zur dynamischen Topologieermittlung des Clients kompatibel.

Der Clustermodus ist deaktiviert mit ElastiCache ist nicht mit dem von Lettuce kompatibel. MasterSlaveTopologyRefresh Stattdessen können Sie für einen deaktivierten Cluster-Modus einen StaticMasterReplicaTopologyProvider konfigurieren und die Lese- und Schreibendpunkte des Clusters bereitstellen.

Weitere Informationen zum Herstellen einer Verbindung mit Clustern mit deaktiviertem Cluster-Modus finden Sie unter Finden der Endpunkte eines Valkey- oder Redis-Clusters OSS (Cluster-Modus deaktiviert) (Konsole).

Wenn Sie die Funktion zur dynamischen Topologieermittlung von Lettuce verwenden möchten, können Sie einen Cluster mit aktiviertem Cluster-Modus mit derselben Shard-Konfiguration wie Ihr vorhandener Cluster erstellen. Für Cluster mit aktiviertem Cluster-Modus empfehlen wir jedoch, mindestens 3 Shards mit mindestens einem Replikat zu konfigurieren, um schnelles Failover zu unterstützen.

Aktiviert. enablePeriodicRefresh Dadurch werden regelmäßige Updates der Clustertopologie aktiviert, sodass der Client die Clustertopologie in Intervallen von refreshPeriod (Standard: 60 Sekunden) aktualisiert. Wenn das Element deaktiviert ist, aktualisiert der Client die Cluster-Topologie nur, falls es bei dem Versuch, Befehle für den Cluster auszuführen, zu Fehlern kommt.

Wenn diese Option aktiviert ist, können Sie die mit der Aktualisierung der Cluster-Topologie verbundene Latenz reduzieren, indem Sie diesen Auftrag zu einer Hintergrundaufgabe hinzufügen. Die Aktualisierung der Topologie erfolgt zwar im Hintergrund, kann jedoch bei Clustern mit vielen Knoten etwas langsam sein. Dies liegt daran, dass alle Knoten nach ihren Ansichten abgefragt werden, um die aktuellste Cluster-Ansicht zu erhalten. Wenn Sie einen großen Cluster betreiben, sollten Sie den Zeitraum erhöhen.

Aktivieren. enableAllAdaptiveRefreshTriggers Dadurch wird die adaptive Topologieaktualisierung aktiviert, die alle Trigger verwendet: MOVED ASK _ REDIRECTREDIRECT, PERSISTENT _RECONNECTS, UNCOVERED _SLOT, UNKNOWN _NODE. Adaptive Aktualisierungsauslöser initiieren Aktualisierungen der Topologieansicht auf der Grundlage von Ereignissen, die während Valkey- oder OSS Redis-Clustervorgängen auftreten. Das Aktivieren dieser Option führt zu einer sofortigen Aktualisierung der Topologie, wenn einer der zuvor genannten Trigger auftritt. Die Rate der adaptiv ausgelöste Aktualisierungen ist durch einen Timeout begrenzt, da Ereignisse in großem Umfang auftreten können (Standard-Timeout zwischen Updates: 30).

closeStaleConnectionsAktivieren. Dadurch können alte Verbindungen beim Aktualisieren der Cluster-Topologie geschlossen werden. Es tritt nur in Kraft, wenn ClusterTopologyRefreshOptions. isPeriodicRefreshEnabled () ist wahr. Wenn es aktiviert ist, kann der Client alte Verbindungen schließen und im Hintergrund neue erstellen. Dadurch wird die Notwendigkeit verringert, während der Befehlslaufzeit ausgefallene Verbindungen zu behandeln.

Aktiviert dynamicRefreshResources. Wir empfehlen, sie dynamicRefreshResources für kleine Cluster zu aktivieren und für große Cluster zu deaktivieren. dynamicRefreshResourcesermöglicht die Erkennung von Clusterknoten anhand des bereitgestellten Seed-Knotens (z. B. vom Cluster-Konfigurationsendpunkt). Es verwendet alle erkannten Knoten als Quellen für die Aktualisierung der Cluster-Topologie.

Bei der Verwendung der dynamischen Aktualisierung werden alle erkannten Knoten nach der Cluster-Topologie abgefragt und es wird versucht, die genaueste Cluster-Ansicht auszuwählen. Wenn der Wert auf „falsch“ festgelegt ist, werden nur die anfänglichen Seed-Knoten als Quellen für die Topologieerkennung verwendet, und die Anzahl der Clients wird nur für die ersten Seed-Knoten ermittelt. Ist er deaktiviert und der Endpunkt der Cluster-Konfiguration wird in einen ausgefallenen Knoten aufgelöst, schlägt der Versuch, die Cluster-Ansicht zu aktualisieren, fehl und führt zu Ausnahmen. Dieses Szenario kann eintreten, da es einige Zeit dauert, bis der Eintrag eines ausgefallenen Knotens vom Endpunkt der Cluster-Konfiguration entfernt wird. Daher kann der Konfigurationsendpunkt für einen kurzen Zeitraum immer noch nach dem Zufallsprinzip auf einen ausgefallenen Knoten aufgelöst werden.

Ist er aktiviert, verwenden wir jedoch alle Cluster-Knoten, die von der Cluster-Ansicht empfangen werden, um ihre aktuelle Ansicht abzufragen. Da wir ausgefallene Knoten aus dieser Ansicht herausfiltern, ist die Topologieaktualisierung erfolgreich. Wenn dies jedoch dynamicRefreshSources zutrifft, fragt Lettuce alle Knoten ab, um die Clusteransicht abzurufen, und vergleicht dann die Ergebnisse. Daher kann dieses Vorgehen für Cluster mit vielen Knoten teuer sein. Wir empfehlen, dass Sie diese Funktion für Cluster mit vielen Knoten deaktivieren.

final ClusterTopologyRefreshOptions topologyOptions = ClusterTopologyRefreshOptions.builder() .enableAllAdaptiveRefreshTriggers() .enablePeriodicRefresh() .dynamicRefreshSources(true) .build();

ClientResources

Konfigurieren Sie DnsResolvermit DirContextDnsResolver. Der DNS Resolver basiert auf Javas com.sun.jndi.dns. DnsContextFactory.

Konfiguration reconnectDelaymit exponentiellem Backoff und vollem Jitter. Lettuce verfügt über integrierte Wiederholungsmechanismen, die auf den exponentiellen Backoff-Strategien basieren. Einzelheiten finden Sie unter Exponential Backoff and Jitter im Architecture-Blog. AWS Weitere Informationen darüber, wie wichtig es ist, eine Backoff-Strategie für Wiederholungsversuche zu verwenden, finden Sie in den Abschnitten zur Backoff-Logik im Blogbeitrag Best Practices im Datenbank-Blog. AWS

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();

Timeouts

Verwenden Sie einen niedrigeren Wert für das Verbindungs-Timeout als für das Befehls-Timeout. Lettuce verwendet einen verzögerten Verbindungsaufbau. Wenn also das Verbindungs-Timeout höher als das Befehls-Timeout ist, kann es nach einer Topologieaktualisierung zu einem Zeitraum mit anhaltendem Ausfall kommen, falls Lettuce versucht, eine Verbindung mit einem fehlerhaften Knoten herzustellen, und das Befehls-Timeout immer überschritten wird.

Verwenden Sie ein dynamisches Befehls-Timeout für verschiedene Befehle. Wir empfehlen, das Befehls-Timeout auf der Grundlage der erwarteten Dauer des Befehls festzulegen. Verwenden Sie beispielsweise ein längeres Timeout für Befehle, die über mehrere Schlüssel iterieren, wie,, oder FLUSHDB Lua-Skripten. FLUSHALL KEYS SMEMBERS Verwenden Sie kürzere Timeouts für Befehle mit nur einer Taste, wieSET, und. GET HSET

Anmerkung

Die im folgenden Beispiel konfigurierten Timeouts gelten für Tests, bei denen SET GET /-Befehle mit Tasten und Werten von bis zu 20 Byte Länge ausgeführt wurden. Die Verarbeitungszeit kann bei komplexen Befehlen oder größeren Schlüsseln und Werten länger sein. Sie sollten die Timeouts je nach Anwendungsfall Ihrer Anwendung festlegen.

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();