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.
Themen
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
Stellen Sie sicher, dass Sie das Verbindungs-Timeout
ClusterClientOption: Client-Optionen mit aktiviertem Clustermodus
Aktiviert AutoReconnect
Eingestellt CommandTimeout
Legt fest nodeFilter
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
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
closeStaleConnections
Aktiviert dynamicRefreshResources
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 DnsResolver
Konfiguration 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();
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();