

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à.

# ElastiCache migliori pratiche e strategie di caching
<a name="BestPractices"></a>

Di seguito puoi trovare le best practice consigliate per Amazon ElastiCache. Queste best practice consentono di migliorare prestazioni e affidabilità della cache. 

**Topics**
+ [Le migliori pratiche generali](WorkingWithRedis.md)
+ [Procedure consigliate per l'utilizzo delle repliche di lettura](ReadReplicas.md)
+ [Comandi Valkey, Memcached e Redis OSS supportati e limitati](SupportedCommands.md)
+ [Configurazione e limiti di Valkey e Redis OSS](RedisConfiguration.md)
+ [IPv6 esempi di client per Valkey, Memcached e Redis OSS](network-type-best-practices.md)
+ [Le migliori pratiche per i clienti (Valkey e Redis OSS)](BestPractices.Clients.redis.md)
+ [Le migliori pratiche per i clienti (Memcached)](BestPractices.Clients.memcached.md)
+ [Cluster dual ElastiCache stack abilitati per TLS](#network-type-configuring-tls-enabled-dual-stack)
+ [Gestione della memoria riservata per Valkey e Redis OSS](redis-memory-management.md)
+ [Procedure consigliate per l'utilizzo di cluster basati su nodi Valkey e Redis OSS](BestPractices.SelfDesigned.md)
+ [Strategie di caching per Memcached](Strategies.md)

# Le migliori pratiche generali
<a name="WorkingWithRedis"></a>

Di seguito puoi trovare informazioni sulle migliori pratiche per l'utilizzo delle interfacce Valkey, Memcached e Redis OSS all'interno. ElastiCache
+ **Usa configurazioni abilitate per la modalità cluster: la modalità cluster abilitata** consente alla cache di scalare orizzontalmente per ottenere uno storage e un throughput più elevati rispetto a una configurazione disabilitata in modalità cluster. ElastiCache serverless è disponibile solo in una configurazione abilitata per la modalità cluster.
+ **Usa connessioni di lunga durata**: la creazione di una nuova connessione è costosa e richiede tempo e risorse della CPU della cache. Riutilizza le connessioni quando possibile (ad esempio con il pool di connessioni) per ammortizzare questo costo rispetto a molti comandi.
+ **Leggi dalle repliche**: se utilizzi sistemi ElastiCache serverless o disponi di repliche di lettura predisposte (cluster basati su nodi), indirizza le letture alle repliche per ottenere una migliore scalabilità, una latenza inferiore. and/or Le letture dalle repliche sono consistenti finali con il nodo primario.

  In un cluster basato su nodi, evita di indirizzare le richieste di lettura a una singola replica di lettura, poiché le letture potrebbero non essere temporaneamente disponibili in caso di errore del nodo. Puoi configurare il client per indirizzare le richieste di lettura ad almeno due repliche di lettura oppure indirizzare le letture a una sola replica e al nodo primario.

  In modalità ElastiCache serverless, la lettura dalla porta di replica (6380) indirizzerà le letture alla zona di disponibilità locale del client, ove possibile, riducendo la latenza di recupero. Esegue automaticamente il fallback agli altri nodi in caso di errore.
+ **Evita comandi costosi**: evita di eseguire operazioni computazionali e intensive, come i comandi and I/O . `KEYS` `SMEMBERS` Suggeriamo l'utilizzo di questo approccio perché queste operazioni aumentano il carico sul cluster e hanno impatto sulle prestazioni del cluster. Utilizza i comandi `SCAN` e `SSCAN`.
+ **Segui le best practice Lua** - Evita script Lua di lunga durata e dichiara sempre in anticipo le chiavi utilizzate degli script Lua. Consigliamo questo approccio per determinare che lo script Lua non utilizza comandi tra slot. Assicurati che le chiavi utilizzate negli script Lua appartengano allo stesso slot.
+ **Usa sharded pub/sub**: quando usi Valkey o Redis OSS per supportare pub/sub carichi di lavoro con throughput elevato, ti consigliamo di utilizzare [sharded pub/sub](https://valkey.io/topics/pubsub/) (disponibile con Valkey e con Redis OSS 7 o versione successiva). I cluster tradizionali abilitati alla modalità cluster pub/sub trasmettono messaggi a tutti i nodi del cluster, il che può comportare un aumento. `EngineCPUUtilization` Notatelo nei ElastiCache comandi tradizionali senza server. pub/sub commands internally use sharded pub/sub

**Topics**

# Procedure consigliate per l'utilizzo delle repliche di lettura
<a name="ReadReplicas"></a>

Molte applicazioni, come gli archivi di sessioni, le classifici e i motori di raccomandazione, richiedono un'elevata disponibilità e gestiscono un numero significativamente maggiore di operazioni di lettura rispetto alle operazioni di scrittura. Queste applicazioni possono spesso tollerare dati leggermente obsoleti (eventuale coerenza), il che significa che è accettabile che utenti diversi visualizzino momentaneamente versioni leggermente diverse degli stessi dati. Esempio:
+ I risultati delle query memorizzate nella cache possono spesso tollerare dati leggermente obsoleti, in particolare per i modelli di cache in cui la fonte della verità è esterna.
+ In una classifica di gioco, un ritardo di qualche secondo nell'aggiornamento dei punteggi spesso non ha un impatto significativo sull'esperienza dell'utente.
+ Per quanto riguarda gli archivi di sessione, alcuni lievi ritardi nella propagazione dei dati della sessione tra le repliche raramente influiscono sulla funzionalità dell'applicazione.
+ I motori di raccomandazione utilizzano in genere l'analisi dei dati storici, quindi la coerenza in tempo reale è meno importante.

La coerenza finale significa che tutti i nodi di replica restituiranno gli stessi dati una volta completato il processo di replica, in genere entro pochi millisecondi. In questi casi d'uso, l'implementazione di repliche di lettura è una strategia efficace per ridurre la latenza durante la lettura dall'istanza. ElastiCache

L'utilizzo di repliche di lettura in Amazon ElastiCache può offrire vantaggi significativi in termini di prestazioni attraverso:

**Scalabilità di lettura migliorata**
+ Distribuisce le operazioni di lettura su più nodi di replica
+ Scarica il traffico di lettura dal nodo primario
+ Riduce la latenza di lettura soddisfacendo le richieste provenienti da repliche geograficamente più vicine

**Prestazioni ottimizzate del nodo primario**
+ Dedica le risorse del nodo principale alle operazioni di scrittura
+ Riduce il sovraccarico di connessione sul nodo primario
+ Migliora le prestazioni di scrittura e mantiene tempi di risposta migliori durante i periodi di picco di traffico

## Utilizzo di Read from Replica in modalità Serverless ElastiCache
<a name="ReadReplicas.serverless"></a>

ElastiCache serverless fornisce due endpoint diversi, per requisiti di coerenza diversi. I due endpoint utilizzano lo stesso nome DNS ma porte diverse. Per utilizzare la read-from-replica porta, devi autorizzare l'accesso a entrambe le porte dall'applicazione client [configurando i gruppi di sicurezza e gli elenchi di controllo degli accessi alla rete del tuo VPC](set-up.md#elasticache-install-grant-access-VPN).

**Endpoint primario (porta 6379)**
+ Utilizzabile per operazioni che richiedono una coerenza immediata
+ Garantisce la lettura della maggior parte up-to-date dei dati
+ Ideale per transazioni critiche e operazioni di scrittura
+ Necessario per le operazioni di scrittura
+ Ad esempio: `test-12345.serverless.use1.cache.amazonaws.com:6379`

**Endpoint ottimizzato per la latenza (porta 6380)**
+ Ottimizzato per operazioni di lettura che possono tollerare un'eventuale coerenza
+ Quando possibile, la modalità ElastiCache serverless indirizza automaticamente le richieste di lettura al nodo di replica nella zona di disponibilità locale del client. Questa ottimizzazione offre una latenza inferiore evitando la latenza di rete aggiuntiva generata dal recupero dei dati da un nodo in una zona di disponibilità diversa.
+ ElastiCache serverless seleziona automaticamente i nodi disponibili in altre zone se un nodo locale non è disponibile
+ Ad esempio: `test-12345.serverless.use1.cache.amazonaws.com:6380`
+ Client come Glide e Lettuce rileveranno e indirizzeranno automaticamente le letture verso l'endpoint con latenza ottimizzata se si fornisce la configurazione di lettura dalla replica. Se il tuo client non supporta la configurazione del routing (ad esempio, valkey-java e versioni precedenti di jedis), devi definire la porta e la configurazione del client corrette per la lettura dalle repliche.

## Connessione per leggere le repliche in Serverless - Valkey e Glide ElastiCache
<a name="ReadReplicas.connecting-primary"></a>

Il seguente frammento di codice mostra come configurare la lettura dalla replica per ElastiCache Serverless nella libreria Valkey glide. Non è necessario specificare la porta per la lettura dalle repliche, ma è necessario configurare la configurazione del routing. `ReadFrom.PREFER_REPLICA`

```
package glide.examples;

import glide.api.GlideClusterClient;
import glide.api.logging.Logger;
import glide.api.models.configuration.GlideClusterClientConfiguration;
import glide.api.models.configuration.NodeAddress;
import glide.api.models.exceptions.ClosingException;
import glide.api.models.exceptions.ConnectionException;
import glide.api.models.exceptions.TimeoutException;
import glide.api.models.configuration.ReadFrom;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class ClusterExample {

    public static void main(String[] args) {
        // Set logger configuration
        Logger.setLoggerConfig(Logger.Level.INFO);

        GlideClusterClient client = null;

        try {
            System.out.println("Connecting to Valkey Glide...");

            // Configure the Glide Client
            GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder()
                .address(NodeAddress.builder()
                    .host("your-endpoint")
                    .port(6379)
                    .build())
                .useTLS(true)
                .readFrom(ReadFrom.PREFER_REPLICA)
                .build();

            // Create the GlideClusterClient
            client = GlideClusterClient.createClient(config).get();
            System.out.println("Connected successfully.");

            // Perform SET operation
            CompletableFuture<String> setResponse = client.set("key", "value");
            System.out.println("Set key 'key' to 'value': " + setResponse.get());

            // Perform GET operation
            CompletableFuture<String> getResponse = client.get("key");
            System.out.println("Get response for 'key': " + getResponse.get());

            // Perform PING operation
            CompletableFuture<String> pingResponse = client.ping();
            System.out.println("PING response: " + pingResponse.get());

        } catch (ClosingException | ConnectionException | TimeoutException | ExecutionException e) {
            System.err.println("An exception occurred: ");
            e.printStackTrace();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // Close the client connection
            if (client != null) {
                try {
                    client.close();
                    System.out.println("Client connection closed.");
                } catch (ClosingException | ExecutionException e) {
                    System.err.println("Error closing client: " + e.getMessage());
                }
            }
        }
    }
}
```

# Comandi Valkey, Memcached e Redis OSS supportati e limitati
<a name="SupportedCommands"></a>

## Comandi Valkey e Redis OSS supportati
<a name="SupportedCommandsRedis"></a>

**Comandi Valkey e Redis OSS supportati**

I seguenti comandi Valkey e Redis OSS sono supportati dalle cache serverless. Oltre a questi comandi, sono supportati anche i [Comandi Valkey e Redis OSS supportatiComandi JSON](json-list-commands.md).

Per informazioni sui comandi del filtro Bloom, vedere [Comandi del filtro Bloom](BloomFilters.md#SupportedCommandsBloom)

**Comandi bitmap**
+ `BITCOUNT`

  Conta il numero di bit impostati (conteggio della popolazione) in una stringa.

  [Ulteriori informazioni](https://valkey.io/commands/bitcount/)
+ `BITFIELD`

  Esegue operazioni arbitrarie di numeri interi bitfield sulle stringhe.

  [Ulteriori informazioni](https://valkey.io/commands/bitfield/)
+ `BITFIELD_RO`

  Esegue operazioni arbitrarie di numeri interi bitfield di sola lettura sulle stringhe.

  [Ulteriori informazioni](https://valkey.io/commands/bitfield_ro/)
+ `BITOP`

  Esegue operazioni bit per bit su più stringhe e archivia il risultato.

  [Ulteriori informazioni](https://valkey.io/commands/bitop/)
+ `BITPOS`

  Trova il primo bit di impostazione (1) o cancellazione (0) in una stringa.

  [Ulteriori informazioni](https://valkey.io/commands/bitpos/)
+ `GETBIT`

  Restituisce un valore di bit per offset.

  [Ulteriori informazioni](https://valkey.io/commands/getbit/)
+ `SETBIT`

  Imposta o cancella il bit all'offset del valore della stringa. Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/setbit/)

**Comandi di gestione dei cluster**
+ `CLUSTER COUNTKEYSINSLOT`

  Restituisce il numero di chiavi in uno slot hash.

  [Ulteriori informazioni](https://valkey.io/commands/cluster-countkeysinslot/)
+ `CLUSTER GETKEYSINSLOT`

  Restituisce i nomi delle chiavi in uno slot hash.

  [Ulteriori informazioni](https://valkey.io/commands/cluster-getkeysinslot/)
+ `CLUSTER INFO`

  Restituisce le informazioni sullo stato di un nodo. In una cache serverless, restituisce lo stato della singola "partizione" virtuale esposta al client.

  [Ulteriori informazioni](https://valkey.io/commands/cluster-info/)
+ `CLUSTER KEYSLOT`

  Restituisce lo slot hash per una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/cluster-keyslot/)
+ `CLUSTER MYID`

  Restituisce l'ID di un nodo. In una cache serverless, restituisce lo stato della singola "partizione" virtuale esposta al client. 

  [Ulteriori informazioni](https://valkey.io/commands/cluster-myid/)
+ `CLUSTER NODES`

  Restituisce la configurazione del cluster per un nodo. In una cache serverless, restituisce lo stato della singola "partizione" virtuale esposta al client. 

  [Ulteriori informazioni](https://valkey.io/commands/cluster-nodes/)
+ `CLUSTER REPLICAS`

  Elenca i nodi di replica di un nodo principale. In una cache serverless, restituisce lo stato della singola "partizione" virtuale esposta al client. 

  [Ulteriori informazioni](https://valkey.io/commands/cluster-replicas/)
+ `CLUSTER SHARDS`

  Restituisce la mappatura degli slot del cluster alle partizioni. In una cache serverless, restituisce lo stato della singola "partizione" virtuale esposta al client. 

  [Ulteriori informazioni](https://valkey.io/commands/cluster-shards/)
+ `CLUSTER SLOTS`

  Restituisce la mappatura degli slot del cluster ai nodi. In una cache serverless, restituisce lo stato della singola "partizione" virtuale esposta al client. 

  [Ulteriori informazioni](https://valkey.io/commands/cluster-slots/)
+ `CLUSTER SLOT-STATS`

  Consente il tracciamento delle metriche per slot relative al conteggio delle chiavi, all'utilizzo della CPU, ai byte di rete in ingresso e ai byte di rete in uscita. 

  [Ulteriori informazioni](https://valkey.io/commands/cluster-slot-stats/)
+ `READONLY`

  Abilita le query di sola lettura per una connessione a un nodo di replica Valkey o Redis OSS Cluster.

  [Ulteriori informazioni](https://valkey.io/commands/readonly/)
+ `READWRITE`

  Abilita le query di lettura/scrittura per una connessione a un nodo di replica Valkey o Redis OSS Cluster.

  [Ulteriori informazioni](https://valkey.io/commands/readwrite/)
+ `SCRIPT SHOW`

  Restituisce il codice sorgente originale di uno script nella cache degli script.

  [Ulteriori informazioni](https://valkey.io/commands/script-show/)

**Comandi di gestione della connessione**
+ `AUTH`

  Autentica la connessione.

  [Ulteriori informazioni](https://valkey.io/commands/auth/)
+ `CLIENT GETNAME`

  Restituisce il nome della connessione.

  [Ulteriori informazioni](https://valkey.io/commands/client-getname/)
+ `CLIENT REPLY`

  Indica al server se rispondere ai comandi.

  [Ulteriori informazioni](https://valkey.io/commands/client-reply/)
+ `CLIENT SETNAME`

  Imposta il nome della connessione.

  [Ulteriori informazioni](https://valkey.io/commands/client-setname/)
+ `ECHO`

  Restituisce la specifica stringa.

  [Ulteriori informazioni](https://valkey.io/commands/echo/)
+ `HELLO`

  Strette di mano con il server Valkey o Redis OSS.

  [Ulteriori informazioni](https://valkey.io/commands/hello/)
+ `PING`

  Restituisce la risposta di attività del server.

  [Ulteriori informazioni](https://valkey.io/commands/ping/)
+ `QUIT`

  Chiude la connessione.

  [Ulteriori informazioni](https://valkey.io/commands/quit/)
+ `RESET`

  Reimposta la connessione.

  [Ulteriori informazioni](https://valkey.io/commands/reset/)
+ `SELECT`

  Cambia il database selezionato.

  [Ulteriori informazioni](https://valkey.io/commands/select/)

**Comandi generici**
+ `COPY`

  Copia il valore di una chiave in una nuova chiave.

  [Ulteriori informazioni](https://valkey.io/commands/copy/)
+ `DEL`

  Elimina una o più chiavi.

  [Ulteriori informazioni](https://valkey.io/commands/del/)
+ `DUMP`

  Restituisce una rappresentazione serializzata del valore archiviato in una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/dump/)
+ `EXISTS`

  Determina se esistono una o più chiavi.

  [Ulteriori informazioni](https://valkey.io/commands/exists/)
+ `EXPIRE`

  Imposta l'ora di scadenza di una chiave in secondi.

  [Ulteriori informazioni](https://valkey.io/commands/expire/)
+ `EXPIREAT`

  Imposta l'ora di scadenza di una chiave su un timestamp Unix.

  [Ulteriori informazioni](https://valkey.io/commands/expireat/)
+ `EXPIRETIME`

  Restituisce l'ora di scadenza di una chiave come timestamp Unix.

  [Ulteriori informazioni](https://valkey.io/commands/expiretime/)
+ `PERSIST`

  Rimuove l'ora di scadenza di una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/persist/)
+ `PEXPIRE`

  Imposta l'ora di scadenza di una chiave in millisecondi.

  [Ulteriori informazioni](https://valkey.io/commands/pexpire/)
+ `PEXPIREAT`

  Imposta l'ora di scadenza di una chiave su un timestamp in millisecondi Unix.

  [Ulteriori informazioni](https://valkey.io/commands/pexpireat/)
+ `PEXPIRETIME`

  Restituisce l'ora di scadenza di una chiave come timestamp in millisecondi Unix.

  [Ulteriori informazioni](https://valkey.io/commands/pexpiretime/)
+ `PTTL`

  Restituisce l'ora di scadenza di una chiave in millisecondi.

  [Ulteriori informazioni](https://valkey.io/commands/pttl/)
+ `RANDOMKEY`

  Restituisce un nome di chiave casuale del database.

  [Ulteriori informazioni](https://valkey.io/commands/randomkey/)
+ `RENAME`

  Rinomina una chiave e sovrascrive la destinazione.

  [Ulteriori informazioni](https://valkey.io/commands/rename/)
+ `RENAMENX`

  Rinomina una chiave solo quando il nome della chiave di destinazione non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/renamenx/)
+ `RESTORE`

  Crea una chiave dalla rappresentazione serializzata di un valore.

  [Ulteriori informazioni](https://valkey.io/commands/restore/)
+ `SCAN`

  Esegue l'iterazione dei nomi delle chiavi nel database.

  [Ulteriori informazioni](https://valkey.io/commands/scan/)
+ `SORT`

  Ordina gli elementi in un elenco, un set o un set ordinato e archivia facoltativamente il risultato.

  [Ulteriori informazioni](https://valkey.io/commands/sort/)
+ `SORT_RO`

  Restituisce gli elementi ordinati di un elenco, un set o un set ordinato.

  [Ulteriori informazioni](https://valkey.io/commands/sort_ro/)
+ `TOUCH`

  Restituisce il numero di chiavi esistenti tra quelle specificate dopo l'aggiornamento dell'ora dell'ultimo accesso.

  [Ulteriori informazioni](https://valkey.io/commands/touch/)
+ `TTL`

  Restituisce l'ora di scadenza di una chiave in secondi.

  [Ulteriori informazioni](https://valkey.io/commands/ttl/)
+ `TYPE`

  Determina il tipo di valore archiviato in una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/type/)
+ `UNLINK`

  Elimina in modo asincrono una o più chiavi.

  [Ulteriori informazioni](https://valkey.io/commands/unlink/)

**Comandi geospaziali**
+ `GEOADD`

  Aggiunge uno o più membri a un indice geospaziale. La chiave viene creata se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/geoadd/)
+ `GEODIST`

  Restituisce la distanza tra due membri di un indice geospaziale.

  [Ulteriori informazioni](https://valkey.io/commands/geodist/)
+ `GEOHASH`

  Restituisce i membri di un indice geospaziale come stringhe geohash.

  [Ulteriori informazioni](https://valkey.io/commands/geohash/)
+ `GEOPOS`

  Restituisce la longitudine e la latitudine dei membri di un indice geospaziale.

  [Ulteriori informazioni](https://valkey.io/commands/geopos/)
+ `GEORADIUS`

  Esegue le query su un indice geospaziale per i membri che si trovano entro una distanza da una coordinata e facoltativamente archivia il risultato.

  [Ulteriori informazioni](https://valkey.io/commands/georadius/)
+ `GEORADIUS_RO`

  Restituisce i membri di un indice geospaziale che si trovano entro una distanza da una coordinata.

  [Ulteriori informazioni](https://valkey.io/commands/georadius_ro/)
+ `GEORADIUSBYMEMBER`

  Esegue le query su un indice geospaziale per i membri che si trovano entro una distanza da un membro e facoltativamente archivia il risultato.

  [Ulteriori informazioni](https://valkey.io/commands/georadiusbymember/)
+ `GEORADIUSBYMEMBER_RO`

  Restituisce i membri di un indice geospaziale che si trovano entro una distanza da un membro.

  [Ulteriori informazioni](https://valkey.io/commands/georadiusbymember_ro/)
+ `GEOSEARCH`

  Esegue le query su un indice geospaziale per i membri presenti all'interno dell'area di un riquadro o di un cerchio.

  [Ulteriori informazioni](https://valkey.io/commands/geosearch/)
+ `GEOSEARCHSTORE`

  Esegue le query su un indice geospaziale per i membri presenti all'interno dell'area di un riquadro o di un cerchio e facoltativamente archivia il risultato.

  [Ulteriori informazioni](https://valkey.io/commands/geosearchstore/)

**Comandi hash**
+ `HDEL`

  Elimina da un hash uno o più campi e i relativi valori. Elimina l'hash se non rimane alcun campo.

  [Ulteriori informazioni](https://valkey.io/commands/hdel/)
+ `HEXISTS`

  Determina se un campo è presente in un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hexists/)
+ `HGET`

  Restituisce il valore di un campo in un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hget/)
+ `HGETALL`

  Restituisce tutti i campi e i valori in un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hgetall/)
+ `HINCRBY`

  Incrementa di un numero il valore intero di un campo in un hash. Utilizza 0 come valore iniziale se il campo non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/hincrby/)
+ `HINCRBYFLOAT`

  Incrementa di un numero il valore in virgola mobile di un campo. Utilizza 0 come valore iniziale se il campo non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/hincrbyfloat/)
+ `HKEYS`

  Restituisce tutti i campi in un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hkeys/)
+ `HLEN`

  Restituisce il numero di campi in un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hlen/)
+ `HMGET`

  Restituisce i valori di tutti i campi in un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hmget/)
+ `HMSET`

  Imposta i valori di più campi.

  [Ulteriori informazioni](https://valkey.io/commands/hmset/)
+ `HRANDFIELD`

  Restituisce uno o più campi casuali di un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hrandfield/)
+ `HSCAN`

  Esegue l'iterazione dei campi e dei valori di un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hscan/)
+ `HSET`

  Crea o modifica il valore di un campo in un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hset/)
+ `HSETNX`

  Imposta il valore di un campo in un hash solo quando il campo non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/hsetnx/)
+ `HSTRLEN`

  Restituisce la lunghezza del valore di un campo.

  [Ulteriori informazioni](https://valkey.io/commands/hstrlen/)
+ `HVALS`

  Restituisce tutti i valori in un hash.

  [Ulteriori informazioni](https://valkey.io/commands/hvals/)

**HyperLogLog Comandi**
+ `PFADD`

  Aggiunge elementi a una chiave. HyperLogLog Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/pfadd/)
+ `PFCOUNT`

  Restituisce la cardinalità approssimativa degli insiemi osservati dalle HyperLogLog chiavi.

  [Ulteriori informazioni](https://valkey.io/commands/pfcount/)
+ `PFMERGE`

  Unisce uno o più HyperLogLog valori in un'unica chiave.

  [Ulteriori informazioni](https://valkey.io/commands/pfmerge/)

**Comandi di elenco**
+ `BLMOVE`

  Visualizza l'elemento di un elenco, lo inserisce in un altro elenco e lo restituisce. Si blocca finché un elemento non è disponibile. Elimina l'elenco se l'ultimo elemento è stato spostato.

  [Ulteriori informazioni](https://valkey.io/commands/blmove/)
+ `BLMPOP`

  Visualizza il primo elemento da uno degli elenchi. Si blocca finché un elemento non è disponibile. Elimina l'elenco se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/blmpop/)
+ `BLPOP`

  Rimuove e restituisce il primo elemento di un elenco. Si blocca finché un elemento non è disponibile. Elimina l'elenco se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/blpop/)
+ `BRPOP`

  Rimuove e restituisce l'ultimo elemento di un elenco. Si blocca finché un elemento non è disponibile. Elimina l'elenco se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/brpop/)
+ `BRPOPLPUSH`

  Visualizza l'elemento di un elenco, lo inserisce in un altro elenco e lo restituisce. Si blocca finché un elemento non è disponibile. Elimina l'elenco se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/brpoplpush/)
+ `LINDEX`

  Restituisce un elemento di un elenco in base all'indice.

  [Ulteriori informazioni](https://valkey.io/commands/lindex/)
+ `LINSERT`

  Inserisce un elemento prima o dopo un altro elemento di un elenco.

  [Ulteriori informazioni](https://valkey.io/commands/linsert/)
+ `LLEN`

  Restituisce la lunghezza di un elenco.

  [Ulteriori informazioni](https://valkey.io/commands/llen/)
+ `LMOVE`

  Restituisce l'elemento di un elenco dopo averlo visualizzato e spostato in un altro. Elimina l'elenco se l'ultimo elemento è stato spostato.

  [Ulteriori informazioni](https://valkey.io/commands/lmove/)
+ `LMPOP`

  Restituisce più elementi di un elenco dopo averli rimossi. Elimina l'elenco se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/lmpop/)
+ `LPOP`

  Restituisce i primi elementi di un elenco dopo averlo rimosso. Elimina l'elenco se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/lpop/)
+ `LPOS`

  Restituisce l'indice degli elementi corrispondenti di un elenco.

  [Ulteriori informazioni](https://valkey.io/commands/lpos/)
+ `LPUSH`

  Antepone uno o più elementi a un elenco. Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/lpush/)
+ `LPUSHX`

  Antepone uno o più elementi a un elenco solo quando l'elenco esiste.

  [Ulteriori informazioni](https://valkey.io/commands/lpushx/)
+ `LRANGE`

  Restituisce un intervallo di elementi di un elenco.

  [Ulteriori informazioni](https://valkey.io/commands/lrange/)
+ `LREM`

  Rimuove gli elementi da un elenco. Elimina l'elenco se l'ultimo elemento è stato rimosso.

  [Ulteriori informazioni](https://valkey.io/commands/lrem/)
+ `LSET`

  Imposta il valore di un elemento in un elenco in base al relativo indice.

  [Ulteriori informazioni](https://valkey.io/commands/lset/)
+ `LTRIM`

  Rimuove gli elementi all'inizio e alla fine di un elenco. Elimina l'elenco se tutti gli elementi sono stati tagliati.

  [Ulteriori informazioni](https://valkey.io/commands/ltrim/)
+ `RPOP`

  Restituisce e rimuove gli ultimi elementi di un elenco. Elimina l'elenco se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/rpop/)
+ `RPOPLPUSH`

  Restituisce l'ultimo elemento di un elenco dopo averlo rimosso e inserito in un altro elenco. Elimina l'elenco se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/rpoplpush/)
+ `RPUSH`

  Aggiunge uno o più elementi a un elenco. Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/rpush/)
+ `RPUSHX`

  Aggiunge un elemento a un elenco solo quando l'elenco esiste.

  [Ulteriori informazioni](https://valkey.io/commands/rpushx/)

**Comandi Pub/Sub**

**Nota**  
I comandi PUBSUB utilizzano internamente PUBSUB partizionato, pertanto i nomi dei canali sono combinati.
+ `PUBLISH`

  Invia un messaggio a un canale.

  [Ulteriori informazioni](https://valkey.io/commands/publish/)
+ `PUBSUB CHANNELS`

  Restituisce i canali attivi.

  [Ulteriori informazioni](https://valkey.io/commands/pubsub-channels/)
+ `PUBSUB NUMSUB`

  Restituisce il numero di abbonati ai canali.

  [Ulteriori informazioni](https://valkey.io/commands/pubsub-numsub/)
+ `PUBSUB SHARDCHANNELS`

  Restituisce i canali di partizione attivi.

  [Ulteriori informazioni](https://valkey.io/commands/pubsub-shardchannels/)
+ `PUBSUB SHARDNUMSUB`

  Restituisce il numero di abbonati ai canali di partizione.

  [Ulteriori informazioni](https://valkey.io/commands/pubsub-shardnumsub/)
+ `SPUBLISH`

  Invia un messaggio a un canale di partizione.

  [Ulteriori informazioni](https://valkey.io/commands/spublish/)
+ `SSUBSCRIBE`

  Ascolta i messaggi pubblicati sui canali di partizione.

  [Ulteriori informazioni](https://valkey.io/commands/ssubscribe/)
+ `SUBSCRIBE`

  Ascolta i messaggi pubblicati sui canali.

  [Ulteriori informazioni](https://valkey.io/commands/subscribe/)
+ `SUNSUBSCRIBE`

  Interrompe l'ascolto dei messaggi pubblicati sui canali di partizione.

  [Ulteriori informazioni](https://valkey.io/commands/sunsubscribe/)
+ `UNSUBSCRIBE`

  Interrompe l'ascolto dei messaggi pubblicati sui canali.

  [Ulteriori informazioni](https://valkey.io/commands/unsubscribe/)

**Comandi di scripting**
+ `EVAL`

  Esegue uno script Lua lato server.

  [Ulteriori informazioni](https://valkey.io/commands/eval/)
+ `EVAL_RO`

  Esegue uno script Lua lato server di sola lettura.

  [Ulteriori informazioni](https://valkey.io/commands/eval_ro/)
+ `EVALSHA`

  Esegue uno script Lua sul lato server tramite digest. SHA1 

  [Ulteriori informazioni](https://valkey.io/commands/evalsha/)
+ `EVALSHA_RO`

  Esegue uno script Lua lato server di sola lettura tramite digest. SHA1 

  [Ulteriori informazioni](https://valkey.io/commands/evalsha_ro/)
+ `SCRIPT EXISTS`

  Determina se esistono script Lua lato server nella cache degli script.

  [Ulteriori informazioni](https://valkey.io/commands/script-exists/)
+ `SCRIPT FLUSH`

  Attualmente la cache degli script no-op è gestita dal servizio. 

  [Ulteriori informazioni](https://valkey.io/commands/script-flush/)
+ `SCRIPT LOAD`

  Carica uno script Lua lato server nella cache degli script.

  [Ulteriori informazioni](https://valkey.io/commands/script-load/)

**Comandi di gestione del server**

**Nota**  
Quando si utilizzano ElastiCache cluster basati su nodi per Valkey e Redis OSS, i comandi flush devono essere inviati a ogni primario dal client per cancellare tutte le chiavi. ElastiCache Serverless per Valkey e Redis OSS funziona in modo diverso, perché astrae la topologia del cluster sottostante. Il risultato è che in ElastiCache Serverless `FLUSHALL` i comandi svuoteranno sempre tutte `FLUSHDB` le chiavi del cluster. Per questo motivo, i comandi flush non possono essere inclusi in una transazione Serverless. 
+ `ACL CAT`

  Elenca le categorie ACL o i comandi all'interno di una categoria.

  [Ulteriori informazioni](https://valkey.io/commands/acl-cat/)
+ `ACL GENPASS`

  Genera una password pseudocasuale e sicura che può essere utilizzata per identificare gli utenti ACL.

  [Ulteriori informazioni](https://valkey.io/commands/acl-genpass/)
+ `ACL GETUSER`

  Elenca le regole ACL di un utente.

  [Ulteriori informazioni](https://valkey.io/commands/acl-getuser/)
+ `ACL LIST`

  Esegue il dump delle regole valide nel formato di file ACL.

  [Ulteriori informazioni](https://valkey.io/commands/acl-list/)
+ `ACL USERS`

  Elenca tutti gli utenti ACL.

  [Ulteriori informazioni](https://valkey.io/commands/acl-users/)
+ `ACL WHOAMI`

  Restituisce il nome utente autenticato della connessione corrente.

  [Ulteriori informazioni](https://valkey.io/commands/acl-whoami/)
+ `DBSIZE`

  Restituisce il numero di chiavi nel database attualmente selezionato. Non si garantisce che questa operazione sia atomica su tutti gli slot.

  [Ulteriori informazioni](https://valkey.io/commands/dbsize/)
+ `COMMAND`

  Restituisce informazioni dettagliate su tutti i comandi.

  [Ulteriori informazioni](https://valkey.io/commands/command/)
+ `COMMAND COUNT`

  Restituisce un numero di comandi.

  [Ulteriori informazioni](https://valkey.io/commands/command-count/)
+ `COMMAND DOCS`

  Restituisce informazioni documentarie su uno, molteplici o tutti i comandi.

  [Ulteriori informazioni](https://valkey.io/commands/command-docs/)
+ `COMMAND GETKEYS`

  Estrae i nomi delle chiavi da un comando arbitrario.

  [Ulteriori informazioni](https://valkey.io/commands/command-getkeys/)
+ `COMMAND GETKEYSANDFLAGS`

  Estrae i nomi delle chiavi e i flag di accesso per un comando arbitrario.

  [Ulteriori informazioni](https://valkey.io/commands/command-getkeysandflags/)
+ `COMMAND INFO`

  Restituisce informazioni su uno, molteplici o tutti i comandi.

  [Ulteriori informazioni](https://valkey.io/commands/command-info/)
+ `COMMAND LIST`

  Restituisce un elenco di nomi di comando.

  [Ulteriori informazioni](https://valkey.io/commands/command-list/)
+ `COMMANDLOG`

  Un contenitore per i comandi del registro dei comandi.

  [Ulteriori informazioni](https://valkey.io/commands/commandlog/)
+ `COMMANDLOG GET`

  Restituisce le voci del registro dei comandi specificato.

  [Ulteriori informazioni](https://valkey.io/commands/commandlog-get/)
+ `COMMANDLOG HELP`

  Mostra testo utile sui diversi sottocomandi.

  [Ulteriori informazioni](https://valkey.io/commands/commandlog-help/)
+ `COMMANDLOG LEN`

  Restituisce il numero di voci nel tipo di registro dei comandi specificato.

  [Ulteriori informazioni](https://valkey.io/commands/commandlog-len/)
+ `COMMANDLOG RESET`

  Cancella tutte le voci dal tipo di registro dei comandi specificato.

  [Ulteriori informazioni](https://valkey.io/commands/commandlog-reset/)
+ `FLUSHALL`

  Rimuove tutte le chiavi da tutti i database. Non si garantisce che questa operazione sia atomica su tutti gli slot. 

  [Ulteriori informazioni](https://valkey.io/commands/flushall/)
+ `FLUSHDB`

  Rimuove tutte le chiavi dal database corrente. Non si garantisce che questa operazione sia atomica su tutti gli slot.

  [Ulteriori informazioni](https://valkey.io/commands/flushdb/)
+ `INFO`

  Restituisce informazioni e statistiche sul server.

  [Ulteriori informazioni](https://valkey.io/commands/info/)
+ `LOLWUT`

  Visualizza la grafica del computer e la versione Valkey o Redis OSS.

  [Ulteriori informazioni](https://valkey.io/commands/lolwut/)
+ `ROLE`

  Restituisce il ruolo di replica.

  [Ulteriori informazioni](https://valkey.io/commands/role/)
+ `TIME`

  Restituisce l'ora del server.

  [Ulteriori informazioni](https://valkey.io/commands/time/)

**Comandi di set**
+ `SADD`

  Aggiunge uno o più membri a un set. Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/sadd/)
+ `SCARD`

  Restituisce il numero di membri di un set.

  [Ulteriori informazioni](https://valkey.io/commands/scard/)
+ `SDIFF`

  Restituisce la differenza di più set.

  [Ulteriori informazioni](https://valkey.io/commands/sdiff/)
+ `SDIFFSTORE`

  Archivia la differenza di più set in una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/sdiffstore/)
+ `SINTER`

  Restituisce l'intersezione di più set.

  [Ulteriori informazioni](https://valkey.io/commands/sinter/)
+ `SINTERCARD`

  Restituisce il numero di membri dell'intersezione di più set.

  [Ulteriori informazioni](https://valkey.io/commands/sintercard/)
+ `SINTERSTORE`

  Archivia l'intersezione di più set in una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/sinterstore/)
+ `SISMEMBER`

  Determina se un membro appartiene a un set.

  [Ulteriori informazioni](https://valkey.io/commands/sismember/)
+ `SMEMBERS`

  Restituisce tutti i membri di un set.

  [Ulteriori informazioni](https://valkey.io/commands/smembers/)
+ `SMISMEMBER`

  Determina se più membri appartengono a un set.

  [Ulteriori informazioni](https://valkey.io/commands/smismember/)
+ `SMOVE`

  Sposta un membro da un set all'altro.

  [Ulteriori informazioni](https://valkey.io/commands/smove/)
+ `SPOP`

  Restituisce uno o più membri casuali di un set dopo averli rimossi. Elimina il set se l'ultimo membro è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/spop/)
+ `SRANDMEMBER`

  Ottiene uno o più membri casuali da un set.

  [Ulteriori informazioni](https://valkey.io/commands/srandmember/)
+ `SREM`

  Rimuove uno o più membri da un set. Elimina il set se l'ultimo membro è stato rimosso.

  [Ulteriori informazioni](https://valkey.io/commands/srem/)
+ `SSCAN`

  Esegue l'iterazione dei membri di un set.

  [Ulteriori informazioni](https://valkey.io/commands/sscan/)
+ `SUNION`

  Restituisce l'unione di più set.

  [Ulteriori informazioni](https://valkey.io/commands/sunion/)
+ `SUNIONSTORE`

  Archivia l'unione di più set in una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/sunionstore/)

**Comandi di set ordinati**
+ `BZMPOP`

  Rimuove e restituisce un membro in base al punteggio da uno o più set ordinati. Si blocca finché un membro non è disponibile. Elimina il set ordinato se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/bzmpop/)
+ `BZPOPMAX`

  Rimuove e restituisce il membro con il punteggio più alto da uno o più set ordinati. Si blocca finché un membro non è disponibile. Elimina il set ordinato se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/bzpopmax/)
+ `BZPOPMIN`

  Rimuove e restituisce il membro con il punteggio più basso da uno o più set ordinati. Si blocca finché un membro non è disponibile. Elimina il set ordinato se l'ultimo elemento è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/bzpopmin/)
+ `ZADD`

  Aggiunge uno o più membri a un set ordinato oppure ne aggiorna i punteggi. Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/zadd/)
+ `ZCARD`

  Restituisce il numero di membri di un set ordinato.

  [Ulteriori informazioni](https://valkey.io/commands/zcard/)
+ `ZCOUNT`

  Restituisce il numero di membri di un set ordinato con il punteggio compreso in un intervallo.

  [Ulteriori informazioni](https://valkey.io/commands/zcount/)
+ `ZDIFF`

  Restituisce la differenza tra più set ordinati.

  [Ulteriori informazioni](https://valkey.io/commands/zdiff/)
+ `ZDIFFSTORE`

  Archivia la differenza di più set ordinati in una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/zdiffstore/)
+ `ZINCRBY`

  Incrementa il punteggio di un membro in un set ordinato.

  [Ulteriori informazioni](https://valkey.io/commands/zincrby/)
+ `ZINTER`

  Restituisce l'intersezione di più set ordinati.

  [Ulteriori informazioni](https://valkey.io/commands/zinter/)
+ `ZINTERCARD`

  Restituisce il numero di membri dell'intersezione di più set ordinati.

  [Ulteriori informazioni](https://valkey.io/commands/zintercard/)
+ `ZINTERSTORE`

  Archivia l'intersezione di più set ordinati in una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/zinterstore/)
+ `ZLEXCOUNT`

  Restituisce il numero di membri di un set ordinato in un intervallo lessicografico.

  [Ulteriori informazioni](https://valkey.io/commands/zlexcount/)
+ `ZMPOP`

  Restituisce i membri con il punteggio più alto o più basso di uno o più set ordinati dopo averli rimossi. Elimina il set ordinato se l'ultimo membro è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/zmpop/)
+ `ZMSCORE`

  Restituisce il punteggio di uno o più membri di un set ordinato.

  [Ulteriori informazioni](https://valkey.io/commands/zmscore/)
+ `ZPOPMAX`

  Restituisce i membri con il punteggio più alto di un set ordinato dopo averli rimossi. Elimina il set ordinato se l'ultimo membro è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/zpopmax/)
+ `ZPOPMIN`

  Restituisce i membri con il punteggio più basso di un set ordinato dopo averli rimossi. Elimina il set ordinato se l'ultimo membro è stato visualizzato.

  [Ulteriori informazioni](https://valkey.io/commands/zpopmin/)
+ `ZRANDMEMBER`

  Restituisce uno o più membri casuali di un set ordinato.

  [Ulteriori informazioni](https://valkey.io/commands/zrandmember/)
+ `ZRANGE`

  Restituisce i membri di un set ordinato in un intervallo di indici.

  [Ulteriori informazioni](https://valkey.io/commands/zrange/)
+ `ZRANGEBYLEX`

  Restituisce i membri di un set ordinato in un intervallo lessicografico.

  [Ulteriori informazioni](https://valkey.io/commands/zrangebylex/)
+ `ZRANGEBYSCORE`

  Restituisce i membri di un set ordinato in un intervallo di punteggi.

  [Ulteriori informazioni](https://valkey.io/commands/zrangebyscore/)
+ `ZRANGESTORE`

  Archivia in una chiave un intervallo di membri di un set ordinato.

  [Ulteriori informazioni](https://valkey.io/commands/zrangestore/)
+ `ZRANK`

  Restituisce l'indice di un membro in un set ordinato per punteggi in ordine crescente.

  [Ulteriori informazioni](https://valkey.io/commands/zrank/)
+ `ZREM`

  Rimuove uno o più membri da un set ordinato. Elimina il set ordinato se tutti i membri sono stati rimossi.

  [Ulteriori informazioni](https://valkey.io/commands/zrem/)
+ `ZREMRANGEBYLEX`

  Rimuove i membri di un set ordinato in un intervallo lessicografico. Elimina il set ordinato se tutti i membri sono stati rimossi.

  [Ulteriori informazioni](https://valkey.io/commands/zremrangebylex/)
+ `ZREMRANGEBYRANK`

  Rimuove i membri di un set ordinato in un intervallo di indici. Elimina il set ordinato se tutti i membri sono stati rimossi.

  [Ulteriori informazioni](https://valkey.io/commands/zremrangebyrank/)
+ `ZREMRANGEBYSCORE`

  Rimuove i membri di un set ordinato in un intervallo di punteggi. Elimina il set ordinato se tutti i membri sono stati rimossi.

  [Ulteriori informazioni](https://valkey.io/commands/zremrangebyscore/)
+ `ZREVRANGE`

  Restituisce i membri di un set ordinato in un intervallo di indici in ordine inverso.

  [Ulteriori informazioni](https://valkey.io/commands/zrevrange/)
+ `ZREVRANGEBYLEX`

  Restituisce i membri di un set ordinato in un intervallo lessicografico in ordine inverso.

  [Ulteriori informazioni](https://valkey.io/commands/zrevrangebylex/)
+ `ZREVRANGEBYSCORE`

  Restituisce i membri di un set ordinato in un intervallo di punteggi in ordine inverso.

  [Ulteriori informazioni](https://valkey.io/commands/zrevrangebyscore/)
+ `ZREVRANK`

  Restituisce l'indice di un membro in un set ordinato per punteggi in ordine decrescente.

  [Ulteriori informazioni](https://valkey.io/commands/zrevrank/)
+ `ZSCAN`

  Esegue l'iterazione dei membri e dei punteggi di un set ordinato.

  [Ulteriori informazioni](https://valkey.io/commands/zscan/)
+ `ZSCORE`

  Restituisce il punteggio di un membro in un set ordinato.

  [Ulteriori informazioni](https://valkey.io/commands/zscore/)
+ `ZUNION`

  Restituisce l'unione di più set ordinati.

  [Ulteriori informazioni](https://valkey.io/commands/zunion/)
+ `ZUNIONSTORE`

  Archivia l'unione di più set ordinati in una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/zunionstore/)

**Comandi di flusso**
+ `XACK`

  Restituisce il numero di messaggi confermati dal membro del gruppo di consumer di un flusso.

  [Ulteriori informazioni](https://valkey.io/commands/xack/)
+ `XADD`

  Aggiunge un nuovo messaggio a un flusso. Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/xadd/)
+ `XAUTOCLAIM`

  Cambia o acquisisce la proprietà dei messaggi in un gruppo di consumer, come se i messaggi fossero recapitati a un membro del gruppo di consumer.

  [Ulteriori informazioni](https://valkey.io/commands/xautoclaim/)
+ `XCLAIM`

  Cambia o acquisisce la proprietà di un messaggio in un gruppo di consumer, come se il messaggio fosse stato recapitato a un membro del gruppo di consumer.

  [Ulteriori informazioni](https://valkey.io/commands/xclaim/)
+ `XDEL`

  Restituisce il numero di messaggi dopo averli rimossi da un flusso.

  [Ulteriori informazioni](https://valkey.io/commands/xdel/)
+ `XGROUP CREATE`

  Crea un gruppo di consumer. 

  [Ulteriori informazioni](https://valkey.io/commands/xgroup-create/)
+ `XGROUP CREATECONSUMER`

  Crea un consumer in un gruppo di consumer.

  [Ulteriori informazioni](https://valkey.io/commands/xgroup-createconsumer/)
+ `XGROUP DELCONSUMER`

  Elimina un consumer da un gruppo di consumer.

  [Ulteriori informazioni](https://valkey.io/commands/xgroup-delconsumer/)
+ `XGROUP DESTROY`

  Distrugge un gruppo di consumer.

  [Ulteriori informazioni](https://valkey.io/commands/xgroup-destroy/)
+ `XGROUP SETID`

  Imposta l'ultimo ID fornito di un gruppo di consumer.

  [Ulteriori informazioni](https://valkey.io/commands/xgroup-setid/)
+ `XINFO CONSUMERS`

  Restituisce l'elenco dei consumer di un gruppo di consumer.

  [Ulteriori informazioni](https://valkey.io/commands/xinfo-consumers/)
+ `XINFO GROUPS`

  Restituisce l'elenco dei gruppi di consumer di un flusso.

  [Ulteriori informazioni](https://valkey.io/commands/xinfo-groups/)
+ `XINFO STREAM`

  Restituisce le informazioni su un flusso.

  [Ulteriori informazioni](https://valkey.io/commands/xinfo-stream/)
+ `XLEN`

  Restituisce il numero dei messaggi in un flusso.

  [Ulteriori informazioni](https://valkey.io/commands/xlen/)
+ `XPENDING`

  Restituisce le informazioni e le voci dell'elenco delle voci in sospeso di un gruppo di consumer di un flusso.

  [Ulteriori informazioni](https://valkey.io/commands/xpending/)
+ `XRANGE`

  Restituisce i messaggi da uno stream all'interno di un intervallo di. IDs

  [Ulteriori informazioni](https://valkey.io/commands/xrange/)
+ `XREAD`

  Restituisce messaggi da più stream con IDs un numero maggiore di quelli richiesti. Si blocca finché un messaggio non è disponibile.

  [Ulteriori informazioni](https://valkey.io/commands/xread/)
+ `XREADGROUP`

  Restituisce i messaggi nuovi o storici di un flusso per un consumer di un gruppo. Si blocca finché un messaggio non è disponibile.

  [Ulteriori informazioni](https://valkey.io/commands/xreadgroup/)
+ `XREVRANGE`

  Restituisce i messaggi da uno stream all'interno di un intervallo IDs in ordine inverso.

  [Ulteriori informazioni](https://valkey.io/commands/xrevrange/)
+ `XTRIM`

  Elimina i messaggi dall'inizio di un flusso.

  [Ulteriori informazioni](https://valkey.io/commands/xtrim/)

**Comandi di stringa**
+ `APPEND`

  Aggiunge una stringa al valore di una chiave. Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/append/)
+ `DECR`

  Diminuisce di uno il valore intero di una chiave. Utilizza 0 come valore iniziale se la chiave non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/decr/)
+ `DECRBY`

  Diminuisce di un numero il valore intero di una chiave. Utilizza 0 come valore iniziale se la chiave non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/decrby/)
+ `GET`

  Restituisce il valore di stringa di una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/get/)
+ `GETDEL`

  Restituisce il valore di stringa di una chiave dopo l'eliminazione della chiave.

  [Ulteriori informazioni](https://valkey.io/commands/getdel/)
+ `GETEX`

  Restituisce il valore di stringa di una chiave dopo averne impostato l'ora di scadenza.

  [Ulteriori informazioni](https://valkey.io/commands/getex/)
+ `GETRANGE`

  Restituisce una sottostringa della stringa archiviata in una chiave.

  [Ulteriori informazioni](https://valkey.io/commands/getrange/)
+ `GETSET`

  Restituisce il valore di stringa precedente di una chiave dopo averla impostata su un nuovo valore.

  [Ulteriori informazioni](https://valkey.io/commands/getset/)
+ `INCR`

  Incrementa di uno il valore intero di una chiave. Utilizza 0 come valore iniziale se la chiave non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/incr/)
+ `INCRBY`

  Incrementa di un numero il valore intero di una chiave. Utilizza 0 come valore iniziale se la chiave non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/incrby/)
+ `INCRBYFLOAT`

  Incrementa di un numero il valore in virgola mobile di una chiave. Utilizza 0 come valore iniziale se la chiave non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/incrbyfloat/)
+ `LCS`

  Trova la sottostringa comune più lunga.

  [Ulteriori informazioni](https://valkey.io/commands/lcs/)
+ `MGET`

  Restituisce atomicamente i valori di stringa di una o più chiavi.

  [Ulteriori informazioni](https://valkey.io/commands/mget/)
+ `MSET`

  Crea o modifica atomicamente i valori di stringa di una o più chiavi.

  [Ulteriori informazioni](https://valkey.io/commands/mset/)
+ `MSETNX`

  Modifica atomicamente i valori di stringa di una o più chiavi solo quando non esistono tutte le chiavi.

  [Ulteriori informazioni](https://valkey.io/commands/msetnx/)
+ `PSETEX`

  Imposta il valore di stringa e l'ora di scadenza in millisecondi di una chiave. La chiave viene creata se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/psetex/)
+ `SET`

  Imposta il valore di stringa di una chiave, ignorandone il tipo. La chiave viene creata se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/set/)
+ `SETEX`

  Imposta il valore di stringa e l'ora di scadenza di una chiave. Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/setex/)
+ `SETNX`

  Imposta il valore di stringa di una chiave solo quando la chiave non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/setnx/)
+ `SETRANGE`

  Sovrascrive una parte del valore di stringa mediante un offset. Crea la chiave, se non esiste.

  [Ulteriori informazioni](https://valkey.io/commands/setrange/)
+ `STRLEN`

  Restituisce la lunghezza di un valore di stringa.

  [Ulteriori informazioni](https://valkey.io/commands/strlen/)
+ `SUBSTR`

  Restituisce una sottostringa da un valore di stringa.

  [Ulteriori informazioni](https://valkey.io/commands/substr/)

**Comandi di transazione**
+ `DISCARD`

  Elimina una transazione.

  [Ulteriori informazioni](https://valkey.io/commands/discard/)
+ `EXEC`

  Esegue tutti i comandi in una transazione.

  [Ulteriori informazioni](https://valkey.io/commands/exec/)
+ `MULTI`

  Inizia una transazione.

  [Ulteriori informazioni](https://valkey.io/commands/multi/)

## Comandi Valkey e Redis OSS con restrizioni
<a name="RestrictedCommandsRedis"></a>

Per offrire un'esperienza di servizio gestito, ElastiCache limita l'accesso a determinati comandi specifici del motore di cache che richiedono privilegi avanzati. Per le cache che eseguono Redis OSS, i seguenti comandi non sono disponibili:
+ `acl setuser`
+ `acl load`
+ `acl save`
+ `acl deluser`
+ `bgrewriteaof`
+ `bgsave`
+ `cluster addslot`
+ `cluster addslotsrange`
+ `cluster bumpepoch`
+ `cluster delslot`
+ `cluster delslotsrange `
+ `cluster failover `
+ `cluster flushslots `
+ `cluster forget `
+ `cluster links`
+ `cluster meet`
+ `cluster setslot`
+ `config`
+ `debug`
+ `migrate`
+ `psync`
+ `replicaof`
+ `save`
+ `slaveof`
+ `shutdown`
+ `sync`

Inoltre, i seguenti comandi non sono disponibili per le cache serverless:
+ `acl log`
+ `client caching`
+ `client getredir`
+ `client id`
+ `client info`
+ `client kill`
+ `client list`
+ `client no-evict`
+ `client pause`
+ `client tracking`
+ `client trackinginfo`
+ `client unblock`
+ `client unpause`
+ `cluster count-failure-reports`
+ `commandlog`
+ `commandlog get`
+ `commandlog help`
+ `commandlog len`
+ `commandlog reset`
+ `fcall`
+ `fcall_ro`
+ `function`
+ `function delete`
+ `function dump`
+ `function flush`
+ `function help`
+ `function kill`
+ `function list`
+ `function load`
+ `function restore`
+ `function stats`
+ `keys`
+ `lastsave`
+ `latency`
+ `latency doctor`
+ `latency graph`
+ `latency help`
+ `latency histogram`
+ `latency history`
+ `latency latest`
+ `latency reset`
+ `memory`
+ `memory doctor`
+ `memory help`
+ `memory malloc-stats`
+ `memory purge`
+ `memory stats`
+ `memory usage`
+ `monitor`
+ `move`
+ `object`
+ `object encoding`
+ `object freq`
+ `object help`
+ `object idletime`
+ `object refcount`
+ `pfdebug`
+ `pfselftest`
+ `psubscribe`
+ `pubsub numpat`
+ `punsubscribe`
+ `script kill`
+ `slowlog`
+ `slowlog get`
+ `slowlog help`
+ `slowlog len`
+ `slowlog reset`
+ `swapdb`
+ `wait`

## Comandi Memcached supportati
<a name="SupportedCommandsMem"></a>

ElastiCache Serverless for Memcached supporta tutti i [comandi](https://github.com/memcached/memcached/wiki/Commands) memcached in memcached 1.6 open source ad eccezione dei seguenti: 
+ Le connessioni client richiedono TLS, di conseguenza il protocollo UDP non è supportato.
+ Il protocollo binario non è supportato, in quanto è ufficialmente [obsoleto](https://github.com/memcached/memcached/wiki/ReleaseNotes160) in memcached 1.6.
+ I comandi `GET/GETS` sono limitati a 16 KB per evitare potenziali attacchi DoS al server con il recupero di un numero elevato di chiavi.
+ Il comando `flush_all` ritardato verrà rifiutato con `CLIENT_ERROR`.
+ I comandi che configurano il motore o rivelano informazioni interne sullo stato o sui log del motore non sono supportati, ad esempio:
  + Per il comando `STATS` sono supportati solo `stats` e `stats reset`. Altre varianti restituiscono `ERROR`.
  + `lru / lru_crawler`: modifica delle impostazioni per LRU e crawler LRU.
  + `watch`: controlla i log del server memcached.
  + `verbosity`: configura il livello di log del server.
  + `me`- il comando meta debug (me) non è supportato

# Configurazione e limiti di Valkey e Redis OSS
<a name="RedisConfiguration"></a>

I motori Valkey e Redis OSS forniscono ciascuno una serie di parametri di configurazione, alcuni dei quali sono modificabili in Redis OSS e altri non sono modificabili ElastiCache per fornire prestazioni e affidabilità stabili.

## Cache serverless
<a name="RedisConfiguration.Serverless"></a>

Per le cache serverless, i gruppi di parametri non vengono utilizzati e tutte le configurazioni di Valkey o Redis OSS non sono modificabili. Sono presenti i seguenti parametri Valkey o Redis OSS:


****  

|  Name  |  Informazioni  |  Description  | 
| --- | --- | --- | 
| acl-pubsub-default | `allchannels` | Le autorizzazioni predefinite del canale pubsub per gli utenti ACL nella cache. | 
| client-output-buffer-limit | `normal 0 0 0` `pubsub 32mb 8mb 60` | I client normali non hanno limiti di buffer. PUB/SUB i client verranno disconnessi se violano il backlog di 32 MiB o violano il backlog di 8 MiB per 60 minuti. | 
| client-query-buffer-limit | 1 GiB | La dimensione massima di un singolo buffer di query dei client. Inoltre, i client non possono emettere una richiesta con più di 3.999 argomenti. | 
| cluster-allow-pubsubshard-when-down | yes | In tal modo la cache può servire il traffico pubsub mentre è parzialmente inattiva. | 
| cluster-allow-reads-when-down | yes | In tal modo la cache può servire il traffico di lettura mentre è parzialmente inattiva. | 
| cluster-enabled | yes | Tutte le cache serverless sono abilitate alla modalità cluster, che consente loro di partizionare in modo trasparente i dati su più partizioni di back-end. Tutti gli slot vengono mostrati ai client come fossero di proprietà di un singolo nodo virtuale. | 
| cluster-require-full-coverage | no | Quando il keyspace è parzialmente inattivo (ovvero almeno uno slot hash è inaccessibile), la cache continua ad accettare le query per la parte del keyspace ancora coperta. L'intero keyspace sarà sempre "coperto" da un singolo nodo virtuale in cluster slots. | 
| lua-time-limit | 5000 | Il tempo massimo di esecuzione per uno script Lua, in millisecondi, prima che venga eseguita l'azione ElastiCache necessaria per arrestare lo script. *Se `lua-time-limit` viene superato, tutti i comandi Valkey o Redis OSS possono restituire un errore nel formato \$1\$1\$1\$1-BUSY.* *Poiché questo stato può causare interferenze con molte operazioni essenziali di Valkey o Redis OSS, ElastiCache emetterà prima un comando SCRIPT KILL.* Se ciò non riesce, ElastiCache riavvierà forzatamente Valkey o Redis OSS. | 
| maxclients | 65000 | Il numero massimo di client che possono essere connessi contemporaneamente alla cache. Le altre connessioni possono essere o meno completate. | 
| maxmemory-policy | volatile-lru | Gli elementi con un set TTL vengono eliminati in base alla stima least-recently-used (LRU) quando viene raggiunto il limite di memoria della cache. | 
| notify-keyspace-events | Stringa vuota | Gli eventi del keyspace non sono attualmente supportati nelle cache serverless. | 
| port | Porta principale: 6379 Porta di lettura: 6380 | Le cache serverless pubblicizzano due porte con lo stesso nome host. La porta principale consente scritture e letture, mentre la porta di lettura consente le letture a coerenza finale con una latenza inferiore utilizzando il comando READONLY. | 
| proto-max-bulk-len | 512 MiB | La dimensione massima di una singola richiesta di elementi. | 
| timeout | 0 | La disconnessione dei client non viene forzata per un determinato periodo di inattività, ma può essere eseguita durante lo stato stazionario a beneficio del sistema di bilanciamento del carico. | 

Inoltre, sono applicati i limiti seguenti:


****  

|  Name  |  Informazioni  |  Description  | 
| --- | --- | --- | 
| Dimensioni per cache | 5.000 GiB | Quantità massima di dati che è possibile archiviare per cache serverless. | 
| Dimensioni per slot | 32 GiB | La dimensione massima di un singolo slot hash Valkey o Redis OSS. I client che cercano di impostare più dati di questi su un singolo slot Valkey o Redis OSS attiveranno la politica di espulsione sullo slot e, se nessuna chiave è eliminabile, riceveranno un errore out of memory (). OOM | 
| ECPU per cache | 15.000.000 di ECPU/secondo | ElastiCache Metrica delle unità di elaborazione (ECPU). Il numero di dati ECPUs consumati dalle tue richieste dipende dal tempo impiegato dalla vCPU e dalla quantità di dati trasferiti. | 
| ECPU per slot | 30.000 - 90.000 ECPU/secondo | Massimo 30.000 ECPUs/second per slot o 90.000 se si utilizza Read from Replica utilizzando connessioni ECPUs/second READONLY. | 
| Argomenti per richiesta | 3.999 | Numero massimo di argomenti per richiesta. I client che inviano più argomenti per richiesta riceveranno un errore. | 
| Lunghezza del nome della chiave | 4 KiB | La dimensione massima per una singola chiave Valkey o Redis OSS o nome di canale. I client che fanno riferimento a chiavi di dimensioni superiori restituiscono un errore. | 
| Dimensione dello script Lua | 4 MiB | La dimensione massima di un singolo script Valkey o Redis OSS Lua. I tentativi di caricare uno script Lua più grande restituiscono un errore. | 

## Cluster basati su nodi
<a name="RedisConfiguration.SelfDesigned"></a>

Per i cluster basati su nodi, vedere [Parametri Valkey e Redis OSS](ParameterGroups.Engine.md#ParameterGroups.Redis) i valori predefiniti dei parametri di configurazione e quali sono configurabili. I valori predefiniti sono generalmente consigliati a meno che non si abbia un caso d'uso specifico che ne richieda la sostituzione.

# IPv6 esempi di client per Valkey, Memcached e Redis OSS
<a name="network-type-best-practices"></a>

ElastiCache è compatibile con Valkey, Memcached e Redis OSS. Ciò significa che i client che supportano IPv6 le connessioni dovrebbero essere in grado di connettersi ai cluster IPv6 Enabled ElastiCache for Memcached. Ci sono alcune avvertenze che vale la pena notare quando si interagisce con risorse abilitate. IPv6 

È possibile visualizzare il post di blog [sulle migliori pratiche per i clienti Valkey e Redis](https://aws.amazon.com/blogs/database/best-practices-redis-clients-and-amazon-elasticache-for-redis/) sul blog AWS Database per consigli sulla configurazione dei client Valkey e Redis OSS per le risorse. ElastiCache 

Di seguito sono riportate le migliori pratiche per interagire con le ElastiCache risorse IPv6 abilitate con le librerie client open source di uso comune. 

## Client convalidati con Valkey e Redis OSS
<a name="network-type-validated-clients-redis"></a>

ElastiCache è compatibile con Valkey e Redis OSS open source. Ciò significa che Valkey e i client Redis OSS open source che supportano IPv6 le connessioni dovrebbero essere in grado di connettersi a cluster IPv6 Enabled ElastiCache for Redis OSS. Inoltre, molti dei client Python e Java più diffusi sono stati specificamente testati e convalidati per funzionare con tutte le configurazioni di tipo di rete supportate (IPv4 solo, IPv6 solo e Dual Stack)

I seguenti client sono stati specificamente convalidati per funzionare con tutte le configurazioni dei tipi di rete supportate per Valkey e Redis OSS.

Clienti convalidati:
+ [Redis Py ()](https://github.com/redis/redis-py) – [4,1.2](https://github.com/redis/redis-py/tree/v4.1.2)
+ [Lettuce](https://lettuce.io/) – [Versione: 6.1.6.RELEASE](https://github.com/lettuce-io/lettuce-core/tree/6.1.6.RELEASE)
+ [Jedis](https://github.com/redis/jedis) – [Versione: 3.6.0](https://github.com/redis/jedis/tree/jedis-3.6.0)

# Le migliori pratiche per i clienti (Valkey e Redis OSS)
<a name="BestPractices.Clients.redis"></a>

Scopri le best practice per gli scenari più comuni e segui gli esempi di codice di alcune delle più popolari librerie client open source Valkey e Redis OSS (redis-py e Lettuce) PHPRedis, nonché le migliori pratiche per interagire con le risorse con ElastiCache le librerie client Memcached open source di uso comune.

**Topics**
+ [Grande numero di connessioni (Valkey e Redis OSS)](BestPractices.Clients.Redis.Connections.md)
+ [Individuazione e backoff esponenziale dei client del cluster (Valkey e Redis OSS)](BestPractices.Clients.Redis.Discovery.md)
+ [Configurazione di un timeout lato client (Valkey e Redis OSS)](BestPractices.Clients.Redis.ClientTimeout.md)
+ [Configurazione di un timeout di inattività lato server (Valkey e Redis OSS)](BestPractices.Clients.Redis.ServerTimeout.md)
+ [Script Lua](BestPractices.Clients.Redis.LuaScripts.md)
+ [Archiviazione di elementi compositi di grandi dimensioni (Valkey e Redis OSS)](BestPractices.Clients.Redis.LargeItems.md)
+ [Configurazione del client Lettuce (Valkey e Redis OSS)](BestPractices.Clients-lettuce.md)
+ [Configurazione di un protocollo preferito per i cluster dual stack (Valkey e Redis OSS)](#network-type-configuring-dual-stack-redis)

# Grande numero di connessioni (Valkey e Redis OSS)
<a name="BestPractices.Clients.Redis.Connections"></a>

Le cache serverless e individuali ElastiCache per i nodi Redis OSS supportano fino a 65.000 connessioni client simultanee. Tuttavia, per ottimizzare le prestazioni, consigliamo che le applicazioni client non operino costantemente a un livello così elevato. Valkey e Redis OSS dispongono ciascuno di un processo a thread singolo basato su un ciclo di eventi in cui le richieste dei client in entrata vengono gestite in sequenza. Ciò significa che il tempo di risposta di un determinato client si allunga con l'aumento del numero di client connessi.

È possibile eseguire la seguente serie di azioni per evitare di imbattersi in un collo di bottiglia di connessione su un server Valkey o Redis OSS:
+ Esegui le operazioni di lettura dalle repliche di lettura. Ciò può essere fatto utilizzando gli endpoint di ElastiCache lettura in modalità cluster disattivata o utilizzando repliche per le letture in modalità cluster abilitata, inclusa una cache serverless.
+ Distribuisci il traffico di scrittura su più nodi primari. Sono disponibili due modi per farlo: È possibile utilizzare un cluster Valkey o Redis OSS con più sharded con un client compatibile con la modalità cluster. puoi scrivere su più nodi primari in modalità cluster disabilitata con il partizionamento lato client. Questa operazione viene eseguita automaticamente in una cache serverless.
+ Usa un pool di connessioni quando disponibile nella libreria client.

In generale, la creazione di una connessione TCP è un'operazione computazionalmente costosa rispetto ai tipici comandi Valkey o Redis OSS. Ad esempio, la gestione di una SET/GET richiesta è un ordine di grandezza più veloce quando si riutilizza una connessione esistente. L'uso di un pool di connessioni client di dimensioni limitate riduce il sovraccarico della gestione delle connessioni. Inoltre, limita il numero di connessioni simultanee in entrata dell'applicazione client.

Il seguente esempio di codice PHPRedis mostra che viene creata una nuova connessione per ogni nuova richiesta utente:

```
$redis = new Redis();
if ($redis->connect($HOST, $PORT) != TRUE) {
	//ERROR: connection failed
	return;
}
$redis->set($key, $value);
unset($redis);
$redis = NULL;
```

Abbiamo confrontato questo codice in un ciclo su un'istanza Amazon Elastic Compute Cloud (Amazon EC2) connessa a un nodo Graviton2 (m6g.2xlarge) per Redis OSS. ElastiCache Abbiamo posizionato il client e il server nella stessa zona di disponibilità. La latenza media dell'intera operazione è stata di 2,82 millisecondi.

Quando abbiamo aggiornato il codice e utilizzato le connessioni persistenti e un pool di connessioni, la latenza media dell'intera operazione è stata di 0,21 millisecondi:

```
$redis = new Redis();
if ($redis->pconnect($HOST, $PORT) != TRUE) {
	// ERROR: connection failed
	return;
}
$redis->set($key, $value);
unset($redis);
$redis = NULL;
```

Configurazioni di redis.ini richieste:
+ `redis.pconnect.pooling_enabled=1`
+ `redis.pconnect.connection_limit=10`

Il codice seguente è un esempio di [pool di connessioni Redis-py](https://redis.readthedocs.io/en/stable/):

```
conn = Redis(connection_pool=redis.BlockingConnectionPool(host=HOST, max_connections=10))
conn.set(key, value)
```

Il codice seguente è un esempio di [pool di connessioni Lettuce](https://lettuce.io/core/release/reference/#_connection_pooling):

```
RedisClient client = RedisClient.create(RedisURI.create(HOST, PORT));
GenericObjectPool<StatefulRedisConnection> pool = ConnectionPoolSupport.createGenericObjectPool(() -> client.connect(), new GenericObjectPoolConfig());
pool.setMaxTotal(10); // Configure max connections to 10
try (StatefulRedisConnection connection = pool.borrowObject()) {
	RedisCommands syncCommands = connection.sync();
	syncCommands.set(key, value);
}
```

# Individuazione e backoff esponenziale dei client del cluster (Valkey e Redis OSS)
<a name="BestPractices.Clients.Redis.Discovery"></a>

Quando ci si connette a un cluster ElastiCache Valkey o Redis OSS in modalità cluster abilitata, la libreria client corrispondente deve essere in grado di riconoscere il cluster. I client devono ottenere una mappa degli slot hash ai nodi corrispondenti del cluster per inviare le richieste ai nodi giusti ed evitare il sovraccarico delle prestazioni dovuto alla gestione dei reindirizzamenti del cluster. Di conseguenza, il client deve ottenere l'elenco completo degli slot e dei nodi mappati in due diverse situazioni:
+ Il client è inizializzato e deve compilare la configurazione iniziale degli slot.
+ Il server riceve un reindirizzamento MOVED, ad esempio in caso di failover in cui tutti gli slot serviti dal precedente nodo primario vengono acquisiti dalla replica oppure in caso di ripartizionamento quando gli slot vengono spostati dal nodo primario di origine al nodo primario di destinazione.

L'individuazione dei client viene in genere effettuata tramite l'emissione di un comando CLUSTER SLOT o CLUSTER NODE al server Valkey o Redis OSS. Consigliamo il metodo CLUSTER SLOT perché restituisce al client il set di intervalli di slot e i nodi primari e di replica associati. Questo metodo non richiede un'analisi aggiuntiva da parte del client ed è più efficiente.

A seconda della topologia del cluster, la dimensione della risposta per il comando CLUSTER SLOT può variare in base alla dimensione del cluster. I cluster più grandi con più nodi producono una risposta di dimensione maggiore. Di conseguenza, è importante garantire che il numero di client che eseguono l'individuazione della topologia del cluster non cresca in modo illimitato. Ad esempio, quando l'applicazione client avvia o perde la connessione del server e deve eseguire l'individuazione del cluster, un errore comune è che l'applicazione client generi diverse richieste di riconnessione e individuazione senza aggiungere un backoff esponenziale al momento del nuovo tentativo. Ciò può impedire al server Valkey o Redis OSS di rispondere per un periodo di tempo prolungato, con un utilizzo della CPU al 100%. L'interruzione si prolunga se ogni comando CLUSTER SLOT deve elaborare un numero elevato di nodi nel bus del cluster. In passato abbiamo osservato diverse interruzioni dei client a causa di questo comportamento in diversi linguaggi, tra cui Python redis-py-cluster () e Java (Lettuce e Redisson).

In una cache serverless, molti problemi vengono mitigati automaticamente perché la topologia del cluster pubblicizzata è statica ed è composta da due elementi: un endpoint di scrittura e un endpoint di lettura. L'individuazione del cluster viene inoltre distribuita automaticamente su più nodi quando si utilizza l'endpoint di cache. I seguenti suggerimenti sono tuttavia utili.

Per mitigare l'impatto causato da un afflusso improvviso di richieste di connessione e individuazione, ti consigliamo di procedere come segue:
+ Implementa un pool di connessioni client di dimensioni limitate per contenere il numero di connessioni simultanee in entrata dell'applicazione client.
+ Quando il client si disconnette dal server a causa di un timeout, riprova con un backoff esponenziale con jitter. In tal modo eviti che più client sovraccarichino il server contemporaneamente.
+ Utilizza le indicazioni contenute in [Ricerca degli endpoint di connessione in ElastiCache](Endpoints.md) per trovare l'endpoint del cluster ed eseguire l'individuazione del cluster. In questo modo, distribuisci il carico dell'individuazione su tutti i nodi del cluster (fino a 90) invece di usare i pochi nodi di inizializzazione codificati nel cluster.

Di seguito sono riportati alcuni esempi di codice per la logica esponenziale dei tentativi di backoff in redis-py e Lettuce. PHPRedis

**Esempio 1 di logica di backoff: redis-py**

redis-py ha un meccanismo di ripetizione dei tentativi integrato che ripete il tentativo una volta subito dopo l'errore. [Questo meccanismo può essere abilitato tramite l'`retry_on_timeout`argomento fornito durante la creazione di un oggetto Redis OSS.](https://redis.readthedocs.io/en/stable/examples/connection_examples.html#redis.Redis) Di seguito è illustrato un meccanismo di ripetizione dei tentativi personalizzato con backoff esponenziale e jitter. Inviamo una richiesta pull per implementare in modo nativo il backoff esponenziale in [redis-py (\$11494)](https://github.com/andymccurdy/redis-py/pull/1494). In futuro potrebbe non essere necessario implementarlo manualmente.

```
def run_with_backoff(function, retries=5):
base_backoff = 0.1 # base 100ms backoff
max_backoff = 10 # sleep for maximum 10 seconds
tries = 0
while True:
try:
  return function()
except (ConnectionError, TimeoutError):
  if tries >= retries:
	raise
  backoff = min(max_backoff, base_backoff * (pow(2, tries) + random.random()))
  print(f"sleeping for {backoff:.2f}s")
  sleep(backoff)
  tries += 1
```

Quindi puoi utilizzare il codice seguente per impostare un valore:

```
client = redis.Redis(connection_pool=redis.BlockingConnectionPool(host=HOST, max_connections=10))
res = run_with_backoff(lambda: client.set("key", "value"))
print(res)
```

A seconda del carico di lavoro, è possibile modificare il valore di backoff di base da 1 secondo a poche decine o centinaia di millisecondi per i carichi di lavoro sensibili alla latenza.

**Esempio di logica di backoff 2: PHPRedis**

PHPRedis dispone di un meccanismo di riprova integrato che riprova un massimo di 10 volte (non configurabile). Si verifica un ritardo configurabile tra i tentativi (con un jitter dal secondo tentativo in poi). Per ulteriori informazioni, consulta il seguente [codice di esempio](https://github.com/phpredis/phpredis/blob/b0b9dd78ef7c15af936144c1b17df1a9273d72ab/library.c#L335-L368). [Abbiamo inviato una pull request per implementare nativamente il backoff esponenziale in [PHPredis (\$11986)](https://github.com/phpredis/phpredis/pull/1986), che da allora è stata unita e documentata.](https://github.com/phpredis/phpredis/blob/develop/README.md#retry-and-backoff) Per chi utilizza l'ultima versione di PHPRedis, non sarà necessario implementarlo manualmente, ma abbiamo incluso qui il riferimento per quelli delle versioni precedenti. Il seguente è un esempio di codice che configura il ritardo del meccanismo di ripetizione dei tentativi:

```
$timeout = 0.1; // 100 millisecond connection timeout
$retry_interval = 100; // 100 millisecond retry interval
$client = new Redis();
if($client->pconnect($HOST, $PORT, $timeout, NULL, $retry_interval) != TRUE) {
	return; // ERROR: connection failed
}
$client->set($key, $value);
```

**Esempio 3 di logica di backoff: Lettuce**

Lettuce dispone di meccanismi di ripetizione dei tentativi incorporati basati sulle strategie di backoff esponenziale descritte nel post [Exponential Backoff and Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/). Di seguito è riportato un estratto di codice che mostra l'approccio completo del jitter:

```
public static void main(String[] args)
{
	ClientResources resources = null;
	RedisClient client = null;

	try {
		resources = DefaultClientResources.builder()
				.reconnectDelay(Delay.fullJitter(
			Duration.ofMillis(100),     // minimum 100 millisecond delay
			Duration.ofSeconds(5),      // maximum 5 second delay
			100, TimeUnit.MILLISECONDS) // 100 millisecond base
		).build();

		client = RedisClient.create(resources, RedisURI.create(HOST, PORT));
		client.setOptions(ClientOptions.builder()
	.socketOptions(SocketOptions.builder().connectTimeout(Duration.ofMillis(100)).build()) // 100 millisecond connection timeout
	.timeoutOptions(TimeoutOptions.builder().fixedTimeout(Duration.ofSeconds(5)).build()) // 5 second command timeout
	.build());

	    // use the connection pool from above example
	} finally {
		if (connection != null) {
			connection.close();
		}

		if (client != null){
			client.shutdown();
		}

		if (resources != null){
			resources.shutdown();
		}

	}
}
```

# Configurazione di un timeout lato client (Valkey e Redis OSS)
<a name="BestPractices.Clients.Redis.ClientTimeout"></a>

**Configurazione del timeout lato client**

Configura il timeout lato client in modo appropriato per assegnare al server il tempo sufficiente per elaborare la richiesta e generare la risposta. Ciò consente inoltre di anticipare l'errore (fail fast) se non è possibile stabilire la connessione al server. Alcuni comandi Valkey o Redis OSS possono essere più costosi dal punto di vista computazionale rispetto ad altri. Ad esempio, script o MULTI/EXEC transazioni Lua che contengono più comandi che devono essere eseguiti atomicamente. In generale, si consiglia un timeout lato client più elevato per evitare il timeout del client prima che la risposta venga ricevuta dal server, tra cui i seguenti scenari:
+ Esecuzione di comandi su più chiavi
+ Esecuzione di MULTI/EXEC transazioni o script Lua costituiti da più comandi singoli Valkey o Redis OSS
+ Lettura di valori di grandi dimensioni
+ Esecuzione di operazioni di blocco come BLPOP

Nel caso di un'operazione di blocco come BLPOP, la best practice consiste nell'impostare il timeout del comando su un valore inferiore al timeout del socket.

Di seguito sono riportati esempi di codice per l'implementazione di un timeout lato client in redis-py e Lettuce. PHPRedis

**Esempio 1 di configurazione del timeout: redis-py**

Di seguito è riportato un esempio di codice con redis-py:

```
# connect to Redis server with a 100 millisecond timeout
# give every Redis command a 2 second timeout
client = redis.Redis(connection_pool=redis.BlockingConnectionPool(host=HOST, max_connections=10,socket_connect_timeout=0.1,socket_timeout=2))

res = client.set("key", "value") # will timeout after 2 seconds
print(res)                       # if there is a connection error

res = client.blpop("list", timeout=1) # will timeout after 1 second
                                      # less than the 2 second socket timeout
print(res)
```

**Esempio 2 di configurazione di Timeout: PHPRedis**

Di seguito è riportato un esempio di codice con: PHPRedis

```
// connect to Redis server with a 100ms timeout
// give every Redis command a 2s timeout
$client = new Redis();
$timeout = 0.1; // 100 millisecond connection timeout
$retry_interval = 100; // 100 millisecond retry interval
$client = new Redis();
if($client->pconnect($HOST, $PORT, 0.1, NULL, 100, $read_timeout=2) != TRUE){
	return; // ERROR: connection failed
}
$client->set($key, $value);

$res = $client->set("key", "value"); // will timeout after 2 seconds
print "$res\n";                      // if there is a connection error

$res = $client->blpop("list", 1); // will timeout after 1 second
print "$res\n";                   // less than the 2 second socket timeout
```

**Esempio 3 di configurazione del timeout: Lettuce**

Di seguito è riportato un esempio di codice con Lettuce:

```
// connect to Redis server and give every command a 2 second timeout
public static void main(String[] args)
{
	RedisClient client = null;
	StatefulRedisConnection<String, String> connection = null;
	try {
		client = RedisClient.create(RedisURI.create(HOST, PORT));
		client.setOptions(ClientOptions.builder()
	.socketOptions(SocketOptions.builder().connectTimeout(Duration.ofMillis(100)).build()) // 100 millisecond connection timeout
	.timeoutOptions(TimeoutOptions.builder().fixedTimeout(Duration.ofSeconds(2)).build()) // 2 second command timeout 
	.build());

		// use the connection pool from above example

		commands.set("key", "value"); // will timeout after 2 seconds
		commands.blpop(1, "list"); // BLPOP with 1 second timeout
	} finally {
		if (connection != null) {
			connection.close();
		}

		if (client != null){
			client.shutdown();
		}
	}
}
```

# Configurazione di un timeout di inattività lato server (Valkey e Redis OSS)
<a name="BestPractices.Clients.Redis.ServerTimeout"></a>

Abbiamo osservato casi in cui l'applicazione di un cliente ha un numero elevato di client inattivi collegati, ma non invia attivamente comandi. In tali scenari, è possibile esaurire tutte le 65.000 connessioni con un numero elevato di client inattivi. Per evitare tali situazioni, configura l'impostazione del timeout in modo appropriato sul server con i [Parametri Valkey e Redis OSS](ParameterGroups.Engine.md#ParameterGroups.Redis). In tal modo si garantisce che il server disconnetta attivamente i client inattivi per evitare un aumento del numero di connessioni. Questa impostazione non è disponibile nelle cache serverless.

# Script Lua
<a name="BestPractices.Clients.Redis.LuaScripts"></a>

Valkey e Redis OSS supportano più di 200 comandi, inclusi quelli per eseguire gli script Lua. Tuttavia, quando si tratta di script Lua, ci sono diverse insidie che possono influire sulla memoria e sulla disponibilità di Valkey o Redis OSS.

**Script Lua non parametrizzati**

Ogni script Lua viene memorizzato nella cache sul server Valkey o Redis OSS prima di essere eseguito. Gli script Lua non parametrizzati sono unici, il che può portare il server Valkey o Redis OSS a archiviare un gran numero di script Lua e a consumare più memoria. Per mitigare questo problema, assicurati che tutti gli script Lua siano parametrizzati ed esegui regolarmente SCRIPT FLUSH per pulire gli script Lua memorizzati nella cache, se necessario.

Tieni inoltre presente che è necessario fornire le chiavi. Se non viene fornito un valore per il parametro KEY, lo script avrà esito negativo. Ad esempio, questo non funzionerà: 

```
serverless-test-lst4hg.serverless.use1.cache.amazonaws.com:6379> eval 'return "Hello World"' 0
(error) ERR Lua scripts without any input keys are not supported.
```

Funzionerà:

```
serverless-test-lst4hg.serverless.use1.cache.amazonaws.com:6379> eval 'return redis.call("get", KEYS[1])' 1 mykey-2
"myvalue-2"
```

Il codice di esempio seguente mostra come utilizzare gli script parametrizzati. Innanzitutto, abbiamo un esempio di approccio non parametrizzato che non è consigliato e produce tre diversi script Lua memorizzati nella cache:

```
eval "return redis.call('set','key1','1')" 0
eval "return redis.call('set','key2','2')" 0
eval "return redis.call('set','key3','3')" 0
```

Utilizza invece lo schema seguente per creare un singolo script in grado di accettare i parametri passati:

```
eval "return redis.call('set',KEYS[1],ARGV[1])" 1 key1 1 
eval "return redis.call('set',KEYS[1],ARGV[1])" 1 key2 2 
eval "return redis.call('set',KEYS[1],ARGV[1])" 1 key3 3
```

**Script Lua a esecuzione prolungata**

Gli script Lua possono eseguire più comandi in modo atomico, quindi il completamento può richiedere più tempo rispetto a un normale comando Valkey o Redis OSS. Se lo script Lua esegue esclusivamente operazioni di sola lettura, puoi interromperlo a metà. Tuttavia, non appena lo script Lua esegue un'operazione di scrittura, non puoi più interromperlo e deve essere eseguito fino al completamento. Uno script Lua a esecuzione prolungata che sta mutando può far sì che il server Valkey o Redis OSS non risponda per un lungo periodo. Per mitigare questo problema, evita gli script Lua a esecuzione prolungata e testali in un ambiente di preproduzione.

**Script Lua con scritture invisibili**

Esistono alcuni modi in cui uno script Lua può continuare a scrivere nuovi dati in Valkey o Redis OSS anche quando Valkey o Redis OSS sono terminati: `maxmemory`
+ Lo script inizia quando il server Valkey o Redis OSS si trova al di sotto `maxmemory` e contiene più operazioni di scrittura al suo interno
+ Il primo comando di scrittura dello script non consuma memoria (come DEL), le successive operazioni di scrittura consumano memoria.
+ È possibile mitigare questo problema configurando una politica di sfratto adeguata in un server Valkey o Redis OSS diverso da. `noeviction` Ciò consente a Redis OSS di eliminare gli elementi e liberare memoria tra gli script Lua.

# Archiviazione di elementi compositi di grandi dimensioni (Valkey e Redis OSS)
<a name="BestPractices.Clients.Redis.LargeItems"></a>

In alcuni scenari, un'applicazione può archiviare elementi compositi di grandi dimensioni in Valkey o Redis OSS (come un set di dati hash da più GB). Questa non è una pratica consigliata perché spesso causa problemi di prestazioni in Valkey o Redis OSS. Ad esempio, il client può eseguire un comando HGETALL per recuperare l'intera raccolta di hash da più GB. Ciò può generare una notevole pressione sulla memoria del server Valkey o Redis OSS che memorizza nel buffer di output dell'elemento di grandi dimensioni nel buffer di output del client. Inoltre, per la migrazione degli slot in modalità cluster, ElastiCache non esegue la migrazione degli slot che contengono elementi con dimensioni serializzate superiori a 256 MB.

Per risolvere i problemi relativi agli elementi di grandi dimensioni, tieni in considerazione i seguenti suggerimenti:
+ Suddividi l'elemento composito di grandi dimensioni in più elementi più piccoli. Ad esempio, suddividi una raccolta di hash di grandi dimensioni in singoli campi chiave-valore con uno schema di nome della chiave che rifletta in modo appropriato la raccolta, ad esempio utilizzando un prefisso comune nel nome della chiave per identificare la raccolta di elementi. Se è necessario accedere atomicamente a più campi della stessa raccolta, è possibile utilizzare il comando MGET per recuperare più chiavi-valori nello stesso comando.
+ Se hai valutato tutte le opzioni ma non riesci ancora a suddividere il set di dati della raccolta di grandi dimensioni, prova a utilizzare comandi che operano su un sottoinsieme dei dati della raccolta anziché sull'intera raccolta. Evita il caso d'uso che richiede il recupero atomico dell'intera raccolta da più GB con lo stesso comando. Un esempio è l'utilizzo del comando HGET o HMGET anziché HGETALL nelle raccolte di hash.

# Configurazione del client Lettuce (Valkey e Redis OSS)
<a name="BestPractices.Clients-lettuce"></a>

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.

**Topics**
+ [Esempio: configurazione Lettuce per la modalità cluster, TLS abilitato](BestPractices.Clients-lettuce-cme.md)
+ [Esempio: configurazione Lettuce per la modalità cluster disattivata, TLS abilitato](BestPractices.Clients-lettuce-cmd.md)

**TTL della cache DNS Java**

Java Virtual Machine (JVM) memorizza nella cache le ricerche dei nomi DNS. Quando la JVM risolve un nome host in un indirizzo IP, memorizza l'indirizzo IP nella cache per un periodo di tempo specificato, noto come (TTL). *time-to-live*

La scelta di un valore TTL è un compromesso tra latenza e reattività al cambiamento. Con tempi più brevi TTLs, i resolver DNS notano gli aggiornamenti nel DNS del cluster più velocemente. 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 il TTL è troppo basso, aumenta il volume delle query, il che può aumentare la latenza dell'applicazione. Sebbene non esista un valore TTL corretto, quando si imposta il valore TTL è opportuno valutare il tempo che è possibile attendere affinché una modifica abbia effetto.

Poiché ElastiCache i nodi utilizzano voci di nome DNS che potrebbero cambiare, consigliamo di configurare la JVM con un TTL basso, compreso tra 5 e 10 secondi. In tal modo si garantisce che quando l'indirizzo IP di un nodo cambia, l'applicazione potrà ricevere e utilizzare il nuovo indirizzo IP della risorsa richiedendo la voce DNS.

In alcune configurazioni Java, il TTL predefinito di JVM è impostato in modo da non aggiornare mai le voci DNS finché JVM non viene riavviato.

Per dettagli su come impostare il TTL JVM, consulta [How to set the JVM TTL](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-jvm-ttl.html#how-to-set-the-jvm-ttl) (Come impostare il TTL JVM).

**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 ricerca DNS per questo URI restituisce un elenco di tutti i nodi disponibili nel cluster e viene risolta casualmente in 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 le [KeepAlive](https://lettuce.io/core/release/api/io/lettuce/core/SocketOptions.KeepAliveOptions.html). 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](https://lettuce.io/core/release/api/io/lettuce/core/SocketOptions.Builder.html#connectTimeout-java.time.Duration-) 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 [AutoReconnect](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterClientOptions.Builder.html#autoReconnect-boolean-)caso di interruzione della connessione.

Imposta [CommandTimeout](https://lettuce.io/core/release/api/io/lettuPrce/core/RedisURI.html#getTimeout--). Per ulteriori dettagli, consulta la sezione relativa ai timeout più avanti in questo argomento.

Impostare [NodeFilter](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterClientOptions.Builder.html#nodeFilter-java.util.function.Predicate-) per filtrare i nodi non riusciti dalla topologia. Lettuce salva tutti i nodi che si trovano nell'output dei "nodi del cluster" (inclusi i nodi con stato PFAIL/FAIL) nelle "partizioni" del client (note anche come partizioni). 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, al termine di un failover e quando il cluster avvia il processo di ripristino, mentre clusterTopology si aggiorna, la mappa dei nodi del bus del cluster prevede un breve periodo di tempo in cui il nodo inattivo viene elencato come nodo non riuscito (FAIL), prima che venga completamente rimosso dalla topologia. Durante questo periodo, il client Lettuce lo considera un nodo sano 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 [Ricerca degli endpoint (console) del cluster Valkey o Redis OSS (modalità cluster disabilitata)](Endpoints.md#Endpoints.Find.Redis).  
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 le [enablePeriodicRefresh](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.Builder.html#enablePeriodicRefresh-java.time.Duration-). Ciò consente aggiornamenti periodici della topologia del cluster in modo che il client aggiorni la topologia del cluster negli intervalli 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.

Abilita le [enableAllAdaptiveRefreshTriggers](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.Builder.html#enableAllAdaptiveRefreshTriggers--). Ciò consente l'aggiornamento adattivo della topologia che utilizza tutti i [trigger](https://lettuce.io/core/6.1.6.RELEASE/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.RefreshTrigger.html): MOVED\$1REDIRECT, ASK\$1REDIRECT, PERSISTENT\$1RECONNECTS, UNCOVERED\$1SLOT, UNKNOWN\$1NODE. I trigger di aggiornamento adattivi avviano gli aggiornamenti della visualizzazione della topologia in base agli eventi che si verificano durante le operazioni del 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 le [closeStaleConnections](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.Builder.html#closeStaleConnections-boolean-). Ciò consente di chiudere le connessioni obsolete durante l'aggiornamento della topologia del cluster. [Entra in vigore solo se. ClusterTopologyRefreshOptions isPeriodicRefreshEnabled ()](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.html#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 le [dynamicRefreshResources](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.Builder.html#dynamicRefreshSources-boolean-). 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 [DnsResolver](https://lettuce.io/core/release/api/io/lettuce/core/resource/DefaultClientResources.Builder.html#dnsResolver-io.lettuce.core.resource.DnsResolver-) con [DirContextDnsResolver](https://lettuce.io/core/release/api/io/lettuce/core/resource/DirContextDnsResolver.html). Il resolver DNS è basato su com.sun.jndi.dns di Java. DnsContextFactory.

Configurazione di [reconnectDelay](https://lettuce.io/core/release/api/io/lettuce/core/resource/DefaultClientResources.Builder.html#reconnectDelay-io.lettuce.core.resource.Delay-) con backoff esponenziale e jitter completo. Lettuce ha meccanismi di ripetizione incorporati basati sulle strategie di backoff esponenziale. Per maggiori dettagli, consulta [Exponential Backoff and Jitter](https://aws.amazon.com/blogs/architecture/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](https://aws.amazon.com/blogs/database/best-practices-redis-clients-and-amazon-elasticache-for-redis/) 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, utilizzare un timeout più lungo per i comandi che iterano su più chiavi, come FLUSHDB, FLUSHALL, KEYS, SMEMBERS o gli script Lua. Utilizzare timeout più brevi per i comandi a chiave singola, come SET, GET e HSET.

**Nota**  
I timeout configurati nell'esempio seguente riguardano i test che eseguono comandi SET/GET 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();
```

# Esempio: configurazione Lettuce per la modalità cluster, TLS abilitato
<a name="BestPractices.Clients-lettuce-cme"></a>

**Nota**  
I timeout nell'esempio seguente riguardano i test che eseguono SET/GET comandi 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. 

```
// Set DNS cache TTL
public void setJVMProperties() {
    java.security.Security.setProperty("networkaddress.cache.ttl", "10");
}

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

// Create RedisURI from the cluster configuration endpoint
clusterConfigurationEndpoint = <cluster-configuration-endpoint> // TODO: add your cluster configuration endpoint
final RedisURI redisUriCluster =
    RedisURI.Builder.redis(clusterConfigurationEndpoint)
        .withPort(6379)
        .withSsl(true)
        .build();

// Configure the client's resources                
ClientResources clientResources = DefaultClientResources.builder()
    .reconnectDelay(
        Delay.fullJitter(
            Duration.ofMillis(100),     // minimum 100 millisecond delay
            Duration.ofSeconds(10),      // maximum 10 second delay
            100, TimeUnit.MILLISECONDS)) // 100 millisecond base
    .dnsResolver(new DirContextDnsResolver())
    .build(); 

// Create a cluster client instance with the URI and resources
RedisClusterClient redisClusterClient = 
    RedisClusterClient.create(clientResources, redisUriCluster);

// Use a dynamic timeout for commands, to avoid timeouts during
// cluster management and slow operations.
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 metaCommandTimeout;
    private final Duration defaultCommandTimeout;

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

TimeoutOptions timeoutOptions = TimeoutOptions.builder()
    .timeoutSource(new DynamicClusterTimeout(DEFAULT_COMMAND_TIMEOUT, META_COMMAND_TIMEOUT))
     .build();

// Configure the topology refreshment options
final ClusterTopologyRefreshOptions topologyOptions = 
    ClusterTopologyRefreshOptions.builder()
    .enableAllAdaptiveRefreshTriggers()
    .enablePeriodicRefresh()
    .dynamicRefreshSources(true)
    .build();

// Configure the socket options
final SocketOptions socketOptions = 
    SocketOptions.builder()
    .connectTimeout(CONNECT_TIMEOUT) 
    .keepAlive(true)
    .build();

// Configure the client's options
final ClusterClientOptions clusterClientOptions = 
    ClusterClientOptions.builder()
    .topologyRefreshOptions(topologyOptions)
    .socketOptions(socketOptions)
    .autoReconnect(true)
    .timeoutOptions(timeoutOptions) 
    .nodeFilter(it -> 
        ! (it.is(RedisClusterNode.NodeFlag.FAIL) 
        || it.is(RedisClusterNode.NodeFlag.EVENTUAL_FAIL) 
        || it.is(RedisClusterNode.NodeFlag.NOADDR))) 
    .validateClusterNodeMembership(false)
    .build();
    
redisClusterClient.setOptions(clusterClientOptions);

// Get a connection
final StatefulRedisClusterConnection<String, String> connection = 
    redisClusterClient.connect();

// Get cluster sync/async commands   
RedisAdvancedClusterCommands<String, String> sync = connection.sync();
RedisAdvancedClusterAsyncCommands<String, String> async = connection.async();
```

# Esempio: configurazione Lettuce per la modalità cluster disattivata, TLS abilitato
<a name="BestPractices.Clients-lettuce-cmd"></a>

**Nota**  
I timeout nell'esempio seguente riguardano i test che eseguono SET/GET comandi 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. 

```
// Set DNS cache TTL
public void setJVMProperties() {
    java.security.Security.setProperty("networkaddress.cache.ttl", "10");
}

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

// Create RedisURI from the primary/reader endpoint
clusterEndpoint = <primary/reader-endpoint> // TODO: add your node endpoint
RedisURI redisUriStandalone =
    RedisURI.Builder.redis(clusterEndpoint).withPort(6379).withSsl(true).withDatabase(0).build();

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

// Use a dynamic timeout for commands, to avoid timeouts during
// slow operations.
class DynamicTimeout extends TimeoutSource {
     private static final Set<ProtocolKeyword> META_COMMAND_TYPES = ImmutableSet.<ProtocolKeyword>builder()
          .add(CommandType.FLUSHDB)
          .add(CommandType.FLUSHALL)
          .add(CommandType.INFO)
          .add(CommandType.KEYS)
          .build();

    private final Duration metaCommandTimeout;
    private final Duration defaultCommandTimeout;

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

TimeoutOptions timeoutOptions = TimeoutOptions.builder()
    .timeoutSource(new DynamicTimeout(DEFAULT_COMMAND_TIMEOUT, META_COMMAND_TIMEOUT))
     .build();                      
                                    
final SocketOptions socketOptions =
    SocketOptions.builder().connectTimeout(CONNECT_TIMEOUT).keepAlive(true).build();

ClientOptions clientOptions =
    ClientOptions.builder().timeoutOptions(timeoutOptions).socketOptions(socketOptions).build();

RedisClient redisClient = RedisClient.create(clientResources, redisUriStandalone);
redisClient.setOptions(clientOptions);
```

## Configurazione di un protocollo preferito per i cluster dual stack (Valkey e Redis OSS)
<a name="network-type-configuring-dual-stack-redis"></a>

Per i cluster Valkey o Redis OSS abilitati alla modalità cluster, è possibile controllare il protocollo che i client utilizzeranno per connettersi ai nodi del cluster con il parametro IP Discovery. Il parametro IP Discovery può essere impostato su uno o. IPv4 IPv6 

Per i cluster Valkey o Redis OSS, il parametro IP Discovery imposta il protocollo IP utilizzato nell'output degli [slot del cluster ()](https://valkey.io/commands/cluster-slots/), dei [cluster shard ()](https://valkey.io/commands/cluster-shards/) e [dei nodi del cluster](https://valkey.io/commands/cluster-nodes/) (). Questi comandi vengono utilizzati dai client per scoprire la topologia del cluster. I client utilizzano i comandi IPs in theses per connettersi agli altri nodi del cluster. 

La modifica di IP Discovery non comporterà alcun tempo di inattività per i client connessi. Tuttavia, la propagazione delle modifiche richiederà tempo. Per determinare quando le modifiche si sono propagate completamente per un cluster Valkey o Redis OSS, monitora l'output di. `cluster slots` Una volta che tutti i nodi restituiti dal comando cluster slots hanno riportato il nuovo protocollo, IPs le modifiche hanno terminato la propagazione. 

Esempio con Redis-Py:

```
cluster = RedisCluster(host="xxxx", port=6379)
target_type = IPv6Address # Or IPv4Address if changing to IPv4

nodes = set()
while len(nodes) == 0 or not all((type(ip_address(host)) is target_type) for host in nodes):
    nodes = set()

   # This refreshes the cluster topology and will discovery any node updates.
   # Under the hood it calls cluster slots
    cluster.nodes_manager.initialize()
    for node in cluster.get_nodes():
        nodes.add(node.host)
    self.logger.info(nodes)

    time.sleep(1)
```

Esempio con Lettuce:

```
RedisClusterClient clusterClient = RedisClusterClient.create(RedisURI.create("xxxx", 6379));

Class targetProtocolType = Inet6Address.class; // Or Inet4Address.class if you're switching to IPv4

Set<String> nodes;
    
do {
   // Check for any changes in the cluster topology.
   // Under the hood this calls cluster slots
    clusterClient.refreshPartitions();
    Set<String> nodes = new HashSet<>();

    for (RedisClusterNode node : clusterClient.getPartitions().getPartitions()) {
        nodes.add(node.getUri().getHost());
    }

    Thread.sleep(1000);
} while (!nodes.stream().allMatch(node -> {
            try {
                return finalTargetProtocolType.isInstance(InetAddress.getByName(node));
            } catch (UnknownHostException ignored) {}
            return false;
}));
```

# Le migliori pratiche per i clienti (Memcached)
<a name="BestPractices.Clients.memcached"></a>

Scopri le best practice per scenari comuni con i cluster ElastiCache Memcached.

**Topics**
+ [Configurazione ElastiCache del client per un bilanciamento efficiente del carico (Memcached)](BestPractices.LoadBalancing.md)
+ [Client convalidati con Memcached](network-type-validated-clients-memcached.md)
+ [Configurazione di un protocollo preferito per i cluster dual stack (Memcached)](network-type-configuring-dual-stack-memcached.md)

# Configurazione ElastiCache del client per un bilanciamento efficiente del carico (Memcached)
<a name="BestPractices.LoadBalancing"></a>

**Nota**  
Questa sezione si applica ai cluster Memcached multinodo basati su nodi.

Per utilizzare in modo efficace più nodi ElastiCache Memcached, è necessario essere in grado di distribuire le chiavi della cache tra i nodi. *Un modo semplice per bilanciare il carico di un cluster con *n* nodi consiste nel calcolare l'hash della chiave dell'oggetto e modificare il risultato per n:.* `hash(key) mod n` Il valore risultante (da 0 a *n*-1) è il numero del nodo in cui inserisci l'oggetto. 

Questo approccio è semplice ed efficace, purché il numero dei nodi (*n*) sia costante. Quando aggiungi o rimuovi un nodo dal cluster, il numero di chiavi da spostare corrisponde tuttavia a *(n - 1) / n* (dove *n* è il nuovo numero di nodi). Con questo approccio, il numero di chiavi da spostare è pertanto maggiore, con un conseguente numero elevato di mancati riscontri nella cache iniziali, specialmente man mano che aumenta il numero dei nodi. Con il dimensionamento da 1 a 2 nodi, viene spostato un numero di chiavi pari a (2-1)/2 (50 percento), ovvero il caso migliore. Con il dimensionamento da 9 a 10 nodi, viene spostato un numero di chiavi pari a (10-1)/10 (90 percento). In caso di un dimensionamento dovuto a un picco nel traffico, è bene evitare un elevato numero di mancati riscontri nella cache, in quanto ciò causerebbe hit nel database, già sovraccaricato dai picchi di traffico.

La soluzione a tale problema è rappresentata da un hashing coerente, L’hashing coerente utilizza un algoritmo in modo tale che quando un nodo viene aggiunto o rimosso da un cluster, il numero di chiavi da spostare è circa *1/n* (dove *n* è il nuovo numero di nodi). Passando da 1 a 2 nodi, viene spostato un numero di chiavi pari a 1/2 (50 percento), ovvero il caso peggiore. Passando da 9 a 10 nodi, viene spostato un numero di chiavi pari a 1/10 (10 percento).

Sei tu, in qualità di utente, che controlli l'algoritmo di hashing utilizzato per il cluster a più nodi. Ti consigliamo di configurare i client in modo da utilizzare un hashing coerente. Fortunatamente, sono disponibili numerose librerie client Memcached nei linguaggi più comuni in grado di implementare l'hashing coerente. Consulta la documentazione della libreria che utilizzi per verificare se supporta l'hashing coerente e ottenere informazioni su come implementarlo.

Se lavori in Java, PHP o.NET, ti consigliamo di utilizzare una delle librerie ElastiCache client Amazon.

## Hashing coerente in Java
<a name="BestPractices.LoadBalancing.Java"></a>

Il client Java ElastiCache Memcached si basa sul client Java open source spymemcached, che dispone di funzionalità di hashing coerenti integrate. La libreria include una classe che implementa un hashing coerente. KetamaConnectionFactory Per impostazione predefinita, l'hashing coerente è disattivato in spymemcached.

Per ulteriori informazioni, consultate la KetamaConnectionFactory documentazione all'indirizzo. [KetamaConnectionFactory](https://github.com/RTBHOUSE/spymemcached/blob/master/src/main/java/net/spy/memcached/KetamaConnectionFactory.java)

## Hashing coerente con PHP con Memcached
<a name="BestPractices.LoadBalancing.PHP"></a>

Il client PHP ElastiCache Memcached è un wrapper della libreria PHP Memcached integrata. Per impostazione predefinita, l'hashing coerente è disattivato dalla libreria PHP Memcached.

Per attivare l'hashing coerente, utilizza il seguente codice.

```
$m = new Memcached();
$m->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
```

Oltre al codice precedente, ti consigliamo anche di attivare `memcached.sess_consistent_hash` nel file php.ini.

 [Per ulteriori informazioni, consulta la documentazione di configurazione in fase di esecuzione per Memcached PHP all'indirizzo http://php. net/manual/en/memcached.configurazione.php.](http://php.net/manual/en/memcached.configuration.php) Nota in particolare il parametro `memcached.sess_consistent_hash`.

## Hashing coerente utilizzando.NET con Memcached
<a name="BestPractices.LoadBalancing.dotNET"></a>

Il client ElastiCache Memcached .NET è un wrapper per Enyim Memcached. Per impostazione predefinita, l'hashing coerente è attivato dal client Enyim Memcached.

 [Per ulteriori informazioni, consulta la documentazione in -Configuration\$1. `memcached/locator` https://github.com/enyim/ EnyimMemcached/wiki/MemcachedClient user-content-memcachedlocator](https://github.com/enyim/EnyimMemcached/wiki/MemcachedClient-Configuration#user-content-memcachedlocator)

# Client convalidati con Memcached
<a name="network-type-validated-clients-memcached"></a>

I seguenti client sono stati specificamente convalidati per funzionare con tutte le configurazioni dei tipi di rete supportate per Memcached.

Clienti convalidati:
+ [AWS ElastiCache Cluster Client Memcached](https://github.com/awslabs/aws-elasticache-cluster-client-memcached-for-php) [per Php — versione \$13.6.2](https://github.com/awslabs/aws-elasticache-cluster-client-memcached-for-php/tree/v3.2.0)
+ [AWS ElastiCache Cluster Client Memcached](https://github.com/awslabs/aws-elasticache-cluster-client-memcached-for-java) per Java: master più recente su Github

# Configurazione di un protocollo preferito per i cluster dual stack (Memcached)
<a name="network-type-configuring-dual-stack-memcached"></a>

Per cluster Memcached puoi controllare il protocollo che verrà utilizzato dai client per connettersi ai nodi del cluster con il parametro IP Discovery. Il parametro IP Discovery può essere impostato su o. IPv4 IPv6 

Il parametro IP Discovery controlla il protocollo IP utilizzato nell'output del cluster config get. Il che a sua volta determinerà il protocollo IP utilizzato dai client che supportano l'individuazione automatica ElastiCache per i cluster Memcached.

La modifica di IP Discovery non comporterà alcun tempo di inattività per i client connessi. Tuttavia, la propagazione delle modifiche richiederà tempo. 

Monitorare l'output di `getAvailableNodeEndPoints` per Java e per Php monitorare l'output di `getServerList`. Una volta che l'output di queste funzioni riporta i risultati IPs per tutti i nodi del cluster che utilizzano il protocollo aggiornato, le modifiche hanno terminato la propagazione.

Esempio di Java

```
MemcachedClient client = new MemcachedClient(new InetSocketAddress("xxxx", 11211));

Class targetProtocolType = Inet6Address.class; // Or Inet4Address.class if you're switching to IPv4

Set<String> nodes;
    
do {
    nodes = client.getAvailableNodeEndPoints().stream().map(NodeEndPoint::getIpAddress).collect(Collectors.toSet());

    Thread.sleep(1000);
} while (!nodes.stream().allMatch(node -> {
            try {
                return finalTargetProtocolType.isInstance(InetAddress.getByName(node));
            } catch (UnknownHostException ignored) {}
            return false;
        }));
```

Esempio di Php:

```
$client = new Memcached;
$client->setOption(Memcached::OPT_CLIENT_MODE, Memcached::DYNAMIC_CLIENT_MODE);
$client->addServer("xxxx", 11211);

$nodes = [];
$target_ips_count = 0;
do {
    # The PHP memcached client only updates the server list if the polling interval has expired and a
    # command is sent
    $client->get('test');
 
    $nodes = $client->getServerList();

    sleep(1);
    $target_ips_count = 0;

    // For IPv4 use FILTER_FLAG_IPV4
    $target_ips_count = count(array_filter($nodes, function($node) { return filter_var($node["ipaddress"], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); }));
 
} while (count($nodes) !== $target_ips_count);
```

Le eventuali connessioni client esistenti create prima dell'aggiornamento di IP Discovery, verranno comunque connesse utilizzando il vecchio protocollo. Tutti i client convalidati si riconnetteranno automaticamente al cluster utilizzando il nuovo protocollo IP una volta rilevate le modifiche nell'output dei comandi di individuazione del cluster. Tuttavia, ciò dipende dall'implementazione del client.

## Cluster dual ElastiCache stack abilitati per TLS
<a name="network-type-configuring-tls-enabled-dual-stack"></a>

Quando TLS è abilitato per ElastiCache i cluster, le funzioni di rilevamento del cluster (`cluster slots``cluster shards`, e `cluster nodes` per Redis) o `config get cluster`per Memcached restituiscono nomi di host anziché. IPs I nomi host vengono quindi utilizzati anziché per connettersi al cluster ed eseguire IPs un handshake TLS. ElastiCache Ciò significa che i client non sono interessati dal parametro Individuazione IP. Per i cluster abilitati per TLS, il parametro Individuazione IP non ha alcun effetto sul protocollo IP preferito. Invece, il protocollo IP utilizzato verrà determinato in base a quello preferito dal client durante la risoluzione dei nomi host DNS.

**Client Java**

Quando ci si connette da un ambiente Java che supporta entrambi IPv4 e IPv6, IPv6 per impostazione predefinita Java preferisce la compatibilità con le IPv4 versioni precedenti. Tuttavia, la preferenza del protocollo IP è configurabile tramite gli argomenti JVM. Per preferire IPv4, la JVM accetta `-Djava.net.preferIPv4Stack=true` e per preferire impostato. IPv6 `-Djava.net.preferIPv6Stack=true` L'impostazione `-Djava.net.preferIPv4Stack=true` significa che la JVM non effettuerà più alcuna connessione. IPv6 **Per Valkey o Redis OSS, ciò include quelle verso altre applicazioni non Valkey e non Redis OSS.**

**Preferenze a livello di host**

In generale, se il client o il runtime client non forniscono opzioni di configurazione per l'impostazione di una preferenza del protocollo IP, quando si esegue la risoluzione DNS, il protocollo IP dipenderà dalla configurazione dell'host. Per impostazione predefinita, la maggior parte degli host preferisce questa IPv6 preferenza, IPv4 ma questa preferenza può essere configurata a livello di host. Ciò influirà su tutte le richieste DNS provenienti dall'host, non solo su quelle ai ElastiCache cluster.

**Host Linux**

Per Linux, una preferenza protocollo IP può essere configurata modificando il file `gai.conf`. Il file `gai.conf` è disponibile in `/etc/gai.conf`. Se non è specificato alcun `gai.conf`, uno di esempio deve essere disponibile in `/usr/share/doc/glibc-common-x.xx/gai.conf` che può essere copiato in `/etc/gai.conf`; è quindi necessario rimuovere i commenti dalla configurazione predefinita. Per aggiornare la configurazione da preferire IPv4 quando ci si connette a un ElastiCache cluster, aggiorna la precedenza per l'intervallo CIDR che comprende il cluster in modo che sia superiore IPs alla precedenza per le connessioni predefinite. IPv6 Per impostazione predefinita, IPv6 le connessioni hanno una precedenza di 40. Ad esempio, supponendo che il cluster si trovi in una sottorete con CIDR 172.31.0. 0:0 /16, la configurazione seguente farebbe sì che i client preferiscano le connessioni a quel cluster. IPv4 

```
label ::1/128       0
label ::/0          1
label 2002::/16     2
label ::/96         3
label ::ffff:0:0/96 4
label fec0::/10     5
label fc00::/7      6
label 2001:0::/32   7
label ::ffff:172.31.0.0/112 8
#
#    This default differs from the tables given in RFC 3484 by handling
#    (now obsolete) site-local IPv6 addresses and Unique Local Addresses.
#    The reason for this difference is that these addresses are never
#    NATed while IPv4 site-local addresses most probably are.  Given
#    the precedence of IPv6 over IPv4 (see below) on machines having only
#    site-local IPv4 and IPv6 addresses a lookup for a global address would
#    see the IPv6 be preferred.  The result is a long delay because the
#    site-local IPv6 addresses cannot be used while the IPv4 address is
#    (at least for the foreseeable future) NATed.  We also treat Teredo
#    tunnels special.
#
# precedence  <mask>   <value>
#    Add another rule to the RFC 3484 precedence table.  See section 2.1
#    and 10.3 in RFC 3484.  The default is:
#
precedence  ::1/128       50
precedence  ::/0          40
precedence  2002::/16     30
precedence ::/96          20
precedence ::ffff:0:0/96  10
precedence ::ffff:172.31.0.0/112 100
```

[Maggiori dettagli su sono disponibili nella pagina man di Linux `gai.conf`](https://man7.org/linux/man-pages/man5/gai.conf.5.html) 

**Host Windows**

Il processo per gli host Windows è simile. Per gli host Windows è possibile eseguire `netsh interface ipv6 set prefix CIDR_CONTAINING_CLUSTER_IPS PRECEDENCE LABEL`. L'effetto è identico alla modifica del file `gai.conf` su host Linux.

Ciò aggiornerà le politiche di preferenza per preferire IPv4 le connessioni alle IPv6 connessioni per l'intervallo CIDR specificato. Ad esempio, supponendo che il cluster si trovi in una sottorete con esecuzione CIDR 172.31.0. 0:0 /16, `netsh interface ipv6 set prefix ::ffff:172.31.0.0:0/112 100 15` risulterebbe la seguente tabella di precedenza che farebbe sì che i client preferiscano la connessione al cluster. IPv4 

```
C:\Users\Administrator>netsh interface ipv6 show prefixpolicies
Querying active state...

Precedence Label Prefix
---------- ----- --------------------------------
100 15 ::ffff:172.31.0.0:0/112
20 4 ::ffff:0:0/96
50 0 ::1/128
40 1 ::/0
30 2 2002::/16
5 5 2001::/32
3 13 fc00::/7
1 11 fec0::/10
1 12 3ffe::/16
1 3 ::/96
```

# Gestione della memoria riservata per Valkey e Redis OSS
<a name="redis-memory-management"></a>

La memoria prenotata è la memoria destinata all'utilizzo diverso dai dati. Quando si esegue un backup o un failover, Valkey e Redis OSS utilizzano la memoria disponibile per registrare le operazioni di scrittura sul cluster mentre i dati del cluster vengono scritti nel file.rdb. Se non disponi di memoria sufficiente per tutte le scritture, il processo non va a buon fine. Di seguito, è possibile trovare informazioni sulle opzioni per la gestione della memoria riservata ElastiCache per Redis OSS e su come applicarle.

**Topics**
+ [Qual è la quantità di memoria prenotata necessaria?](#redis-memory-management-need)
+ [Parametri per gestire memoria prenotata](#redis-memory-management-parameters)
+ [Specifica del parametro di gestione della memoria prenotata](#redis-reserved-memory-management-change)

## Qual è la quantità di memoria prenotata necessaria?
<a name="redis-memory-management-need"></a>

Se utilizzi una versione di Redis OSS precedente alla 2.8.22, riserva più memoria per i backup e i failover rispetto a Redis OSS 2.8.22 o successiva. Questo requisito è dovuto ai diversi modi in cui Redis OSS implementa il processo di backup. ElastiCache La regola generale consiste nel riservare metà del `maxmemory` valore di un tipo di nodo all'overhead Redis OSS per le versioni precedenti alla 2.8.22 e un quarto per le versioni Redis OSS 2.8.22 e successive. 

A causa delle diverse modalità di ElastiCache implementazione del processo di backup e replica, la regola generale consiste nel riservare il 25% del valore di un tipo di nodo utilizzando il parametro. `maxmemory` `reserved-memory-percent` Questo è il valore predefinito e consigliato nella maggior parte dei casi.

Quando i tipi di istanze micro e piccole istanze burstable funzionano vicino `maxmemory` ai limiti, è possibile che si verifichi l'utilizzo dello swap. Per migliorare l'affidabilità operativa di questi tipi di istanze durante il backup, la replica e il traffico elevato, consigliamo di aumentare il valore del `reserved-memory-percent` parametro fino al 30% sui tipi di istanze di piccole dimensioni e fino al 50% sui tipi di micro istanze.

Per carichi di lavoro impegnativi in scrittura su ElastiCache cluster con tiering dei dati, consigliamo di aumentare la memoria disponibile del nodo fino `reserved-memory-percent` al 50%.

Per ulteriori informazioni, consulta gli argomenti seguenti:
+ [Garantire la disponibilità di memoria sufficiente per creare un'istantanea Valkey o Redis OSS](BestPractices.BGSAVE.md)
+ [Modalità di implementazione di sincronizzazione e backup](Replication.Redis.Versions.md)
+ [Suddivisione dei dati su più livelli in ElastiCache](data-tiering.md)

## Parametri per gestire memoria prenotata
<a name="redis-memory-management-parameters"></a>

A partire dal 16 marzo 2017, Amazon ElastiCache fornisce due parametri che si escludono a vicenda per la gestione della memoria Valkey o Redis OSS e. `reserved-memory` `reserved-memory-percent` Nessuno di questi parametri fa parte della distribuzione Valkey o Redis OSS. 

A seconda di quando sei diventato ElastiCache cliente, l'uno o l'altro di questi parametri è il parametro di gestione della memoria predefinito. Questo parametro si applica quando si crea un nuovo cluster o gruppo di replica Valkey o Redis OSS e si utilizza un gruppo di parametri predefinito. 
+ Per i clienti che hanno iniziato prima del 16 marzo 2017: quando si crea un cluster o un gruppo di replica Redis OSS utilizzando il gruppo di parametri predefinito, il parametro di gestione della memoria è. `reserved-memory` In questo caso, zero (0) byte di memoria sono riservati. 
+ Per i clienti che hanno iniziato il 16 marzo 2017 o dopo tale data: quando si crea un cluster o un gruppo di replica Valkey o Redis OSS utilizzando il gruppo di parametri predefinito, il parametro di gestione della memoria è. `reserved-memory-percent` In questo caso, il 25% del valore `maxmemory` del nodo è riservato per scopi non dati.

Dopo aver letto i due parametri di gestione della memoria Valkey o Redis OSS, potresti preferire utilizzare quello che non è quello predefinito o con valori non predefiniti. In questo caso, puoi passare all'altro parametro di gestione della memoria prenotata. 

Per modificare il valore di tale parametro, è possibile creare un gruppo di parametri personalizzato e modificarlo in modo da utilizzare il parametro e il valore di gestione della memoria preferiti. È quindi possibile utilizzare il gruppo di parametri personalizzato ogni volta che si crea un nuovo cluster o gruppo di replica Valkey o Redis OSS. Per cluster o gruppi di replica esistenti, puoi modificarli per utilizzare il gruppo di parametri personalizzato.

 Per ulteriori informazioni, consulta gli argomenti seguenti: 
+ [Specifica del parametro di gestione della memoria prenotata](#redis-reserved-memory-management-change)
+ [Creazione di un gruppo di ElastiCache parametri](ParameterGroups.Creating.md)
+ [Modifica di un gruppo di ElastiCache parametri](ParameterGroups.Modifying.md)
+ [Modifica di un cluster ElastiCache](Clusters.Modify.md)
+ [Modifica di un gruppo di replica](Replication.Modify.md)

### Il parametro reserved-memory
<a name="redis-memory-management-parameters-reserved-memory"></a>

Prima del 16 marzo 2017, tutta la gestione della memoria riservata ElastiCache per Redis OSS veniva eseguita utilizzando il parametro. `reserved-memory` Il valore di default di `reserved-memory` è 0. Questa impostazione predefinita non riserva memoria per il sovraccarico di Valkey o Redis OSS e consente a Valkey o Redis OSS di consumare tutta la memoria di un nodo con i dati. 

La modifica di `reserved-memory` per disporre di memoria sufficiente per i backup e i failover, richiede la creazione di un gruppo di parametri personalizzato. In questo gruppo di parametri personalizzati, viene impostato `reserved-memory` un valore appropriato per la versione Valkey o Redis OSS in esecuzione sul cluster e il tipo di nodo del cluster. Per ulteriori informazioni, consulta [Qual è la quantità di memoria prenotata necessaria?](#redis-memory-management-need)

Il parametro `reserved-memory` è specifico ElastiCache e non fa parte della distribuzione generale Redis OSS.

La procedura seguente mostra come utilizzare per `reserved-memory` gestire la memoria sul cluster Valkey o Redis OSS.

**Per prenotare la memoria utilizzando la memoria prenotata**

1. Creare un gruppo di parametri personalizzato specificando la famiglia di gruppi di parametri corrispondente alla versione del motore in esecuzione, ad esempio specificando la proprietà`redis2.8`famiglia di gruppi di parametri. Per ulteriori informazioni, consulta [Creazione di un gruppo di ElastiCache parametri](ParameterGroups.Creating.md).

   ```
   aws elasticache create-cache-parameter-group \
      --cache-parameter-group-name redis6x-m3xl \
      --description "Redis OSS 2.8.x for m3.xlarge node type" \
      --cache-parameter-group-family redis6.x
   ```

1. Calcola quanti byte di memoria riservare per il sovraccarico di Valkey o Redis OSS. Il valore di `maxmemory` per il tipo di nodo è disponibile in [Parametri specifici del tipo di nodo Redis OSS](ParameterGroups.Engine.md#ParameterGroups.Redis.NodeSpecific).

1. Modificare il gruppo di parametri personalizzato in modo che il parametro `reserved-memory` corrisponda al numero di byte calcolati nella fase precedente. L' AWS CLI esempio seguente presuppone che tu stia utilizzando una versione di Redis OSS precedente alla 2.8.22 e che sia necessario riservare metà di quella del nodo. `maxmemory` Per ulteriori informazioni, consulta [Modifica di un gruppo di ElastiCache parametri](ParameterGroups.Modifying.md).

   ```
   aws elasticache modify-cache-parameter-group \
      --cache-parameter-group-name redis28-m3xl \
      --parameter-name-values "ParameterName=reserved-memory, ParameterValue=7130316800"
   ```

   Occorre un gruppo di parametri personalizzato separato per ogni tipo di nodo in uso, perché ogni tipo di nodo dispone di un valore `maxmemory` diverso. Pertanto, ogni tipo di nodo richiede un valore diverso per `reserved-memory`.

1. Modifica il cluster o il gruppo di replica Redis OSS per utilizzare il gruppo di parametri personalizzato.

   L'esempio CLI seguente modifica il cluster ` my-redis-cluster` per utilizzare da subito il gruppo di parametri personalizzato `redis28-m3xl`. Per ulteriori informazioni, consulta [Modifica di un cluster ElastiCache](Clusters.Modify.md).

   ```
   aws elasticache modify-cache-cluster \
      --cache-cluster-id my-redis-cluster \
      --cache-parameter-group-name redis28-m3xl \
      --apply-immediately
   ```

   L'esempio CLI seguente modifica il gruppo di replica `my-redis-repl-grp` per utilizzare da subito il gruppo di parametri personalizzato `redis28-m3xl`. Per ulteriori informazioni, consulta [Modifica di un gruppo di replica](Replication.Modify.md).

   ```
   aws elasticache modify-replication-group \
      --replication-group-id my-redis-repl-grp \
      --cache-parameter-group-name redis28-m3xl \
      --apply-immediately
   ```

### Parametro reserved-memory-percent
<a name="redis-memory-management-parameters-reserved-memory-percent"></a>

Il 16 marzo 2017, Amazon ElastiCache ha introdotto il parametro `reserved-memory-percent` e lo ha reso disponibile su tutte le versioni ElastiCache di Redis OSS. Lo scopo di `reserved-memory-percent` è semplificare la gestione della memoria prenotata tra tutti i cluster. A tal fine, l'utente può disporre di un singolo gruppo di parametri per ogni famiglia di gruppo di parametri (ad esempio `redis2.8`) per gestire la memoria prenotata dei cluster, a prescindere dal tipo di nodo. Il valore di default per `reserved-memory-percent` è 25 (25 percento).

Il parametro `reserved-memory-percent` è specifico ElastiCache e non fa parte della distribuzione generale Redis OSS.

Se il cluster utilizza un tipo di nodo della famiglia r6gd e l'utilizzo della memoria raggiunge il 75%, il tiering di dati verrà attivato automaticamente. Per ulteriori informazioni, consulta [Suddivisione dei dati su più livelli in ElastiCache](data-tiering.md).

**Per riservare memoria utilizzando reserved-memory-percent**  
Da utilizzare `reserved-memory-percent` per gestire la memoria sul cluster ElastiCache for Redis OSS, esegui una delle seguenti operazioni:
+ Se utilizzi Redis OSS 2.8.22 o versione successiva, assegna il gruppo di parametri predefinito al cluster. Il valore di default di 25 percento dovrebbe essere adeguato. In caso contrario, attenersi alla procedura descritta di seguito per modificare il valore.
+ Se utilizzi una versione di Redis OSS precedente alla 2.8.22, probabilmente dovrai riservare più memoria rispetto al 25 percento predefinito. `reserved-memory-percent` A tale scopo, procedi come indicato di seguito. 

**Per modificare il valore percentuale di reserved-memory-percent**

1. Creare un gruppo di parametri personalizzato specificando la famiglia di gruppi di parametri corrispondente alla versione del motore in esecuzione, ad esempio specificando la famiglia di gruppi di parametri `redis2.8`. Un gruppo di parametri di default è necessario perché non è possibile modificare un gruppo di parametri di default. Per ulteriori informazioni, consulta [Creazione di un gruppo di ElastiCache parametri](ParameterGroups.Creating.md).

   ```
   aws elasticache create-cache-parameter-group \
      --cache-parameter-group-name redis28-50 \
      --description "Redis OSS 2.8.x 50% reserved" \
      --cache-parameter-group-family redis2.8
   ```

   Poiché `reserved-memory-percent` consente di riservare memoria con una percentuale della `maxmemory` del nodo, non è necessario un gruppo di parametri personalizzato per ogni tipo di nodo.

1. Modificare il gruppo di parametri personalizzato in modo che `reserved-memory-percent` sia 50 (50 percento). Per ulteriori informazioni, consulta [Modifica di un gruppo di ElastiCache parametri](ParameterGroups.Modifying.md).

   ```
   aws elasticache modify-cache-parameter-group \
      --cache-parameter-group-name redis28-50 \
      --parameter-name-values "ParameterName=reserved-memory-percent, ParameterValue=50"
   ```

1. Utilizzate questo gruppo di parametri personalizzato per qualsiasi cluster o gruppo di replica Redis OSS che esegue una versione di Redis OSS precedente alla 2.8.22.

   L'esempio CLI seguente modifica il cluster Redis OSS `my-redis-cluster` per utilizzare il gruppo di parametri personalizzato a partire da subito. `redis28-50` Per ulteriori informazioni, consulta [Modifica di un cluster ElastiCache](Clusters.Modify.md).

   ```
   aws elasticache modify-cache-cluster \
      --cache-cluster-id my-redis-cluster \
      --cache-parameter-group-name redis28-50 \
      --apply-immediately
   ```

   L'esempio CLI seguente modifica il gruppo di replica Redis OSS `my-redis-repl-grp` per utilizzare il gruppo di parametri personalizzato a partire da subito. `redis28-50` Per ulteriori informazioni, consulta [Modifica di un gruppo di replica](Replication.Modify.md).

   ```
   aws elasticache modify-replication-group \
      --replication-group-id my-redis-repl-grp \
      --cache-parameter-group-name redis28-50 \
      --apply-immediately
   ```

## Specifica del parametro di gestione della memoria prenotata
<a name="redis-reserved-memory-management-change"></a>

Se eri un ElastiCache cliente attuale il 16 marzo 2017, il tuo parametro di gestione della memoria riservata predefinito è `reserved-memory` pari a zero (0) byte di memoria riservata. Se sei diventato ElastiCache cliente dopo il 16 marzo 2017, il tuo parametro di gestione della memoria riservata predefinito prevede `reserved-memory-percent` il 25 percento della memoria riservata del nodo. Questo vale indipendentemente dal momento in cui hai creato il cluster o il gruppo di replica ElastiCache per Redis OSS. Tuttavia, è possibile modificare il parametro di gestione della memoria riservata utilizzando l'API AWS CLI o ElastiCache .

I parametri `reserved-memory` e `reserved-memory-percent` sono mutuamente esclusivi. Un gruppo di parametri ne conterrà sempre uno ma non entrambi. Puoi cambiare il parametro utilizzato da un gruppo di parametri per la gestione della memoria prenotata modificando il gruppo di parametri. Il gruppo di parametri deve essere un gruppo di parametri personalizzato, perché non puoi modificare i gruppi di parametri di default. Per ulteriori informazioni, consulta [Creazione di un gruppo di ElastiCache parametri](ParameterGroups.Creating.md).

**Per specificare reserved-memory-percent**  
Per utilizzare `reserved-memory-percent` come parametro di gestione della memoria prenotata, modifica un gruppo di parametri personalizzato utilizzando il comando `modify-cache-parameter-group`. Utilizzo del parametro `parameter-name-values` per specificare `reserved-memory-percent` e un valore per esso.

L'esempio CLI seguente modifica il gruppo di parametri personalizzato `redis32-cluster-on` in modo che utilizzi `reserved-memory-percent` per gestire memoria prenotata. Affinché il gruppo di parametri utilizzi il parametro `ParameterName` per la gestione della memoria prenotata, occorre assegnare un valore a `ParameterValue`. Per ulteriori informazioni, consulta [Modifica di un gruppo di ElastiCache parametri](ParameterGroups.Modifying.md).

```
aws elasticache modify-cache-parameter-group \
   --cache-parameter-group-name redis32-cluster-on \
   --parameter-name-values "ParameterName=reserved-memory-percent, ParameterValue=25"
```

**Per specificare la memoria reserved-memory**  
Per utilizzare `reserved-memory` come parametro di gestione della memoria prenotata, modifica un gruppo di parametri personalizzato utilizzando il comando `modify-cache-parameter-group`. Utilizzo del parametro `parameter-name-values` per specificare `reserved-memory` e un valore per esso.

L'esempio CLI seguente modifica il gruppo di parametri personalizzato `redis32-m3xl` in modo che utilizzi `reserved-memory` per gestire memoria prenotata. Affinché il gruppo di parametri utilizzi il parametro `ParameterName` per la gestione della memoria prenotata, occorre assegnare un valore a `ParameterValue`. Poiché la versione del motore è più recente di 2.8.22, impostiamo il valore su `3565158400` che è 25 percento di una `maxmemory` di `cache.m3.xlarge`. Per ulteriori informazioni, consulta [Modifica di un gruppo di ElastiCache parametri](ParameterGroups.Modifying.md).

```
aws elasticache modify-cache-parameter-group \
   --cache-parameter-group-name redis32-m3xl \
   --parameter-name-values "ParameterName=reserved-memory, ParameterValue=3565158400"
```

# Procedure consigliate per l'utilizzo di cluster basati su nodi Valkey e Redis OSS
<a name="BestPractices.SelfDesigned"></a>

L'uso della tecnologia Multi-AZ, la disponibilità di memoria sufficiente, il ridimensionamento dei cluster e la riduzione al minimo dei tempi di inattività sono tutti concetti utili da tenere a mente quando si lavora con cluster basati su nodi in Valkey o Redis OSS. Ti consigliamo di esaminare e seguire queste best practices.

**Topics**
+ [Ridurre al minimo i tempi di inattività con la funzione Multi-AZ](multi-az.md)
+ [Garantire la disponibilità di memoria sufficiente per creare un'istantanea Valkey o Redis OSS](BestPractices.BGSAVE.md)
+ [Ridimensionamento di cluster online](best-practices-online-resharding.md)
+ [Riduzione al minimo dei tempi di inattività durante la manutenzione](BestPractices.MinimizeDowntime.md)

# Ridurre al minimo i tempi di inattività con la funzione Multi-AZ
<a name="multi-az"></a>

Esistono diversi casi in cui ElastiCache Valkey o Redis OSS potrebbero dover sostituire un nodo primario; questi includono alcuni tipi di manutenzione pianificata e l'improbabile evento di un guasto del nodo primario o della zona di disponibilità.

Questa sostituzione comporta alcuni tempi di inattività per il cluster, ma se la funzione Multi-AZ è abilitata, il tempo di inattività viene ridotto al minimo. Il ruolo del nodo primario eseguirà automaticamente il failover su una delle repliche di lettura. Non è necessario creare ed effettuare il provisioning di un nuovo nodo primario, in quanto ElastiCache gestirà il problema in modo trasparente. Questo failover e la promozione delle repliche garantiscono la possibilità di ricominciare a scrivere nel nuovo nodo primario non appena la promozione è terminata.

Vedi[Riduzione al minimo dei tempi di inattività ElastiCache utilizzando Multi-AZ con Valkey e Redis OSS](AutoFailover.md), per saperne di più su Multi-AZ e sulla riduzione al minimo dei tempi di inattività.

# Garantire la disponibilità di memoria sufficiente per creare un'istantanea Valkey o Redis OSS
<a name="BestPractices.BGSAVE"></a>

**Istantanee e sincronizzazioni in Valkey 7.2 e versioni successive e Redis OSS versione 2.8.22 e successive**  
Valkey offre il supporto predefinito per istantanee e sincronizzazioni. Redis OSS 2.8.22 introduce un processo di salvataggio senza forkless che consente di allocare una maggiore quantità di memoria all'uso dell'applicazione senza aumentare l'utilizzo dello swap durante le sincronizzazioni e i salvataggi. Per ulteriori informazioni, consulta [Modalità di implementazione di sincronizzazione e backup](Replication.Redis.Versions.md).

**Istantanee e sincronizzazioni Redis OSS precedenti alla versione 2.8.22**

Quando si lavora con ElastiCache Redis OSS, Redis OSS richiama un comando di scrittura in background in diversi casi:
+ Durante la creazione di uno snapshot per un backup.
+ Durante la sincronizzazione delle repliche con il nodo principale in un gruppo di repliche
+ Quando si abilita la funzionalità di sola aggiunta di file (AOF) per Redis OSS.
+ Durante la promozione di una replica a primaria (che causa una sincronizzazione tra nodi principali/replica).

Ogni volta che Redis OSS esegue un processo di scrittura in background, è necessario disporre di memoria disponibile sufficiente per far fronte al sovraccarico del processo. La mancanza di memoria sufficiente provoca un errore del processo. Per questo motivo, è importante scegliere un tipo di istanza di nodo con memoria sufficiente durante la creazione del cluster Redis OSS.

## Processo di scrittura in background e utilizzo della memoria con Valkey e Redis OSS
<a name="BestPractices.BGSAVE.Process"></a>

Ogni volta che viene chiamato un processo di scrittura in background, Valkey e Redis OSS ne eseguono un fork (ricordate che questi motori sono a thread singolo). Un fork mantiene i dati su disco in un file snapshot Redis OSS .rdb. Tutti gli altri servizi fork eseguono operazioni di lettura e scrittura. Per garantire che l'istantanea sia un' point-in-timeistantanea, tutti gli aggiornamenti e le aggiunte ai dati vengono scritti in un'area di memoria disponibile separata dall'area dati.

Finché è disponibile memoria sufficiente per registrare tutte le operazioni di scrittura mentre i dati vengono resi persistenti sul disco, non si dovrebbero avere problemi di memoria insufficiente. Potresti riscontrare problemi di memoria insufficiente qualora si verifichi uno dei seguenti casi:
+ L'applicazione esegue molte operazioni di scrittura e richiede pertanto un'elevata quantità di memoria disponibile per accettare dati nuovi o aggiornati.
+ Hai a disposizione una quantità di memoria veramente limitata in cui scrivere dati nuovi o aggiornati.
+ Il set di dati di cui disponi è di grandi dimensioni. Poiché per essere reso persistente sul disco è necessario molto tempo, sono necessarie numerose operazioni di scrittura.

Il diagramma seguente illustra l'utilizzo della memoria durante l'esecuzione di un processo di scrittura in background.

![\[Immagine. Diagramma dell'utilizzo della memoria durante una scrittura in background.\]](http://docs.aws.amazon.com/it_it/AmazonElastiCache/latest/dg/images/ElastiCache-bgsaveMemoryUseage.png)


Per informazioni sull'impatto di un backup sulle prestazioni, consulta [Impatto sulle prestazioni dei backup di cluster basati su nodi](backups.md#backups-performance).

[Per ulteriori informazioni su come Valkey e Redis OSS eseguono le istantanee, consulta http://valkey.io.](http://valkey.io)

Per ulteriori informazioni sulle regioni e sulle zone di disponibilità, consulta [Scelta delle regioni e delle zone di disponibilità per ElastiCache](RegionsAndAZs.md). 

## Come evitare di esaurire la memoria durante l'esecuzione di una scrittura in background
<a name="BestPractices.BGSAVE.memoryFix"></a>

Ogni volta che `BGREWRITEAOF` viene chiamato un processo di scrittura in background come `BGSAVE` o, per evitare che il processo abbia esito negativo, è necessario disporre di più memoria di quella che verrà consumata dalle operazioni di scrittura durante il processo. Lo scenario peggiore è che durante l'operazione di scrittura in background ogni record venga aggiornato e alcuni nuovi record vengano aggiunti alla cache. Per questo motivo, si consiglia di impostare su 50 (50 percento) per le versioni Redis OSS precedenti `reserved-memory-percent` alla 2.8.22 o su 25 (25 percento) per Valkey e tutte le versioni Redis OSS 2.8.22 e successive. 

Il valore `maxmemory` indica la memoria che hai a disposizione per i dati e il sovraccarico operativo. Poiché non puoi modificare il parametro `reserved-memory` nel gruppo di parametri di default, devi creare un gruppo di parametri personalizzato per il cluster. Il valore predefinito per `reserved-memory` è 0, che consente a Redis OSS di consumare tutta la *memoria massima con i dati, lasciando potenzialmente troppo poca memoria* per altri usi, ad esempio un processo di scrittura in background. Per i valori di `maxmemory` per tipo di istanza del nodo, consulta [Parametri specifici del tipo di nodo Redis OSS](ParameterGroups.Engine.md#ParameterGroups.Redis.NodeSpecific).

È inoltre possibile utilizzare il `reserved-memory` parametro per ridurre la quantità di memoria utilizzata sulla confezione.

Per ulteriori informazioni sui parametri specifici di Valkey e Redis in, vedere. ElastiCache [Parametri Valkey e Redis OSS](ParameterGroups.Engine.md#ParameterGroups.Redis)

Per informazioni sulla creazione e sulla modifica di gruppi di parametri, consulta [Creazione di un gruppo di ElastiCache parametri](ParameterGroups.Creating.md) e [Modifica di un gruppo di ElastiCache parametri](ParameterGroups.Modifying.md).

# Ridimensionamento di cluster online
<a name="best-practices-online-resharding"></a>

Il *resharding * implica l'aggiunta e la rimozione di partizioni o nodi nel cluster e la ridistribuzione di spazi chiave. Diversi fattori hanno pertanto impatto sull'operazione di resharding, come il carico sul cluster, l'utilizzo della memoria e la dimensione complessiva dei dati. Per un'esperienza ottimale, ti consigliamo di attenerti a tutte le best practice relative al cluster per una distribuzione uniforme dei modelli di carico di lavoro. È inoltre consigliabile completare i passaggi indicati di seguito.

Prima di avviare il resharding, ti consigliamo di effettuare quanto segue:
+ **Testa la tua applicazione** - Testa il comportamento della tua applicazione durante il resharding in un ambiente di gestione temporanea, se possibile.
+ **Ottieni una notifica immediata dei problemi di dimensionamento** - Il resharding è un'operazione che richiede notevoli risorse di calcolo. Per questo motivo, consigliamo di mantenere l'utilizzo della CPU al di sotto dell'80% sulle istanze multicore e a meno del 50% sulle istanze single core durante il resharding. Monitora ElastiCache le metriche Redis OSS e avvia il resharding prima che l'applicazione inizi a rilevare problemi di scalabilità. Parametri utili da considerare sono `CPUUtilization`, `NetworkBytesIn`, `NetworkBytesOut`, `CurrConnections`, `NewConnections`, `FreeableMemory`, `SwapUsage` e `BytesUsedForCacheItems`.
+ **Verifica che sia disponibile memoria sufficiente per il dimensionamento** - Se esegui il dimensionamento, assicurati che la memoria libera disponibile sule partizioni da conservare sia almeno 1,5 volte quella utilizzata sule partizioni che desideri rimuovere.
+ **Avvia il resharding durante orari non di punta** Ciò consente di ridurre la latenza e l'impatto sulla velocità effettiva per il client durante l'operazione di resharding. In questo modo, il resharding viene inoltre completato più rapidamente, in quanto è possibile utilizzare più risorse per la ridistribuzione degli slot.
+ **Analizza il comportamento di timeout del client** - Alcuni client potrebbero presentare una latenza più elevata durante il dimensionamento del cluster online. Può essere utile configurare la libreria client con un timeout maggiore, in quanto aumenta il tempo a disposizione del sistema per eseguire la connessione, anche in caso di condizioni di carico più elevato sul server. In alcuni casi è possibile che si desideri aprire un numero elevato di connessioni al server. I questi casi considera la necessità di aggiungere backoff esponenziale alla logica di riconnessione. In questo modo è possibile evitare l'aumento di nuove connessioni eseguite contemporaneamente sul server.
+ **Carica le tue funzioni su ogni shard**: durante la scalabilità orizzontale del cluster, replica ElastiCache automaticamente le funzioni caricate in uno dei nodi esistenti (selezionati a caso) sui nuovi nodi. Se il tuo cluster ha Valkey 7.2 e versioni successive o Redis OSS 7.0 o versioni successive e la tua applicazione utilizza [Functions](https://valkey.io/topics/functions-intro/), ti consigliamo di caricare tutte le tue funzioni su tutti gli shard prima di scalare in modo che il cluster non finisca con funzioni diverse su shard diversi.

Dopo il resharding, tieni presente quanto segue:
+ Il dimensionamento potrebbe riuscire parzialmente se la memoria disponibile nele partizioni di destinazione non è sufficiente. In tal caso, controlla la memoria disponibile e prova di nuovo a eseguire l'operazione, se necessario. I dati sulle partizioni di destinazione non verranno eliminati.
+ I comandi `FLUSHALL` e `FLUSHDB` non sono supportati negli script Lua durante un'operazione di riassegnazione delle partizioni. Nelle versioni precedenti a Redis OSS 6, il `BRPOPLPUSH` comando non era supportato se opera sullo slot da migrare.

# Riduzione al minimo dei tempi di inattività durante la manutenzione
<a name="BestPractices.MinimizeDowntime"></a>

La configurazione in modalità cluster ha la migliore disponibilità durante le operazioni gestite o non gestite. Si consiglia di utilizzare un client supportato in modalità cluster che si connette all'endpoint di individuazione del cluster. Per la modalità cluster disattivata, si consiglia di utilizzare l'endpoint primario per tutte le operazioni di scrittura. 

Per attività di lettura, le applicazioni possono inoltre connettersi a qualsiasi nodo nel cluster. A differenza dell'endpoint primario, gli endpoint dei nodi vengono risolti in endpoint specifici. Se apporti una modifica al cluster, ad esempio aggiungendo o eliminando una replica, devi aggiornare gli endpoint dei nodi nell'applicazione. Questo è il motivo per cui, con la modalità cluster disabilitata, ti consigliamo di utilizzare l'endpoint di lettura per le attività di lettura.

Se AutoFailover è abilitato nel cluster, il nodo primario potrebbe cambiare. Pertanto, l'applicazione deve confermare il ruolo del nodo e aggiornare tutti gli endpoint di lettura. In questo modo hai la garanzia che non verrà causato un carico eccessivo sull'endpoint primario. Se AutoFailover disabilitato, il ruolo del nodo non cambia. Tuttavia, il tempo di inattività nelle operazioni gestite o non gestite è maggiore rispetto ai cluster abilitati. AutoFailover

 Evita di indirizzare le richieste di lettura a un singolo nodo di replica di lettura perché la sua indisponibilità potrebbe causare un'interruzione della lettura. Esegui il fallback alla lettura del nodo primario oppure assicurati di disporre di almeno due repliche di lettura per evitare interruzioni di lettura durante la manutenzione. 

# Strategie di caching per Memcached
<a name="Strategies"></a>

Nel seguente argomento, puoi trovare le strategie per popolare e gestire la cache Memcached.

L'implementazione di strategie per il popolamento e la gestione della cache dipende dal tipo di dati che desideri memorizzare e dai modelli di accesso a tali dati. Ad esempio, probabilmente non utilizzerai la stessa strategia per la classifica dei 10 migliori punteggi di gioco in un sito di gaming, o per le notizie più interessanti. Nella parte restante di questa sezione, discuteremo delle strategie più comuni di gestione della cache, dei loro vantaggi e svantaggi.

**Topics**
+ [Repliche di lettura](#Strategies.ReadReplicas)
+ [Caricamento lento](#Strategies.LazyLoading)
+ [Write-Through](#Strategies.WriteThrough)
+ [Aggiunta di TTL](#Strategies.WithTTL)
+ [Argomenti correlati](#Strategies.SeeAlso)

## Repliche di lettura
<a name="Strategies.ReadReplicas"></a>

Spesso è possibile migliorare in modo significativo le prestazioni delle cache ElastiCache serverless creando repliche e leggendo da esse anziché dal nodo di cache principale. Per ulteriori informazioni, consulta [Procedure consigliate per l'utilizzo delle repliche di lettura](ReadReplicas.md).

## Caricamento lento
<a name="Strategies.LazyLoading"></a>

Come dice lo stesso nome, il *caricamento lento* è una strategia di caching che consente di caricare i dati nella cache solo quando necessario. Funziona come descritto di seguito. 

Amazon ElastiCache è un archivio chiave-valore in memoria che si trova tra l'applicazione e l'archivio dati (database) a cui accede. Ogni volta che l'applicazione richiede dati, invia innanzitutto la richiesta alla cache. ElastiCache Se i dati sono presenti nella cache e sono correnti, ElastiCache restituisce tali dati all'applicazione. Se i dati non sono presenti nella cache o sono scaduti, l'applicazione richiede i dati al Data Store. L'archivio dati restituisce quindi i dati all'applicazione. Successivamente, l'applicazione scrive i dati ricevuti dall'archivio nella cache. In questo modo, può essere recuperato più rapidamente la prossima volta che viene richiesto.

Un’*occorrenza della cache* si verifica quando i dati sono presenti nella cache e non sono scaduti:

1. L'applicazione richiede i dati alla cache.

1. La cache restituisce i dati all'applicazione.

Una *mancato riscontro nella cache* si verifica quando i dati non sono presenti nella cache o sono scaduti:

1. L'applicazione richiede i dati alla cache.

1. La cache non dispone dei dati richiesti e restituisce un `null`.

1. L'applicazione richiede e riceve i dati dal database.

1. L'applicazione aggiorna la cache con i nuovi dati.

### Vantaggi e svantaggi del caricamento lento
<a name="Strategies.LazyLoading.Evaluation"></a>

I vantaggi del caricamento lento sono i seguenti:
+ Solo i dati richiesti vengono memorizzati nella cache.

  Poiché la maggior parte dei dati non viene mai richiesta, il caricamento lento evita di riempire la cache con i dati non richiesti.
+ Gli errori dei nodi non sono fatali per l'applicazione.

  Se un nodo restituisce un errore e viene sostituito da un nuovo nodo vuoto, l'applicazione continua a funzionare, nonostante l'aumento della latenza. Quando le richieste vengono effettuate al nuovo nodo, ogni mancato riscontro nella cache comporta una query del database. Allo stesso tempo, la copia dei dati viene aggiunta alla cache in modo che le richieste successive vengano richiamate dalla cache.

Gli svantaggi del caricamento pigro sono i seguenti:
+ Comporta una penalità per mancato riscontro nella cache. Ogni mancato riscontro nella cache comporta tre passaggi: 

  1. Richiesta iniziale dei dati dalla cache

  1. Query del database per i database

  1. Scrittura dei dati sulla cache

   Questi mancati riscontri possono causare un notevole ritardo dei dati destinati all'applicazione.
+ Dati obsoleti.

  Se i dati vengono scritti nella cache solo quando si verifica un mancato riscontro nella cache, i dati nella cache diventano obsoleti. Questo risultato si verifica perché non sono stati aggiornati alla cache quando i dati vengono modificati nel database. Per risolvere questo problema, è possibile utilizzare il [Write-Through](#Strategies.WriteThrough) e strategie [Aggiunta di TTL](#Strategies.WithTTL).

### Esempio di pseudocodice di caricamento pigro
<a name="Strategies.LazyLoading.CodeExample"></a>

Il codice seguente è un esempio di pseudo codice della logica di caricamento lento.

```
// *****************************************
// function that returns a customer's record.
// Attempts to retrieve the record from the cache.
// If it is retrieved, the record is returned to the application.
// If the record is not retrieved from the cache, it is
//    retrieved from the database, 
//    added to the cache, and 
//    returned to the application
// *****************************************
get_customer(customer_id)

    customer_record = cache.get(customer_id)
    if (customer_record == null)
    
        customer_record = db.query("SELECT * FROM Customers WHERE id = {0}", customer_id)
        cache.set(customer_id, customer_record)
    
    return customer_record
```

Per questo esempio, il codice dell'applicazione che ottiene i dati è il seguente.

```
customer_record = get_customer(12345)
```

## Write-Through
<a name="Strategies.WriteThrough"></a>

La strategia di scrittura contemporanea aggiunge i dati o li aggiorna nella cache ogni qualvolta i dati vengano scritti sul database.

### Vantaggi e svantaggi della scrittura contemporanea
<a name="Strategies.WriteThrough.Evaluation"></a>

I vantaggi di write-through sono i seguenti:
+ I dati nella cache non sono mai obsoleti.

  Poiché i dati nella cache vengono aggiornati ogni volta che vengono scritti sul database, i dati nella cache sono sempre correnti.
+ Penalità di scrittura e penalità di lettura.

  Ogni scrittura comporta due passaggi: 

  1. Una scrittura sulla cache

  1. Una scrittura sul database

   Che aggiunge latenza al processo. Detto questo, gli utenti finali sono generalmente più tolleranti della latenza durante l'aggiornamento o il richiamo dei dati. Esiste la convinzione che gli aggiornamenti comportino maggior lavoro e richiedano pertanto tempi lunghi.

Gli svantaggi di write-through sono i seguenti:
+ Dati mancanti.

  Se si esegue un giro verso l'alto di un nuovo nodo, dovuto a un errore del nodo o a un dimensionamento orizzontale, i dati mancanti sono stati visualizzati. Questi dati continuano a mancare fino a quando non vengono aggiunti o aggiornati nel database. È possibile ridurre al minimo questo implementando [caricamento lento](#Strategies.LazyLoading)con write-through.
+ Abbandono della cache.

  La maggior parte dei dati non viene mai letta, il che è uno spreco di risorse. Da [aggiunta di un valore durata (TTL)](#Strategies.WithTTL), è possibile ridurre gli sprechi di spazio.

### Esempio di pseudocodice write-through
<a name="Strategies.WriteThrough.CodeExample"></a>

Il codice seguente è un esempio di pseudo codice della logica di wright-through.

```
// *****************************************
// function that saves a customer's record.
// *****************************************
save_customer(customer_id, values)

    customer_record = db.query("UPDATE Customers WHERE id = {0}", customer_id, values)
    cache.set(customer_id, customer_record)
    return success
```

Per questo esempio, il codice dell'applicazione che ottiene i dati è il seguente.

```
save_customer(12345,{"address":"123 Main"})
```

## Aggiunta di TTL
<a name="Strategies.WithTTL"></a>

Il caricamento lento accetta i dati obsoleti, ma non restituisce errori con i nodi vuoti. La scrittura contemporanea garantisce dati sempre aggiornati ma può restituire un errore con i nodi vuoti e può popolare la cache con dati superflui. Aggiungendo un valore durata (TTL) a ogni scrittura, puoi avere i vantaggi di ogni strategia. Allo stesso tempo, puoi in gran parte evitare di ingombrare la cache con dati extra.

*Time to live (TTL)* è un valore intero che specifica il numero di secondi che mancano alla scadenza della chiave. Valkey o Redis OSS possono specificare secondi o millisecondi per questo valore. Memcached specifica questo valore in secondi. Quando un'applicazione tenta di leggere una chiave scaduta, viene trattata come se la chiave non fosse mai stata trovata. Il database viene interrogato per la chiave e la cache viene aggiornata. Questo approccio non garantisce che un valore non sia obsoleto. Tuttavia, impedisce ai dati di diventare troppo obsoleti e richiede che i valori nella cache vengano occasionalmente aggiornati dal database.

[Per ulteriori informazioni, vedete i comandi [Valkey e Redis](https://valkey.io/commands) OSS o i comandi Memcached. `set`](https://www.tutorialspoint.com/memcached/memcached_set_data.htm)

### Esempi di pseudocodice TTL
<a name="Strategies.WithTTL.CodeExample"></a>

Il codice seguente è un esempio di pseudo codice della logica di write-through con TTL.

```
// *****************************************
// function that saves a customer's record.
// The TTL value of 300 means that the record expires
//    300 seconds (5 minutes) after the set command 
//    and future reads will have to query the database.
// *****************************************
save_customer(customer_id, values)

    customer_record = db.query("UPDATE Customers WHERE id = {0}", customer_id, values)
    cache.set(customer_id, customer_record, 300)

    return success
```

Il codice seguente è un esempio di pseudo codice della logica di caricamento lento con TTL.

```
// *****************************************
// function that returns a customer's record.
// Attempts to retrieve the record from the cache.
// If it is retrieved, the record is returned to the application.
// If the record is not retrieved from the cache, it is 
//    retrieved from the database, 
//    added to the cache, and 
//    returned to the application.
// The TTL value of 300 means that the record expires
//    300 seconds (5 minutes) after the set command 
//    and subsequent reads will have to query the database.
// *****************************************
get_customer(customer_id)

    customer_record = cache.get(customer_id)
    
    if (customer_record != null)
        if (customer_record.TTL < 300)
            return customer_record        // return the record and exit function
            
    // do this only if the record did not exist in the cache OR
    //    the TTL was >= 300, i.e., the record in the cache had expired.
    customer_record = db.query("SELECT * FROM Customers WHERE id = {0}", customer_id)
    cache.set(customer_id, customer_record, 300)  // update the cache
    return customer_record                // return the newly retrieved record and exit function
```

Per questo esempio, il codice dell'applicazione che ottiene i dati è il seguente.

```
save_customer(12345,{"address":"123 Main"})
```

```
customer_record = get_customer(12345)
```

## Argomenti correlati
<a name="Strategies.SeeAlso"></a>
+ [Datastore in memoria](elasticache-use-cases.md#elasticache-use-cases-data-store)
+ [Scelta di un motore e di una versione](SelectEngine.md)
+ [Ridimensionamento ElastiCache](Scaling.md)