Configurazione del client Lettuce (Valkey e Redis) OSS - Amazon ElastiCache

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Configurazione del client Lettuce (Valkey e Redis) OSS

Questa sezione descrive le opzioni di configurazione consigliate per Java e Lettuce e come si applicano ai cluster. ElastiCache

I suggerimenti in questa sezione sono stati testati con Lettuce versione 6.2.2.

Cache Java DNS TTL

La macchina virtuale Java (JVM) memorizza nella cache le ricerche dei DNS nomi. Quando JVM risolve un nome host in un indirizzo IP, memorizza l'indirizzo IP nella cache per un periodo di tempo specificato, noto come (). time-to-liveTTL

La scelta del TTL valore è un compromesso tra latenza e reattività al cambiamento. Con tempi più breviTTLs, i DNS resolver notano gli aggiornamenti nel cluster più velocemente. DNS Ciò può far sì che l'applicazione risponda più rapidamente alle sostituzioni o ad altri flussi di lavoro a cui è sottoposto il cluster. Tuttavia, se TTL è troppo basso, aumenta il volume delle query, il che può aumentare la latenza dell'applicazione. Sebbene non esista un TTL valore corretto, vale la pena considerare il periodo di tempo che ci si può permettere di attendere che una modifica abbia effetto quando si imposta il TTL valore.

Poiché ElastiCache i nodi utilizzano voci di DNS nome che potrebbero cambiare, ti consigliamo TTL di configurarle JVM con un minimo da 5 a 10 secondi. In questo modo, quando l'indirizzo IP di un nodo cambia, l'applicazione sarà in grado di ricevere e utilizzare il nuovo indirizzo IP della risorsa richiedendo l'DNSimmissione.

In alcune configurazioni Java, l'JVMimpostazione predefinita TTL è impostata in modo che non aggiorni mai le DNS voci fino al riavvio di. JVM

Per dettagli su come impostare il tuo JVMTTL, vedi Come impostare il. JVM TTL

Versione Lettuce

Consigliamo la versione Lettuce 6.2.2 o versioni successive.

Endpoints

Quando si utilizzano cluster abilitati in modalità cluster, impostare redisUri sull'endpoint di configurazione del cluster. La DNS relativa ricerca URI restituisce un elenco di tutti i nodi disponibili nel cluster, e viene risolta casualmente su uno di essi durante l'inizializzazione del cluster. Per ulteriori dettagli su come funziona l'aggiornamento della topologia, vedere più avanti in questo argomento. dynamicRefreshResources

SocketOption

Abilita. KeepAlive L'abilitazione di questa opzione riduce la necessità di gestire le connessioni non riuscite durante il runtime del comando.

Assicurarsi di impostare il timeout di connessione in base ai requisiti dell'applicazione e al carico di lavoro. Per ulteriori informazioni, consulta la sezione relativa ai timeout più avanti in questo argomento.

ClusterClientOption: opzioni client abilitate per la modalità cluster

Abilita in AutoReconnectcaso di interruzione della connessione.

Impostare CommandTimeout. Per ulteriori dettagli, consulta la sezione relativa ai timeout più avanti in questo argomento.

Impostato nodeFilterper filtrare i nodi guasti dalla topologia. Lettuce salva tutti i nodi che si trovano nell'output dei «nodi del cluster» (inclusi i nodi conPFAIL/FAILstatus) nelle «partizioni» del client (note anche come shard). Durante il processo di creazione della topologia del cluster, tenta di connettersi a tutti i nodi della partizione. Questo comportamento di Lettuce, che consiste nell'aggiungere nodi non riusciti, può causare errori di connessione (o avvisi) quando i nodi vengono sostituiti per qualsiasi motivo.

Ad esempio, dopo il completamento di un failover e l'avvio del processo di ripristino da parte del cluster, mentre clusterTopology viene aggiornato, la mappa dei nodi del bus del cluster trascorre un breve periodo di tempo in cui il nodo inattivo viene elencato come nodo, prima di essere completamente rimosso FAIL dalla topologia. Durante questo periodo, il client Lettuce lo considera un nodo integro e si connette continuamente ad esso. Ciò causa un errore dopo che il nuovo tentativo è esaurito.

Per esempio:

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

Il filtraggio dei nodi viene utilizzato al meglio con DynamicRefreshSources set to true. Altrimenti, se la vista della topologia viene presa da un singolo nodo di origine problematico, che rileva un nodo primario non riuscito di qualche partizione, filtrerà questo nodo primario, il che comporterà la mancata copertura degli slot. La presenza di più nodi iniziali (quando DynamicRefreshSources è vero) riduce la probabilità che si verifichi questo problema, poiché almeno alcuni nodi iniziali dovrebbero avere una vista topologica aggiornata dopo un failover con il primario appena promosso.

ClusterTopologyRefreshOptions: opzioni per controllare l'aggiornamento della topologia del cluster del client Cluster Mode Enabled

Nota

I cluster con la modalità cluster disabilitata non supportano i comandi di rilevamento del cluster e non sono compatibili con la funzionalità di rilevamento della topologia dinamica di tutti i client.

La modalità cluster disabilitata con ElastiCache non è compatibile con Lettuce's. MasterSlaveTopologyRefresh Invece, per la modalità cluster disabilitata è possibile configurare un StaticMasterReplicaTopologyProvider e fornire gli endpoint di lettura e scrittura del cluster.

Per ulteriori informazioni sulla connessione a cluster disattivati, consulta Individuazione degli endpoint di un cluster Valkey o Redis OSS (modalità cluster disabilitata) (console).

Se desideri utilizzare la funzionalità di rilevamento della topologia dinamica di Lettuce, puoi creare un cluster con la modalità cluster abilitata con la stessa configurazione di partizioni del cluster esistente. Tuttavia, per i cluster abilitati alla modalità cluster, consigliamo di configurare almeno 3 shard con almeno una replica per supportare il failover rapido.

Abilita. enablePeriodicRefresh Ciò consente gli aggiornamenti periodici della topologia del cluster in modo che il client aggiorni la topologia del cluster a intervalli di refreshPeriod (impostazione predefinita: 60 secondi). Quando è disabilitato, il client aggiorna la topologia del cluster solo quando si verificano errori quando tenta di eseguire comandi sul cluster.

Con questa opzione abilitata, è possibile ridurre la latenza associata all'aggiornamento della topologia del cluster aggiungendo questo processo a un'attività in background. Sebbene l'aggiornamento della topologia venga eseguito in un processo in background, può essere piuttosto lento per i cluster con molti nodi. Questo perché vengono eseguite query sulle viste di tutti i nodi per ottenere la vista del cluster più aggiornata. Se si gestisce un cluster di grandi dimensioni, si potrebbe voler aumentare il periodo.

enableAllAdaptiveRefreshTriggersAbilita. Ciò consente l'aggiornamento adattivo della topologia che utilizza tutti i trigger: MOVED _REDIRECT, _, ASK _ REDIRECTRECONNECTS, PERSISTENT UNCOVERED _. SLOT UNKNOWN NODE I trigger di aggiornamento adattivi avviano gli aggiornamenti della visualizzazione della topologia in base agli eventi che si verificano durante le operazioni dei cluster Valkey o Redis. OSS L'attivazione di questa opzione comporta un aggiornamento immediato della topologia quando si verifica uno dei trigger precedenti. Gli aggiornamenti attivati adattivi hanno una frequenza limitata mediante un timeout perché gli eventi possono verificarsi su larga scala (timeout predefinito tra gli aggiornamenti: 30).

Abilita. closeStaleConnections Ciò consente di chiudere le connessioni obsolete durante l'aggiornamento della topologia del cluster. Entra in vigore solo se ClusterTopologyRefreshOptions. isPeriodicRefreshEnabled () è vero. Quando è abilitato, il client può chiudere le connessioni obsolete e crearne di nuove in background. Ciò riduce la necessità di gestire le connessioni non riuscite durante il runtime del comando.

Abilita dynamicRefreshResources. Ti consigliamo di abilitarlo dynamicRefreshResources per i cluster di piccole dimensioni e di disabilitarlo per i cluster di grandi dimensioni. dynamicRefreshResourcesconsente di scoprire i nodi del cluster dal nodo iniziale fornito (ad esempio, l'endpoint di configurazione del cluster). Utilizza tutti i nodi rilevati come origine per aggiornare la topologia del cluster.

Utilizzando l'aggiornamento dinamico, esegue query su tutti i nodi rilevati per la topologia del cluster e tenta di scegliere la vista del cluster più accurata. Se è impostato su false, solo i nodi di origine iniziali vengono utilizzati come origini per l'individuazione della topologia e il numero di client viene ottenuto solo per i nodi di origine iniziali. Quando è disabilitato, se l'endpoint di configurazione del cluster viene risolto in un nodo non riuscito, il tentativo di aggiornare la vista del cluster restituisce un errore e genera delle eccezioni. Questo scenario può verificarsi perché è necessario del tempo prima che un nodo non riuscito venga rimosso dall'endpoint di configurazione del cluster. Pertanto, l'endpoint di configurazione può ancora essere risolto casualmente in un nodo non riuscito per un breve lasso di tempo.

Quando è abilitato, tuttavia, utilizziamo tutti i nodi del cluster ricevuti dalla vista del cluster per eseguire query sulla vista corrente. Poiché filtriamo i nodi non riusciti da quella vista, l'aggiornamento della topologia avverrà correttamente. Tuttavia, quando dynamicRefreshSources è vero, Lettuce interroga tutti i nodi per ottenere la visualizzazione del cluster e quindi confronta i risultati. Pertanto, l'operazione può essere costosa per i cluster con molti nodi. Consigliamo di disattivare questa funzionalità per i cluster con molti nodi.

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

ClientResources

Configura con. DnsResolverDirContextDnsResolver Il DNS resolver è basato su com.sun.jndi.dns di Java. DnsContextFactory.

Configurazione reconnectDelaycon backoff esponenziale e full jitter. Lettuce ha meccanismi di ripetizione incorporati basati sulle strategie di backoff esponenziale. Per maggiori dettagli, consulta Exponential Backoff and Jitter sul blog di architettura. AWS Per ulteriori informazioni sull'importanza di adottare una strategia di backoff tra tentativi ripetuti, consulta le sezioni sulla logica di backoff del post sulle best practice sul Database 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();

Timeout

Usa un valore di timeout di connessione inferiore rispetto al timeout dei comandi. Lettuce utilizza l'avvio lento della connessione. Quindi, se il timeout di connessione è superiore al timeout del comando, si può avere un periodo di errore persistente dopo un aggiornamento della topologia se Lettuce tenta di connettersi a un nodo non integro e il timeout del comando viene sempre superato.

Utilizzo di un timeout dinamico dei comandi per diversi comandi. Consigliamo di impostare il timeout dei comandi in base alla durata prevista dei comandi. Ad esempio, utilizzate un timeout più lungo per i comandi che eseguono iterazioni su più tasti,, o gli FLUSHDB script FLUSHALL Lua. KEYS SMEMBERS Utilizzate timeout più brevi per i comandi a chiave singola, come, e. SET GET HSET

Nota

I timeout configurati nell'esempio seguente sono per i test che hanno eseguito GET comandiSET/con chiavi e valori lunghi fino a 20 byte. Il tempo di elaborazione può essere più lungo quando i comandi sono complessi o le chiavi e i valori sono più grandi. È necessario impostare i timeout in base al caso d'uso dell'applicazione.

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