

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

# ElastiCache Best Practices und Caching-Strategien
<a name="BestPractices"></a>

Im Folgenden finden Sie empfohlene Best Practices für Amazon ElastiCache. Durch die Einhaltung dieser Methoden lassen sich die Performance und Zuverlässigkeit des Caches verbessern. 

**Topics**
+ [Allgemeine Best Practices](WorkingWithRedis.md)
+ [Bewährte Methoden für die Verwendung von Read Replicas](ReadReplicas.md)
+ [Unterstützte und eingeschränkte Valkey-, Memcached- und Redis OSS-Befehle](SupportedCommands.md)
+ [Konfiguration und Grenzwerte für Valkey und Redis OSS](RedisConfiguration.md)
+ [IPv6 Kundenbeispiele für Valkey, Memcached und Redis OSS](network-type-best-practices.md)
+ [Bewährte Methoden für Kunden (Valkey und Redis OSS)](BestPractices.Clients.redis.md)
+ [Bewährte Methoden für Kunden (Memcached)](BestPractices.Clients.memcached.md)
+ [TLS-fähige ElastiCache Dual-Stack-Cluster](#network-type-configuring-tls-enabled-dual-stack)
+ [Verwaltung von reserviertem Speicher für Valkey und Redis OSS](redis-memory-management.md)
+ [Bewährte Methoden bei der Arbeit mit nodenbasierten Valkey- und Redis OSS-Clustern](BestPractices.SelfDesigned.md)
+ [Caching-Strategien für Memcached](Strategies.md)

# Allgemeine Best Practices
<a name="WorkingWithRedis"></a>

Im Folgenden finden Sie Informationen zu bewährten Methoden für die Verwendung der OSS-Schnittstellen Valkey, Memcached und Redis. ElastiCache
+ **Verwenden Sie Konfigurationen mit aktiviertem Clustermodus — Bei aktiviertem** Clustermodus kann der Cache horizontal skaliert werden, um mehr Speicherplatz und Durchsatz zu erzielen als bei einer Konfiguration mit deaktiviertem Clustermodus. ElastiCache Serverless ist nur in einer Konfiguration mit aktiviertem Clustermodus verfügbar.
+ **Langlebige Verbindungen verwenden** – Das Erstellen einer neuen Verbindung ist teuer und beansprucht Zeit und CPU-Ressourcen aus dem Cache. Verwenden Sie Verbindungen nach Möglichkeit wieder (z. B. mit Verbindungspooling), um diese Kosten für viele Befehle zu amortisieren.
+ **Aus Replikaten lesen — Wenn Sie ElastiCache serverlose Systeme verwenden oder Read Replicas** (knotenbasierte Cluster) bereitgestellt haben, leiten Sie Lesevorgänge direkt an Replikate weiter, um eine bessere Skalierbarkeit und geringere Latenz zu erreichen. and/or Lesevorgänge aus Replikaten sind mit dem Primärknoten letztendlich konsistent.

  Vermeiden Sie es in einem knotenbasierten Cluster, Leseanforderungen an eine einzelne Read Replica weiterzuleiten, da Lesevorgänge möglicherweise vorübergehend nicht verfügbar sind, wenn der Knoten ausfällt. Konfigurieren Sie Ihren Client entweder so, dass Leseanfragen an mindestens zwei Read Replicas weitergeleitet werden oder Lesevorgänge an ein einzelnes Replikat und den Primärknoten weitergeleitet werden.

  Im ElastiCache serverlosen Modus werden Lesevorgänge, wenn vom Replikat-Port (6380) gelesen wird, nach Möglichkeit in die lokale Availability Zone des Clients geleitet, wodurch die Latenz beim Abrufen reduziert wird. Bei Ausfällen wird automatisch auf die anderen Knoten zurückgegriffen.
+ **Vermeiden Sie teure Befehle** — Vermeiden Sie es, I/O rechenintensive Operationen wie die Befehle und auszuführen. `KEYS` `SMEMBERS` Wir empfehlen diesen Ansatz, da diese Operationen die Last auf dem Cluster erhöhen und Einfluss auf die Performance des Clusters haben. Verwenden Sie stattdessen die Befehle `SCAN` und `SSCAN`.
+ **Befolgen Sie die bewährten Methoden von Lua** – Vermeiden Sie lange laufende Lua-Skripte und deklarieren Sie Schlüssel, die in Lua-Skripten verwendet werden, immer im Voraus. Wir empfehlen diesen Ansatz, um festzustellen, dass im Lua-Skript keine slotübergreifenden Befehle verwendet werden. Vergewissern Sie sich, dass die in Lua-Skripts verwendeten Schlüssel zum gleichen Slot gehören.
+ **Sharded Pub/Sub verwenden** — Wenn Sie Valkey oder Redis OSS verwenden, um pub/sub Workloads mit hohem Durchsatz zu unterstützen, empfehlen wir die Verwendung von [Sharded Pub/Sub](https://valkey.io/topics/pubsub/) (verfügbar mit Valkey und mit Redis OSS 7 oder höher). Herkömmliche Cluster, die pub/sub im Clustermodus aktiviert sind, senden Nachrichten an alle Knoten im Cluster, was zu hohen Werten führen kann. `EngineCPUUtilization` Beachten Sie, dass es sich bei ElastiCache serverlosen Befehlen um herkömmliche Befehle handelt. pub/sub commands internally use sharded pub/sub

**Topics**

# Bewährte Methoden für die Verwendung von Read Replicas
<a name="ReadReplicas"></a>

Viele Anwendungen, wie Sitzungsspeicher, Bestenlisten und Empfehlungsmodule, erfordern eine hohe Verfügbarkeit und verarbeiten deutlich mehr Lese- als Schreibvorgänge. Diese Anwendungen können häufig leicht veraltete Daten tolerieren (letztendliche Konsistenz), was bedeutet, dass es akzeptabel ist, wenn verschiedene Benutzer vorübergehend leicht unterschiedliche Versionen derselben Daten sehen. Beispiel:
+ Im Cache gespeicherte Abfrageergebnisse können häufig leicht veraltete Daten tolerieren, insbesondere bei zwischengespeicherten Mustern, bei denen die Quelle der Wahrheit extern ist.
+ In einer Gaming-Bestenliste wirkt sich eine Verzögerung von einigen Sekunden bei aktualisierten Ergebnissen häufig nicht wesentlich auf die Benutzererfahrung aus.
+ Bei Sitzungsspeichern wirken sich geringfügige Verzögerungen bei der Übertragung von Sitzungsdaten zwischen Replikaten selten auf die Anwendungsfunktionalität aus.
+ Empfehlungs-Engines verwenden in der Regel historische Datenanalysen, sodass Konsistenz in Echtzeit weniger wichtig ist.

Letztendliche Konsistenz bedeutet, dass alle Replikatknoten irgendwann dieselben Daten zurückgeben, sobald der Replikationsprozess abgeschlossen ist, normalerweise innerhalb von Millisekunden. Für solche Anwendungsfälle ist die Implementierung von Read Replicas eine effektive Strategie, um die Latenz beim Lesen aus Ihrer Instance zu reduzieren. ElastiCache

Die Verwendung von Read Replicas in Amazon ElastiCache kann erhebliche Leistungsvorteile bieten durch:

**Verbesserte Leseskalierbarkeit**
+ Verteilt Lesevorgänge auf mehrere Replikatknoten
+ Lädt den Lesetraffic vom primären Knoten ab
+ Reduziert die Leselatenz, indem Anfragen von geografisch näher gelegenen Replikaten bearbeitet werden

**Optimierte Leistung des Primärknotens**
+ Weist Ressourcen des primären Knotens für Schreiboperationen zu
+ Reduziert den Verbindungsaufwand auf dem Primärknoten
+ Verbessert die Schreibleistung und sorgt für bessere Antwortzeiten in Zeiten mit hohem Datenverkehr

## Verwenden von Read from Replica in Serverless ElastiCache
<a name="ReadReplicas.serverless"></a>

ElastiCache Serverless bietet zwei verschiedene Endpunkte für unterschiedliche Konsistenzanforderungen. Die beiden Endpunkte verwenden denselben DNS-Namen, aber unterschiedliche Ports. Um den read-from-replica Port verwenden zu können, müssen Sie den Zugriff auf beide Ports von Ihrer Client-Anwendung aus autorisieren, indem Sie [die Sicherheitsgruppen und Netzwerkzugriffskontrolllisten Ihrer VPC konfigurieren](set-up.md#elasticache-install-grant-access-VPN).

**Primärer Endpunkt (Port 6379)**
+ Wird für Operationen verwendet, die sofortige Konsistenz erfordern
+ Garantiert das Lesen der meisten up-to-date Daten
+ Am besten für kritische Transaktionen und Schreibvorgänge
+ Erforderlich für Schreiboperationen
+ Beispiel: `test-12345.serverless.use1.cache.amazonaws.com:6379`

**Latenzoptimierter Endpunkt (Port 6380)**
+ Optimiert für Lesevorgänge, die eine eventuelle Konsistenz tolerieren
+ Wenn möglich, leitet ElastiCache Serverless Leseanfragen automatisch an den Replikatknoten in der lokalen Availability Zone des Clients weiter. Diese Optimierung sorgt für eine geringere Latenz, da die zusätzliche Netzwerklatenz vermieden wird, die beim Abrufen von Daten von einem Knoten in einer anderen Availability Zone entsteht.
+ ElastiCache Serverless wählt automatisch verfügbare Knoten in anderen Zonen aus, wenn ein lokaler Knoten nicht verfügbar ist
+ Beispiel: `test-12345.serverless.use1.cache.amazonaws.com:6380`
+ Clients wie Glide und Lettuce erkennen Lesevorgänge automatisch und leiten sie an den latenzoptimierten Endpunkt weiter, wenn Sie die Konfiguration „Read from Replica“ angeben. Wenn Ihr Client die Routing-Konfiguration nicht unterstützt (z. B. Valkey-Java und ältere Jedis-Versionen), müssen Sie den richtigen Port und die richtige Client-Konfiguration definieren, um aus Replikaten zu lesen.

## Verbindung herstellen, um Repliken in Serverless zu lesen — Valkey und Glide ElastiCache
<a name="ReadReplicas.connecting-primary"></a>

Der folgende Codeausschnitt zeigt, wie Sie Read from Replica für ElastiCache Serverless in der Valkey-Glide-Bibliothek konfigurieren können. Sie müssen keinen Port für das Lesen von Replikaten angeben, aber Sie müssen die Routing-Konfiguration konfigurieren. `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());
                }
            }
        }
    }
}
```

# Unterstützte und eingeschränkte Valkey-, Memcached- und Redis OSS-Befehle
<a name="SupportedCommands"></a>

## Unterstützte Valkey- und Redis OSS-Befehle
<a name="SupportedCommandsRedis"></a>

**Unterstützte Valkey- und Redis OSS-Befehle**

Die folgenden Valkey- und Redis OSS-Befehle werden von serverlosen Caches unterstützt. Zusätzlich zu diesen Befehlen werden außerdem diese [Unterstützte Valkey- und Redis OSS-BefehleJSON-Befehle](json-list-commands.md) unterstützt.

Informationen zu Bloom-Filter-Befehlen finden Sie unter [Bloom-Filter-Befehle](BloomFilters.md#SupportedCommandsBloom)

**Bitmap-Befehle**
+ `BITCOUNT`

  Zählt die Anzahl der gesetzten Bits (Populationszählung) in einer Zeichenfolge.

  [Weitere Informationen](https://valkey.io/commands/bitcount/)
+ `BITFIELD`

  Führt willkürliche Bitfeld-Ganzzahl-Operationen für Zeichenfolgen aus.

  [Weitere Informationen](https://valkey.io/commands/bitfield/)
+ `BITFIELD_RO`

  Führt willkürliche, schreibgeschützte Bitfeld-Ganzzahl-Operationen für Zeichenfolgen aus.

  [Weitere Informationen](https://valkey.io/commands/bitfield_ro/)
+ `BITOP`

  Führt bitweise Operationen an mehreren Zeichenfolgen aus und speichert das Ergebnis.

  [Weitere Informationen](https://valkey.io/commands/bitop/)
+ `BITPOS`

  Findet das erste gesetzte (1) oder nicht gesetzte Bit (0) in einer Zeichenfolge.

  [Weitere Informationen](https://valkey.io/commands/bitpos/)
+ `GETBIT`

  Gibt einen Bitwert nach Offset zurück.

  [Weitere Informationen](https://valkey.io/commands/getbit/)
+ `SETBIT`

  Setzt oder löscht das Bit am Offset des Zeichenfolgenwerts. Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/setbit/)

**Befehle zur Clusterverwaltung**
+ `CLUSTER COUNTKEYSINSLOT`

  Gibt die Anzahl der Schlüssel in einem Hash-Slot zurück.

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

  Gibt die Schlüsselnamen in einem Hash-Slot zurück.

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

  Gibt Informationen zum Status eines Knotens zurück. Gibt in einem Serverless-Cache den Status des einzelnen virtuellen „Shard“ zurück, der dem Client angezeigt wird.

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

  Gibt den Hash-Slot für einen Schlüssel zurück.

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

  Gibt die ID eines Knotens zurück. Gibt in einem Serverless-Cache den Status des einzelnen virtuellen „Shard“ zurück, der dem Client angezeigt wird. 

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

  Gibt die Clusterkonfiguration für einen Knoten zurück. Gibt in einem Serverless-Cache den Status des einzelnen virtuellen „Shard“ zurück, der dem Client angezeigt wird. 

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

  Listet die Replikatknoten eines Hauptknotens auf. Gibt in einem Serverless-Cache den Status des einzelnen virtuellen „Shard“ zurück, der dem Client angezeigt wird. 

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

  Gibt die Zuordnung von Cluster-Slots zu Shards zurück. Gibt in einem Serverless-Cache den Status des einzelnen virtuellen „Shard“ zurück, der dem Client angezeigt wird. 

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

  Gibt die Zuordnung von Cluster-Slots zu Knoten zurück. Gibt in einem Serverless-Cache den Status des einzelnen virtuellen „Shard“ zurück, der dem Client angezeigt wird. 

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

  Ermöglicht die Nachverfolgung von Metriken pro Steckplatz für Schlüsselanzahl, CPU-Auslastung, eingehende Netzwerk-Bytes und ausgehende Netzwerk-Bytes. 

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

  Ermöglicht schreibgeschützte Abfragen für eine Verbindung zu einem Valkey- oder Redis OSS-Cluster-Replikatknoten.

  [Weitere Informationen](https://valkey.io/commands/readonly/)
+ `READWRITE`

  Aktiviert Lese-/Schreibabfragen für eine Verbindung zu einem Valkey- oder Redis OSS-Cluster-Replikatknoten.

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

  Gibt den ursprünglichen Quellcode eines Skripts im Skript-Cache zurück.

  [Weitere Informationen](https://valkey.io/commands/script-show/)

**Befehle zur Verbindungsverwaltung**
+ `AUTH`

  Authentifiziert die Verbindung.

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

  Gibt den Namen der Verbindung zurück.

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

  Weist den Server an, ob er auf Befehle antworten soll.

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

  Legt den Verbindungsnamen fest.

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

  Gibt die angegebene Zeichenfolge zurück.

  [Weitere Informationen](https://valkey.io/commands/echo/)
+ `HELLO`

  Handshakes mit dem Valkey- oder Redis OSS-Server.

  [Weitere Informationen](https://valkey.io/commands/hello/)
+ `PING`

  Gibt die Lebhaftigkeitsantwort des Servers zurück.

  [Weitere Informationen](https://valkey.io/commands/ping/)
+ `QUIT`

  Schließt die Verbindung.

  [Weitere Informationen](https://valkey.io/commands/quit/)
+ `RESET`

  Setzt die Verbindung zurück.

  [Weitere Informationen](https://valkey.io/commands/reset/)
+ `SELECT`

  Ändert die ausgewählte Datenbank.

  [Weitere Informationen](https://valkey.io/commands/select/)

**Generische Befehle**
+ `COPY`

  Kopiert den Wert eines Schlüssels in einen neuen Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/copy/)
+ `DEL`

  Löscht einen oder mehrere Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/del/)
+ `DUMP`

  Gibt eine serialisierte Darstellung des in einem Schlüssel gespeicherten Werts zurück.

  [Weitere Informationen](https://valkey.io/commands/dump/)
+ `EXISTS`

  Ermittelt, ob ein oder mehrere Schlüssel existieren.

  [Weitere Informationen](https://valkey.io/commands/exists/)
+ `EXPIRE`

  Legt die Ablaufzeit eines Schlüssels in Sekunden fest.

  [Weitere Informationen](https://valkey.io/commands/expire/)
+ `EXPIREAT`

  Legt die Ablaufzeit eines Schlüssels auf einen Unix-Zeitstempel fest.

  [Weitere Informationen](https://valkey.io/commands/expireat/)
+ `EXPIRETIME`

  Gibt die Ablaufzeit eines Schlüssels als Unix-Zeitstempel zurück.

  [Weitere Informationen](https://valkey.io/commands/expiretime/)
+ `PERSIST`

  Entfernt die Ablaufzeit eines Schlüssels.

  [Weitere Informationen](https://valkey.io/commands/persist/)
+ `PEXPIRE`

  Legt die Ablaufzeit eines Schlüssels in Millisekunden fest.

  [Weitere Informationen](https://valkey.io/commands/pexpire/)
+ `PEXPIREAT`

  Legt die Ablaufzeit eines Schlüssels auf einen Unix-Millisekunden-Zeitstempel fest.

  [Weitere Informationen](https://valkey.io/commands/pexpireat/)
+ `PEXPIRETIME`

  Gibt die Ablaufzeit eines Schlüssels als Unix-Millisekunden-Zeitstempel zurück.

  [Weitere Informationen](https://valkey.io/commands/pexpiretime/)
+ `PTTL`

  Gibt die Ablaufzeit eines Schlüssels in Millisekunden zurück.

  [Weitere Informationen](https://valkey.io/commands/pttl/)
+ `RANDOMKEY`

  Gibt einen zufälligen Schlüsselnamen aus der Datenbank zurück.

  [Weitere Informationen](https://valkey.io/commands/randomkey/)
+ `RENAME`

  Benennt einen Schlüssel um und überschreibt das Ziel.

  [Weitere Informationen](https://valkey.io/commands/rename/)
+ `RENAMENX`

  Benennt einen Schlüssel nur um, wenn der Name des Zielschlüssels nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/renamenx/)
+ `RESTORE`

  Erstellt einen Schlüssel aus der serialisierten Darstellung eines Werts.

  [Weitere Informationen](https://valkey.io/commands/restore/)
+ `SCAN`

  Iteriert über die Schlüsselnamen in der Datenbank.

  [Weitere Informationen](https://valkey.io/commands/scan/)
+ `SORT`

  Sortiert die Elemente in einer Liste, einem Set oder einem sortierten Set und speichert optional das Ergebnis.

  [Weitere Informationen](https://valkey.io/commands/sort/)
+ `SORT_RO`

  Gibt die sortierten Elemente einer Liste, eines Sets oder eines sortierten Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/sort_ro/)
+ `TOUCH`

  Gibt die Anzahl der vorhandenen Schlüssel aus den angegebenen Schlüsseln zurück, nachdem der Zeitpunkt des letzten Zugriffs aktualisiert wurde.

  [Weitere Informationen](https://valkey.io/commands/touch/)
+ `TTL`

  Gibt die Ablaufzeit eines Schlüssels in Sekunden zurück.

  [Weitere Informationen](https://valkey.io/commands/ttl/)
+ `TYPE`

  Ermittelt den Typ des Wertes, der in einem Schlüssel gespeichert ist.

  [Weitere Informationen](https://valkey.io/commands/type/)
+ `UNLINK`

  Löscht asynchron einen oder mehrere Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/unlink/)

**Geodatenbefehle**
+ `GEOADD`

  Fügt einem Geodatenindex ein oder mehrere Mitglieder hinzu. Der Schlüssel wird erstellt, wenn er nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/geoadd/)
+ `GEODIST`

  Gibt den Abstand zwischen zwei Mitgliedern eines Geodatenindex zurück.

  [Weitere Informationen](https://valkey.io/commands/geodist/)
+ `GEOHASH`

  Gibt Elemente aus einem Geodatenindex als Geohash-Zeichenfolgen zurück.

  [Weitere Informationen](https://valkey.io/commands/geohash/)
+ `GEOPOS`

  Gibt den Längen- und Breitengrad von Elementen aus einem Geodatenindex zurück.

  [Weitere Informationen](https://valkey.io/commands/geopos/)
+ `GEORADIUS`

  Fragt einen Geodatenindex nach Elementen ab, die sich innerhalb einer Entfernung von einer Koordinate befinden, und speichert optional das Ergebnis.

  [Weitere Informationen](https://valkey.io/commands/georadius/)
+ `GEORADIUS_RO`

  Gibt Elemente aus einem Geodatenindex zurück, die sich innerhalb einer Entfernung von einer Koordinate befinden.

  [Weitere Informationen](https://valkey.io/commands/georadius_ro/)
+ `GEORADIUSBYMEMBER`

  Fragt einen Geodatenindex nach Elementen ab, die sich innerhalb einer Entfernung von einem Element befinden, und speichert optional das Ergebnis.

  [Weitere Informationen](https://valkey.io/commands/georadiusbymember/)
+ `GEORADIUSBYMEMBER_RO`

  Gibt Elemente aus einem Geodatenindex zurück, die sich innerhalb einer Entfernung von einem Element befinden.

  [Weitere Informationen](https://valkey.io/commands/georadiusbymember_ro/)
+ `GEOSEARCH`

  Fragt einen Geodatenindex nach Elementen ab, die sich in einem Bereich eines Felds oder Kreises befinden.

  [Weitere Informationen](https://valkey.io/commands/geosearch/)
+ `GEOSEARCHSTORE`

  Fragt einen Geodatenindex nach Elementen ab, die sich in einem Bereich eines Felds oder Kreises befinden, und speichert optional das Ergebnis.

  [Weitere Informationen](https://valkey.io/commands/geosearchstore/)

**Hash-Befehle**
+ `HDEL`

  Löscht ein oder mehrere Felder und deren Werte aus einem Hash. Löscht den Hash, wenn keine Felder mehr vorhanden sind.

  [Weitere Informationen](https://valkey.io/commands/hdel/)
+ `HEXISTS`

  Ermittelt, ob ein Feld in einem Hash existiert.

  [Weitere Informationen](https://valkey.io/commands/hexists/)
+ `HGET`

  Gibt den Wert eines Felds in einem Hash zurück.

  [Weitere Informationen](https://valkey.io/commands/hget/)
+ `HGETALL`

  Gibt alle Felder und Werte in einem Hash zurück.

  [Weitere Informationen](https://valkey.io/commands/hgetall/)
+ `HINCRBY`

  Inkrementiert den Ganzzahlwert eines Felds in einem Hash um eine Zahl. Verwendet 0 als Anfangswert, wenn das Feld nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/hincrby/)
+ `HINCRBYFLOAT`

  Inkrementiert den Gleitkommawert eines Felds um eine Zahl. Verwendet 0 als Anfangswert, wenn das Feld nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/hincrbyfloat/)
+ `HKEYS`

  Gibt alle Felder in einem Hash zurück.

  [Weitere Informationen](https://valkey.io/commands/hkeys/)
+ `HLEN`

  Gibt die Anzahl der Felder in einem Hash zurück.

  [Weitere Informationen](https://valkey.io/commands/hlen/)
+ `HMGET`

  Gibt die Werte aller Felder in einem Hash zurück.

  [Weitere Informationen](https://valkey.io/commands/hmget/)
+ `HMSET`

  Legt die Werte mehrerer Felder fest.

  [Weitere Informationen](https://valkey.io/commands/hmset/)
+ `HRANDFIELD`

  Gibt ein oder mehrere zufällige Felder aus einem Hash zurück.

  [Weitere Informationen](https://valkey.io/commands/hrandfield/)
+ `HSCAN`

  Iteriert über Felder und Werte eines Hashs.

  [Weitere Informationen](https://valkey.io/commands/hscan/)
+ `HSET`

  Erstellt oder ändert den Wert eines Felds in einem Hash.

  [Weitere Informationen](https://valkey.io/commands/hset/)
+ `HSETNX`

  Legt den Wert eines Felds in einem Hash nur fest, wenn das Feld nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/hsetnx/)
+ `HSTRLEN`

  Gibt die Länge des Werts eines Felds zurück.

  [Weitere Informationen](https://valkey.io/commands/hstrlen/)
+ `HVALS`

  Gibt alle Werte in einem Hash zurück.

  [Weitere Informationen](https://valkey.io/commands/hvals/)

**HyperLogLog Befehle**
+ `PFADD`

  Fügt einem Schlüssel Elemente hinzu. HyperLogLog Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/pfadd/)
+ `PFCOUNT`

  Gibt die ungefähre Kardinalität der Menge (n) zurück, die von dem/den HyperLogLog Schlüssel (n) beobachtet wurde.

  [Weitere Informationen](https://valkey.io/commands/pfcount/)
+ `PFMERGE`

  Führt einen oder mehrere HyperLogLog Werte zu einem einzigen Schlüssel zusammen.

  [Weitere Informationen](https://valkey.io/commands/pfmerge/)

**Listenbefehle**
+ `BLMOVE`

  Löscht ein Element aus einer Liste, verschiebt es in eine andere Liste und gibt es zurück. Blockiert, bis ein Element anderweitig verfügbar ist. Löscht die Liste, wenn das letzte Element verschoben wurde.

  [Weitere Informationen](https://valkey.io/commands/blmove/)
+ `BLMPOP`

  Löscht das erste Element aus einer von mehreren Listen. Blockiert, bis ein Element anderweitig verfügbar ist. Löscht die Liste, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/blmpop/)
+ `BLPOP`

  Entfernt das erste Element in einer Liste und gibt es zurück. Blockiert, bis ein Element anderweitig verfügbar ist. Löscht die Liste, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/blpop/)
+ `BRPOP`

  Entfernt das letzte Element in einer Liste und gibt es zurück. Blockiert, bis ein Element anderweitig verfügbar ist. Löscht die Liste, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/brpop/)
+ `BRPOPLPUSH`

  Löscht ein Element aus einer Liste, verschiebt es in eine andere Liste und gibt es zurück. Blockiert, bis ein Element anderweitig verfügbar ist. Löscht die Liste, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/brpoplpush/)
+ `LINDEX`

  Gibt ein Element anhand seines Index aus einer Liste zurück.

  [Weitere Informationen](https://valkey.io/commands/lindex/)
+ `LINSERT`

  Fügt ein Element vor oder nach einem anderen Element in eine Liste ein.

  [Weitere Informationen](https://valkey.io/commands/linsert/)
+ `LLEN`

  Gibt die Länge einer Liste zurück.

  [Weitere Informationen](https://valkey.io/commands/llen/)
+ `LMOVE`

  Gibt ein Element zurück, nachdem es aus einer Liste entfernt und in eine andere verschoben wurde. Löscht die Liste, wenn das letzte Element verschoben wurde.

  [Weitere Informationen](https://valkey.io/commands/lmove/)
+ `LMPOP`

  Gibt mehrere Elemente aus einer Liste zurück, nachdem sie entfernt wurden. Löscht die Liste, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/lmpop/)
+ `LPOP`

  Gibt die ersten Elemente in einer Liste zurück, nachdem sie entfernt wurde. Löscht die Liste, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/lpop/)
+ `LPOS`

  Gibt den Index übereinstimmender Elemente in einer Liste zurück.

  [Weitere Informationen](https://valkey.io/commands/lpos/)
+ `LPUSH`

  Stellt einer Liste ein oder mehrere Elemente voran. Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/lpush/)
+ `LPUSHX`

  Stellt einer Liste nur dann ein oder mehrere Elemente voran, wenn die Liste existiert.

  [Weitere Informationen](https://valkey.io/commands/lpushx/)
+ `LRANGE`

  Gibt einen Bereich von Elementen aus einer Liste zurück.

  [Weitere Informationen](https://valkey.io/commands/lrange/)
+ `LREM`

  Entfernt Elemente aus einer Liste. Löscht die Liste, wenn das letzte Element entfernt wurde.

  [Weitere Informationen](https://valkey.io/commands/lrem/)
+ `LSET`

  Legt den Wert eines Elements in einer Liste anhand seines Index fest.

  [Weitere Informationen](https://valkey.io/commands/lset/)
+ `LTRIM`

  Entfernt Elemente am Anfang und Ende einer Liste. Löscht die Liste, wenn alle Elemente gekürzt wurden.

  [Weitere Informationen](https://valkey.io/commands/ltrim/)
+ `RPOP`

  Gibt die letzten Elemente einer Liste zurück und entfernt sie. Löscht die Liste, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/rpop/)
+ `RPOPLPUSH`

  Gibt das letzte Element einer Liste zurück, nachdem es entfernt und in eine andere Liste verschoben wurde. Löscht die Liste, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/rpoplpush/)
+ `RPUSH`

  Fügt ein oder mehrere Elemente an eine Liste an. Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/rpush/)
+ `RPUSHX`

  Fügt ein Element nur dann an eine Liste an, wenn die Liste existiert.

  [Weitere Informationen](https://valkey.io/commands/rpushx/)

**Pub/Sub-Befehle**

**Anmerkung**  
PUBSUB-Befehle verwenden intern Sharded PUBSUB, sodass Kanalnamen gemischt werden.
+ `PUBLISH`

  Sendet eine Nachricht an einen Kanal.

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

  Gibt die aktiven Kanäle zurück.

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

  Gibt die Anzahl der Subscriber von Kanälen zurück.

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

  Gibt die aktiven Shard-Kanäle zurück.

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

  Gibt die Anzahl der Subscriber von Shard-Kanälen zurück.

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

  Sendet eine Nachricht an einen Shard-Kanal.

  [Weitere Informationen](https://valkey.io/commands/spublish/)
+ `SSUBSCRIBE`

  Lauscht nach Nachrichten, die auf Shard-Kanälen veröffentlicht wurden.

  [Weitere Informationen](https://valkey.io/commands/ssubscribe/)
+ `SUBSCRIBE`

  Lauscht nach Nachrichten, die auf Kanälen veröffentlicht wurden.

  [Weitere Informationen](https://valkey.io/commands/subscribe/)
+ `SUNSUBSCRIBE`

  Beendet das Lauschen nach Nachrichten, die an Shard-Kanäle gesendet wurden.

  [Weitere Informationen](https://valkey.io/commands/sunsubscribe/)
+ `UNSUBSCRIBE`

  Beendet das Lauschen nach Nachrichten, die an Kanäle gesendet wurden.

  [Weitere Informationen](https://valkey.io/commands/unsubscribe/)

**Befehle zur Skripterstellung**
+ `EVAL`

  Führt ein serverseitiges Lua-Skript aus.

  [Weitere Informationen](https://valkey.io/commands/eval/)
+ `EVAL_RO`

  Führt ein schreibgeschütztes serverseitiges Lua-Skript aus.

  [Weitere Informationen](https://valkey.io/commands/eval_ro/)
+ `EVALSHA`

  Führt ein serverseitiges Lua-Skript per Digest aus. SHA1 

  [Weitere Informationen](https://valkey.io/commands/evalsha/)
+ `EVALSHA_RO`

  Führt ein schreibgeschütztes serverseitiges Lua-Skript per Digest aus. SHA1 

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

  Ermittelt, ob serverseitige Lua-Skripte im Skriptcache vorhanden sind.

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

  Derzeit wird ein No-Op-Skript-Cache vom Service verwaltet. 

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

  Lädt ein serverseitiges Lua-Skript in den Skript-Cache.

  [Weitere Informationen](https://valkey.io/commands/script-load/)

**Befehle zur Serververwaltung**

**Anmerkung**  
Bei der Verwendung knotenbasierter ElastiCache Cluster für Valkey und Redis OSS müssen vom Client Flush-Befehle an jeden Primärserver gesendet werden, um alle Schlüssel zu leeren. ElastiCache Serverless für Valkey und Redis OSS funktioniert unterschiedlich, da es die zugrunde liegende Cluster-Topologie wegabstrahiert. Das Ergebnis ist, dass in ElastiCache Serverless `FLUSHDB` und mit `FLUSHALL` Befehlen immer alle Schlüssel im Cluster geleert werden. Aus diesem Grund können Flush-Befehle nicht in eine serverlose Transaktion aufgenommen werden. 
+ `ACL CAT`

  Listet die ACL-Kategorien oder die Befehle innerhalb einer Kategorie auf.

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

  Generiert ein pseudozufälliges, sicheres Passwort, das zur Identifizierung von ACL-Benutzern verwendet werden kann.

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

  Listet die ACL-Regeln eines Benutzers auf.

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

  Gibt die effektiven Regeln im ACL-Dateiformat aus.

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

  Listet alle ACL-Benutzer auf.

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

  Gibt den authentifizierten Benutzernamen der aktuellen Verbindung zurück.

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

  Gibt die Anzahl der Schlüssel in der aktuell ausgewählten Datenbank zurück. Es kann nicht garantiert werden, dass diese Operation in allen Slots atomar abläuft.

  [Weitere Informationen](https://valkey.io/commands/dbsize/)
+ `COMMAND`

  Gibt detaillierte Informationen zu allen Befehlen zurück.

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

  Gibt eine Anzahl von Befehlen zurück.

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

  Gibt durch Dokumente belegte Informationen zu einem, mehreren oder allen Befehlen zurück.

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

  Extrahiert die Schlüsselnamen aus einem willkürlichen Befehl.

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

  Extrahiert die Schlüsselnamen und Zugriffs-Flags für einen willkürlichen Befehl.

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

  Gibt Informationen zu einem, mehreren oder allen Befehlen zurück.

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

  Gibt eine Liste von Befehlsnamen zurück.

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

  Ein Container für Befehlsprotokollbefehle.

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

  Gibt die Einträge des angegebenen Befehlsprotokolls zurück.

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

  Zeigt hilfreichen Text zu den verschiedenen Unterbefehlen an.

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

  Gibt die Anzahl der Einträge im angegebenen Typ von Befehlsprotokoll zurück.

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

  Löscht alle Einträge aus dem angegebenen Typ von Befehlsprotokoll.

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

  Entfernt alle Schlüssel aus allen Datenbanken. Es kann nicht garantiert werden, dass diese Operation in allen Slots atomar abläuft. 

  [Weitere Informationen](https://valkey.io/commands/flushall/)
+ `FLUSHDB`

  Entfernt alle Schlüssel aus der aktuellen Datenbank. Es kann nicht garantiert werden, dass diese Operation in allen Slots atomar abläuft.

  [Weitere Informationen](https://valkey.io/commands/flushdb/)
+ `INFO`

  Gibt Informationen und Statistiken über den Server zurück.

  [Weitere Informationen](https://valkey.io/commands/info/)
+ `LOLWUT`

  Zeigt Computergrafiken und die Valkey- oder Redis-OSS-Version an.

  [Weitere Informationen](https://valkey.io/commands/lolwut/)
+ `ROLE`

  Gibt die Replikationsrolle zurück.

  [Weitere Informationen](https://valkey.io/commands/role/)
+ `TIME`

  Gibt die Serverzeit zurück.

  [Weitere Informationen](https://valkey.io/commands/time/)

**Set-Befehle**
+ `SADD`

  Fügt einem Set ein oder mehrere Mitglieder hinzu. Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/sadd/)
+ `SCARD`

  Gibt die Anzahl der Mitglieder in einem Set zurück.

  [Weitere Informationen](https://valkey.io/commands/scard/)
+ `SDIFF`

  Gibt die Differenz zwischen mehreren Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/sdiff/)
+ `SDIFFSTORE`

  Speichert die Differenz zwischen mehreren Sets in einem Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/sdiffstore/)
+ `SINTER`

  Gibt den Schnittpunkt mehrerer Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/sinter/)
+ `SINTERCARD`

  Gibt die Anzahl der Mitglieder des Schnittpunkts mehrerer Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/sintercard/)
+ `SINTERSTORE`

  Speichert den Schnittpunkt mehrerer Sets in einem Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/sinterstore/)
+ `SISMEMBER`

  Ermittelt, ob ein Mitglied zu einem Set gehört.

  [Weitere Informationen](https://valkey.io/commands/sismember/)
+ `SMEMBERS`

  Gibt alle Mitglieder eines Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/smembers/)
+ `SMISMEMBER`

  Ermittelt, ob mehrere Mitglieder zu einem Set gehören.

  [Weitere Informationen](https://valkey.io/commands/smismember/)
+ `SMOVE`

  Verschiebt ein Mitglied von einem Set in ein anderes.

  [Weitere Informationen](https://valkey.io/commands/smove/)
+ `SPOP`

  Gibt ein oder mehrere zufällige Mitglieder aus einer Gruppe zurück, nachdem sie entfernt wurden. Löscht das Set, wenn das letzte Mitglied gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/spop/)
+ `SRANDMEMBER`

  Ruft ein oder mehrere zufällige Mitglieder aus einem Set ab.

  [Weitere Informationen](https://valkey.io/commands/srandmember/)
+ `SREM`

  Entfernt ein oder mehrere Mitglieder aus einem Set. Löscht das Set, wenn das letzte Mitglied entfernt wurde.

  [Weitere Informationen](https://valkey.io/commands/srem/)
+ `SSCAN`

  Iteriert über Mitglieder eines Sets.

  [Weitere Informationen](https://valkey.io/commands/sscan/)
+ `SUNION`

  Gibt die Vereinigung mehrerer Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/sunion/)
+ `SUNIONSTORE`

  Speichert die Vereinigung mehrerer Sets in einem Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/sunionstore/)

**Befehle zu Sorted Sets**
+ `BZMPOP`

  Entfernt ein Mitglied aus einem oder mehreren sortierten Sets und gibt es nach Score zurück. Blockiert, bis ein Element anderweitig verfügbar ist. Löscht das sortierte Set, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/bzmpop/)
+ `BZPOPMAX`

  Entfernt das Element mit dem höchsten Score aus einem oder mehreren sortierten Sets und gibt es zurück. Blockiert, bis ein Element anderweitig verfügbar ist. Löscht das sortierte Set, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/bzpopmax/)
+ `BZPOPMIN`

  Entfernt das Element mit dem niedrigsten Score aus einem oder mehreren sortierten Sets und gibt es zurück. Blockiert, bis ein Element anderweitig verfügbar ist. Löscht das sortierte Set, wenn das letzte Element gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/bzpopmin/)
+ `ZADD`

  Fügt einem sortierten Set ein oder mehrere Mitglieder hinzu oder aktualisiert deren Scores. Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/zadd/)
+ `ZCARD`

  Gibt die Anzahl der Mitglieder in einem sortierten Set zurück.

  [Weitere Informationen](https://valkey.io/commands/zcard/)
+ `ZCOUNT`

  Gibt die Anzahl der Mitglieder in einem sortierten Set zurück, deren Scores innerhalb eines bestimmten Bereichs liegen.

  [Weitere Informationen](https://valkey.io/commands/zcount/)
+ `ZDIFF`

  Gibt den Unterschied zwischen mehreren sortierten Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/zdiff/)
+ `ZDIFFSTORE`

  Speichert den Unterschied mehrerer sortierter Sets in einem Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/zdiffstore/)
+ `ZINCRBY`

  Inkrementiert den Score eines Mitglieds in einem sortierten Set.

  [Weitere Informationen](https://valkey.io/commands/zincrby/)
+ `ZINTER`

  Gibt den Schnittpunkt mehrerer sortierter Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/zinter/)
+ `ZINTERCARD`

  Gibt die Anzahl der Mitglieder des Schnittpunkts mehrerer sortierter Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/zintercard/)
+ `ZINTERSTORE`

  Speichert den Schnittpunkt mehrerer sortierter Sets in einem Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/zinterstore/)
+ `ZLEXCOUNT`

  Gibt die Anzahl der Elemente in einem sortierten Set innerhalb eines lexikografischen Bereichs zurück.

  [Weitere Informationen](https://valkey.io/commands/zlexcount/)
+ `ZMPOP`

  Gibt die Elemente mit dem höchsten oder niedrigsten Score aus einem oder mehreren sortierten Sets zurück, nachdem sie entfernt wurden. Löscht das sortierte Set, wenn das letzte Mitglied gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/zmpop/)
+ `ZMSCORE`

  Gibt den Score eines oder mehrerer Mitglieder eines sortierten Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/zmscore/)
+ `ZPOPMAX`

  Gibt die Mitglieder mit dem höchsten Score aus einem sortierten Set zurück, nachdem sie entfernt wurden. Löscht das sortierte Set, wenn das letzte Mitglied gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/zpopmax/)
+ `ZPOPMIN`

  Gibt die Mitglieder mit dem niedrigsten Score aus einem sortierten Set zurück, nachdem sie entfernt wurden. Löscht das sortierte Set, wenn das letzte Mitglied gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/zpopmin/)
+ `ZRANDMEMBER`

  Gibt ein oder mehrere zufällige Mitglieder aus einem sortierten Set zurück.

  [Weitere Informationen](https://valkey.io/commands/zrandmember/)
+ `ZRANGE`

  Gibt Elemente in einem sortierten Set innerhalb eines Indexbereichs zurück.

  [Weitere Informationen](https://valkey.io/commands/zrange/)
+ `ZRANGEBYLEX`

  Gibt Elemente in einem sortierten Set innerhalb eines lexikografischen Bereichs zurück.

  [Weitere Informationen](https://valkey.io/commands/zrangebylex/)
+ `ZRANGEBYSCORE`

  Gibt Elemente in einem sortierten Set innerhalb eines Score-Bereichs zurück.

  [Weitere Informationen](https://valkey.io/commands/zrangebyscore/)
+ `ZRANGESTORE`

  Speichert einen Bereich von Elementen aus einem sortierten Set in einem Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/zrangestore/)
+ `ZRANK`

  Gibt den Index eines Elements in einem sortierten Set zurück, sortiert nach aufsteigenden Scores.

  [Weitere Informationen](https://valkey.io/commands/zrank/)
+ `ZREM`

  Entfernt ein oder mehrere Elemente aus einem sortierten Set. Löscht das sortierte Set, wenn alle Elemente entfernt wurden.

  [Weitere Informationen](https://valkey.io/commands/zrem/)
+ `ZREMRANGEBYLEX`

  Entfernt Elemente in einem sortierten Set innerhalb eines lexikografischen Bereichs. Löscht das sortierte Set, wenn alle Elemente entfernt wurden.

  [Weitere Informationen](https://valkey.io/commands/zremrangebylex/)
+ `ZREMRANGEBYRANK`

  Entfernt Elemente in einem sortierten Sete innerhalb eines Indexbereichs. Löscht das sortierte Set, wenn alle Elemente entfernt wurden.

  [Weitere Informationen](https://valkey.io/commands/zremrangebyrank/)
+ `ZREMRANGEBYSCORE`

  Entfernt Elemente aus einem sortierten Set innerhalb eines Score-Bereichs. Löscht das sortierte Set, wenn alle Elemente entfernt wurden.

  [Weitere Informationen](https://valkey.io/commands/zremrangebyscore/)
+ `ZREVRANGE`

  Gibt Elemente in einem sortierten Set innerhalb eines Indexbereichs in umgekehrter Reihenfolge zurück.

  [Weitere Informationen](https://valkey.io/commands/zrevrange/)
+ `ZREVRANGEBYLEX`

  Gibt Elemente in einem sortierten Set innerhalb eines lexikografischen Bereichs in umgekehrter Reihenfolge zurück.

  [Weitere Informationen](https://valkey.io/commands/zrevrangebylex/)
+ `ZREVRANGEBYSCORE`

  Gibt Elemente in einem sortierten Set innerhalb eines Score-Bereichs in umgekehrter Reihenfolge zurück.

  [Weitere Informationen](https://valkey.io/commands/zrevrangebyscore/)
+ `ZREVRANK`

  Gibt den Index eines Elements in einem sortierten Set zurück, sortiert nach absteigenden Scores.

  [Weitere Informationen](https://valkey.io/commands/zrevrank/)
+ `ZSCAN`

  Iteriert über Elemente und Scores eines sortierten Sets.

  [Weitere Informationen](https://valkey.io/commands/zscan/)
+ `ZSCORE`

  Gibt den Score eines Elements in einem sortierten Set zurück.

  [Weitere Informationen](https://valkey.io/commands/zscore/)
+ `ZUNION`

  Gibt die Vereinigung mehrerer sortierter Sets zurück.

  [Weitere Informationen](https://valkey.io/commands/zunion/)
+ `ZUNIONSTORE`

  Speichert die Vereinigung mehrerer sortierter Sets in einem Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/zunionstore/)

**Stream-Befehle**
+ `XACK`

  Gibt die Anzahl der Nachrichten zurück, die vom Mitglied der Verbrauchergruppe eines Streams erfolgreich bestätigt wurden.

  [Weitere Informationen](https://valkey.io/commands/xack/)
+ `XADD`

  Hängt eine neue Nachricht an einen Stream an. Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/xadd/)
+ `XAUTOCLAIM`

  Ändert oder erwirbt den Besitz von Nachrichten in einer Verbrauchergruppe, als ob die Nachrichten als Mitglied der Verbrauchergruppe zugestellt würden.

  [Weitere Informationen](https://valkey.io/commands/xautoclaim/)
+ `XCLAIM`

  Ändert oder erwirbt den Besitz einer Nachricht in einer Verbrauchergruppe, als ob die Nachricht als Mitglied der Verbrauchergruppe zugestellt würde.

  [Weitere Informationen](https://valkey.io/commands/xclaim/)
+ `XDEL`

  Gibt die Anzahl der Nachrichten zurück, nachdem sie aus einem Stream entfernt wurden.

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

  Erstellt eine Verbrauchergruppe. 

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

  Erstellt einen Verbraucher in einer Verbrauchergruppe.

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

  Löscht einen Verbraucher aus einer Verbrauchergruppe.

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

  Löscht eine Verbrauchergruppe.

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

  Legt die zuletzt zugestellte ID einer Verbrauchergruppe fest.

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

  Gibt eine Liste der Verbraucher in einer Verbrauchergruppe zurück.

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

  Gibt eine Liste der Verbrauchergruppen eines Streams zurück.

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

  Gibt Informationen zu einem Stream zurück.

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

  Gibt die Anzahl der Nachrichten in einem Stream zurück.

  [Weitere Informationen](https://valkey.io/commands/xlen/)
+ `XPENDING`

  Gibt die Informationen und Einträge aus der Liste der ausstehenden Einträge einer Stream-Verbrauchergruppe zurück.

  [Weitere Informationen](https://valkey.io/commands/xpending/)
+ `XRANGE`

  Gibt die Nachrichten aus einem Stream innerhalb eines Bereichs von zurück. IDs

  [Weitere Informationen](https://valkey.io/commands/xrange/)
+ `XREAD`

  Gibt Nachrichten aus mehreren Streams zurück, deren IDs Anzahl größer als die angeforderten ist. Blockiert, bis eine Nachricht anderweitig verfügbar ist.

  [Weitere Informationen](https://valkey.io/commands/xread/)
+ `XREADGROUP`

  Gibt neue oder historische Nachrichten aus einem Stream für einen Verbraucher in einer Gruppe zurück. Blockiert, bis eine Nachricht anderweitig verfügbar ist.

  [Weitere Informationen](https://valkey.io/commands/xreadgroup/)
+ `XREVRANGE`

  Gibt die Nachrichten aus einem Stream innerhalb eines Bereichs von IDs in umgekehrter Reihenfolge zurück.

  [Weitere Informationen](https://valkey.io/commands/xrevrange/)
+ `XTRIM`

  Löscht Nachrichten am Anfang eines Streams.

  [Weitere Informationen](https://valkey.io/commands/xtrim/)

**Zeichenfolgenbefehle**
+ `APPEND`

  Hängt eine Zeichenfolge an den Wert eines Schlüssels an. Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/append/)
+ `DECR`

  Dekrementiert den Ganzzahlwert eines Schlüssels um eins. Verwendet 0 als Anfangswert, wenn der Schlüssel nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/decr/)
+ `DECRBY`

  Dekrementiert eine Zahl vom Ganzzahlwert eines Schlüssels. Verwendet 0 als Anfangswert, wenn der Schlüssel nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/decrby/)
+ `GET`

  Gibt den Zeichenfolgenwert eines Schlüssels zurück.

  [Weitere Informationen](https://valkey.io/commands/get/)
+ `GETDEL`

  Gibt den Zeichenfolgenwert eines Schlüssels zurück, nachdem der Schlüssel gelöscht wurde.

  [Weitere Informationen](https://valkey.io/commands/getdel/)
+ `GETEX`

  Gibt den Zeichenfolgenwert eines Schlüssels zurück, nachdem dessen Ablaufzeit festgelegt wurde.

  [Weitere Informationen](https://valkey.io/commands/getex/)
+ `GETRANGE`

  Gibt eine Teilzeichenfolge der Zeichenfolge zurück, die in einem Schlüssel gespeichert ist.

  [Weitere Informationen](https://valkey.io/commands/getrange/)
+ `GETSET`

  Gibt den vorherigen Zeichenfolgenwert eines Schlüssels zurück, nachdem dieser auf einen neuen Wert festgelegt wurde.

  [Weitere Informationen](https://valkey.io/commands/getset/)
+ `INCR`

  Inkrementiert den Ganzzahlwert eines Schlüssels um eins. Verwendet 0 als Anfangswert, wenn der Schlüssel nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/incr/)
+ `INCRBY`

  Inkrementiert den Ganzzahlwert eines Schlüssels um eine Zahl. Verwendet 0 als Anfangswert, wenn der Schlüssel nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/incrby/)
+ `INCRBYFLOAT`

  Inkrementiert den Gleitkommawert eines Schlüssels um eine Zahl. Verwendet 0 als Anfangswert, wenn der Schlüssel nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/incrbyfloat/)
+ `LCS`

  Findet die längste gemeinsame Teilzeichenfolge.

  [Weitere Informationen](https://valkey.io/commands/lcs/)
+ `MGET`

  Gibt atomar die Zeichenfolgenwerte eines oder mehrerer Schlüssel zurück.

  [Weitere Informationen](https://valkey.io/commands/mget/)
+ `MSET`

  Erstellt oder ändert atomar die Zeichenfolgenwerte eines oder mehrerer Schlüssel.

  [Weitere Informationen](https://valkey.io/commands/mset/)
+ `MSETNX`

  Ändert die Zeichenfolgenwerte eines oder mehrerer Schlüssel nur dann atomar, wenn alle Schlüssel nicht existieren.

  [Weitere Informationen](https://valkey.io/commands/msetnx/)
+ `PSETEX`

  Legt sowohl den Zeichenfolgenwert als auch die Ablaufzeit eines Schlüssels in Millisekunden fest. Der Schlüssel wird erstellt, wenn er nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/psetex/)
+ `SET`

  Legt den Zeichenfolgenwert eines Schlüssels fest, wobei sein Typ ignoriert wird. Der Schlüssel wird erstellt, wenn er nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/set/)
+ `SETEX`

  Legt den Zeichenfolgenwert und die Ablaufzeit eines Schlüssels fest. Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/setex/)
+ `SETNX`

  Legt den Zeichenfolgenwert eines Schlüssels nur fest, wenn der Schlüssel nicht existiert.

  [Weitere Informationen](https://valkey.io/commands/setnx/)
+ `SETRANGE`

  Überschreibt einen Teil eines Zeichenfolgenwerts durch einen anderen um einen Offset. Erstellt den Schlüssel, sofern er nicht vorhanden ist.

  [Weitere Informationen](https://valkey.io/commands/setrange/)
+ `STRLEN`

  Gibt die Länge eines Zeichenfolgenwerts zurück.

  [Weitere Informationen](https://valkey.io/commands/strlen/)
+ `SUBSTR`

  Gibt eine Teilzeichenfolge aus einem Zeichenfolgenwert zurück.

  [Weitere Informationen](https://valkey.io/commands/substr/)

**Transaktionsbefehle**
+ `DISCARD`

  Verwirft eine Transaktion.

  [Weitere Informationen](https://valkey.io/commands/discard/)
+ `EXEC`

  Führt alle Befehle in einer Transaktion aus.

  [Weitere Informationen](https://valkey.io/commands/exec/)
+ `MULTI`

  Startet eine Transaktion.

  [Weitere Informationen](https://valkey.io/commands/multi/)

## Eingeschränkte Valkey- und Redis OSS-Befehle
<a name="RestrictedCommandsRedis"></a>

 ElastiCache Schränkt den Zugriff auf bestimmte Cache-Engine-spezifische Befehle ein, die erweiterte Rechte erfordern, um ein Managed Service-Erlebnis zu bieten. Für Caches, auf denen Redis OSS ausgeführt wird, sind die folgenden Befehle nicht verfügbar:
+ `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`

Darüber hinaus sind die folgenden Befehle für Serverless-Caches nicht verfügbar:
+ `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`

## Unterstützte Memcached-Befehle
<a name="SupportedCommandsMem"></a>

ElastiCache Serverless for Memcached unterstützt alle [Memcached-Befehle](https://github.com/memcached/memcached/wiki/Commands) in Open Source Memcached 1.6 mit Ausnahme der folgenden: 
+ Client-Verbindungen erfordern TLS, weshalb das UDP-Protokoll nicht unterstützt wird.
+ Das Binärprotokoll wird nicht unterstützt, da es in Memcached 1.6 offiziell [veraltet](https://github.com/memcached/memcached/wiki/ReleaseNotes160) ist.
+ `GET/GETS`-Befehle sind auf 16 KB begrenzt, um einen möglichen DoS-Angriff auf den Server durch Abrufen einer großen Anzahl von Schlüsseln zu vermeiden.
+ Ein verzögerter `flush_all`-Befehl wird mit `CLIENT_ERROR` zurückgewiesen.
+ Befehle, die die Engine konfigurieren oder interne Informationen zum Engine-Status oder zu Protokollen preisgeben, werden nicht unterstützt. Dazu gehören:
  + Für `STATS`-Befehle werden nur `stats` und `stats reset` unterstützt. Für andere Varianten wird `ERROR` zurückgegeben.
  + `lru / lru_crawler` – Änderung der LRU- und LRU-Crawler-Einstellungen
  + `watch` – beobachtet Memcached-Serverprotokolle
  + `verbosity` – konfiguriert die Protokollstufe des Servers
  + `me`- Der Befehl meta debug (me) wird nicht unterstützt

# Konfiguration und Grenzwerte für Valkey und Redis OSS
<a name="RedisConfiguration"></a>

Die Valkey- und Redis OSS-Engines bieten jeweils eine Reihe von Konfigurationsparametern, von denen einige ElastiCache für Redis OSS modifizierbar sind und andere nicht modifizierbar sind, um eine stabile Leistung und Zuverlässigkeit zu gewährleisten.

## Serverless-Caches
<a name="RedisConfiguration.Serverless"></a>

Für serverlose Caches werden keine Parametergruppen verwendet und die gesamte Valkey- oder Redis-OSS-Konfiguration kann nicht geändert werden. Die folgenden Valkey- oder Redis-OSS-Parameter sind vorhanden:


****  

|  Name  |  Details  |  Description  | 
| --- | --- | --- | 
| acl-pubsub-default | `allchannels` | Standardberechtigungen für Pub/Sub-Kanäle für ACL-Benutzer im Cache. | 
| client-output-buffer-limit | `normal 0 0 0` `pubsub 32mb 8mb 60` | Normale Clients haben kein Pufferlimit. PUB/SUB Clients werden getrennt, wenn sie den 32 MiB-Backlog oder den 8 MiB-Backlog für 60 Sekunden überschreiten. | 
| client-query-buffer-limit | 1 GiB | Die maximale Größe eines einzelnen Client-Abfragepuffers. Darüber hinaus können Kunden keine Anfrage mit mehr als 3.999 Argumenten stellen. | 
| cluster-allow-pubsubshard-when-down | yes | Dadurch kann der Cache Pub/Sub-Datenverkehr bereitstellen, während der Cache teilweise ausgefallen ist. | 
| cluster-allow-reads-when-down | yes | Dadurch kann der Cache Lesedatenverkehr bereitstellen, während der Cache teilweise ausgefallen ist. | 
| cluster-enabled | yes | Für alle Serverless-Caches ist der Clustermodus aktiviert, sodass sie ihre Daten transparent auf mehrere Backend-Shards partitionieren können. Alle Slots werden den Clients so angezeigt, als gehörten sie einem einzigen virtuellen Knoten. | 
| cluster-require-full-coverage | no | Wenn der Keyspace teilweise ausgefallen ist (d. h. auf mindestens einen Hash-Slot kann nicht zugegriffen werden), akzeptiert der Cache weiterhin Abfragen für den Teil des Keyspace, der noch abgedeckt ist. Der gesamte Keyspace wird immer von einem einzigen virtuellen Knoten in cluster slots „abgedeckt“. | 
| lua-time-limit | 5000 | Die maximale Ausführungszeit für ein Lua-Skript in Millisekunden, bevor Maßnahmen zum Stoppen des Skripts ergriffen ElastiCache werden. *Wenn sie überschritten `lua-time-limit` wird, geben alle Valkey- oder Redis OSS-Befehle möglicherweise einen Fehler der Form \$1\$1\$1\$1-BUSY zurück.* *Da dieser Status viele wichtige Valkey- oder Redis-OSS-Operationen stören kann, ElastiCache wird zunächst ein SCRIPT KILL-Befehl ausgegeben.* Wenn dies nicht erfolgreich ist, ElastiCache wird Valkey oder Redis OSS zwangsweise neu gestartet. | 
| maxclients | 65000 | Die maximale Anzahl von Clients, die zu jedem beliebigen Zeitpunkt mit dem Cache verbunden sein können. Weitere Verbindungen können erfolgreich hergestellt werden oder auch nicht. | 
| maxmemory-policy | volatile-lru | Elemente mit einem TTL-Satz werden nach einer Schätzung least-recently-used (LRU) gelöscht, wenn das Speicherlimit eines Caches erreicht ist. | 
| notify-keyspace-events | (eine leere Zeichenfolge) | Keyspace-Ereignisse werden in Serverless-Caches derzeit nicht unterstützt. | 
| port | Primärer Port: 6379 Leseport: 6380 | Serverless-Caches kündigen zwei Ports mit demselben Hostnamen an. Der primäre Port lässt Schreib- und Lesevorgänge zu, wohingegen der Leseport mithilfe des Befehls READONLY letztendlich konsistente Lesevorgänge mit niedrigerer Latenz ermöglicht. | 
| proto-max-bulk-len | 512 MiB | Die maximale Größe einer einzelnen Elementanforderung. | 
| timeout | 0 | Zu einer bestimmten Leerlaufzeit werden die Verbindungen mit Clients nicht gewaltsam getrennt, sie können jedoch aus Gründen des Lastausgleichs im stabilen Zustand getrennt werden. | 

Darüber hinaus gelten die folgenden Limits:


****  

|  Name  |  Details  |  Description  | 
| --- | --- | --- | 
| Größe pro Cache | 5.000 GiB | Maximale Datenmenge, die pro serverlosem Cache gespeichert werden kann. | 
| Größe pro Steckplatz | 32 GiB | Die maximale Größe eines einzelnen Valkey- oder Redis OSS-Hash-Slots. Clients, die versuchen, mehr Daten auf einem einzelnen Valkey- oder Redis-OSS-Steckplatz zu speichern, lösen die Räumungsrichtlinie für den Steckplatz aus, und wenn keine Schlüssel entfernt werden können, wird ein Fehler wegen Speichermangel () angezeigt. OOM | 
| ECPU pro Cache | 15.000.000 ECPU/Sekunde | ElastiCache Metrisch für Verarbeitungseinheiten (ECPU) Die Anzahl der von Ihren Anfragen ECPUs verbrauchten Daten hängt von der vCPU vCPU-Zeit und der Menge der übertragenen Daten ab. | 
| ECPU pro Steckplatz | 30.000 bis 90.000 ECPU/Sekunde | Maximal 30.000 ECPUs/second pro Steckplatz oder 90.000 ECPUs/second bei Verwendung von Read from Replica mit READONLY-Verbindungen. | 
| Argumente pro Anfrage | 3.999 | Maximale Anzahl von Argumenten pro Anfrage. Clients, die mehr Argumente pro Anfrage senden, erhalten eine Fehlermeldung. | 
| Länge des Schlüsselnamens | 4 KiB | Die maximale Größe für einen einzelnen Valkey- oder Redis-OSS-Schlüssel oder Kanalnamen. Clients, die auf Schlüssel verweisen, die größer sind, wird eine Fehlermeldung angezeigt. | 
| Größe des Lua-Skripts | 4 MiB | Die maximale Größe eines einzelnen Valkey- oder Redis OSS-Lua-Skripts. Versuche, ein Lua-Skript zu laden, das größer ist als dieses, führen zu einer Fehlermeldung. | 

## Knotenbasierte Cluster
<a name="RedisConfiguration.SelfDesigned"></a>

Informationen zu knotenbasierten Clustern finden Sie unter [Valkey- und Redis OSS-Parameter](ParameterGroups.Engine.md#ParameterGroups.Redis) Die Standardwerte der Konfigurationsparameter und die konfigurierbaren Werte. Die Standardwerte werden generell empfohlen, es sei denn, Sie haben einen bestimmten Anwendungsfall, bei dem sie außer Kraft gesetzt werden müssen.

# IPv6 Kundenbeispiele für Valkey, Memcached und Redis OSS
<a name="network-type-best-practices"></a>

ElastiCache ist mit Valkey, Memcached und Redis OSS kompatibel. Das bedeutet, dass Clients, die IPv6 Verbindungen unterstützen, in der Lage sein sollten, eine Verbindung zu Clustern herzustellen, die für Memcached IPv6 aktiviert sind ElastiCache . Bei der Interaktion mit IPv6 aktivierten Ressourcen gibt es einige Vorsichtsmaßnahmen, die es zu beachten gilt.

Empfehlungen zur Konfiguration von [Valkey- und Redis OSS-Clients für Ressourcen finden Sie im Blogbeitrag Best Practices](https://aws.amazon.com/blogs/database/best-practices-redis-clients-and-amazon-elasticache-for-redis/) für Valkey- und Redis-Clients im AWS Datenbank-Blog. ElastiCache 

Im Folgenden finden Sie bewährte Methoden für die Interaktion mit IPv6 aktivierten ElastiCache Ressourcen mithilfe häufig verwendeter Open-Source-Clientbibliotheken. 

## Validierte Kunden mit Valkey und Redis OSS
<a name="network-type-validated-clients-redis"></a>

ElastiCache ist mit Valkey und dem Open-Source-Redis OSS kompatibel. Das bedeutet, dass Valkey- und Open-Source-Redis-OSS-Clients, die IPv6 Verbindungen unterstützen, in der Lage sein sollten, eine Verbindung zu für Redis IPv6 aktivierten ElastiCache OSS-Clustern herzustellen. Darüber hinaus wurden mehrere der beliebtesten Python- und Java-Clients speziell getestet und validiert, sodass sie mit allen unterstützten Netzwerktypkonfigurationen (IPv4 nur, IPv6 nur und Dual Stack) funktionieren.

Die folgenden Clients wurden speziell dafür validiert, dass sie mit allen unterstützten Netzwerktypkonfigurationen für Valkey und Redis OSS funktionieren.

Validierte Clients:
+ [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/) – [Version: 6.1.6.RELEASE](https://github.com/lettuce-io/lettuce-core/tree/6.1.6.RELEASE)
+ [Jedis](https://github.com/redis/jedis) – [Version: 3.6.0](https://github.com/redis/jedis/tree/jedis-3.6.0)

# Bewährte Methoden für Kunden (Valkey und Redis OSS)
<a name="BestPractices.Clients.redis"></a>

Lernen Sie bewährte Methoden für gängige Szenarien kennen und folgen Sie den Codebeispielen einiger der beliebtesten Open-Source-Clientbibliotheken von Valkey und Redis OSS (redis-py und Lettuce) sowie von Best Practices für die Interaktion mit ElastiCache Ressourcen mit häufig verwendeten Open-Source-Memcached-Clientbibliotheken. PHPRedis

**Topics**
+ [Große Anzahl von Verbindungen (Valkey und Redis OSS)](BestPractices.Clients.Redis.Connections.md)
+ [Cluster-Client-Erkennung und exponentielles Backoff (Valkey und Redis OSS)](BestPractices.Clients.Redis.Discovery.md)
+ [Konfigurieren Sie ein clientseitiges Timeout (Valkey und Redis OSS)](BestPractices.Clients.Redis.ClientTimeout.md)
+ [Konfigurieren Sie ein serverseitiges Leerlauf-Timeout (Valkey und Redis OSS)](BestPractices.Clients.Redis.ServerTimeout.md)
+ [Lua-Skripte](BestPractices.Clients.Redis.LuaScripts.md)
+ [Speichern großer zusammengesetzter Artikel (Valkey und Redis OSS)](BestPractices.Clients.Redis.LargeItems.md)
+ [Konfiguration des Lettuce-Clients (Valkey und Redis OSS)](BestPractices.Clients-lettuce.md)
+ [Konfiguration eines bevorzugten Protokolls für Dual-Stack-Cluster (Valkey und Redis OSS)](#network-type-configuring-dual-stack-redis)

# Große Anzahl von Verbindungen (Valkey und Redis OSS)
<a name="BestPractices.Clients.Redis.Connections"></a>

Serverlose Caches und individuelle Caches ElastiCache für Redis OSS-Knoten unterstützen bis zu 65.000 gleichzeitige Client-Verbindungen. Zur Optimierung der Leistung empfehlen wir jedoch, dass Client-Anwendungen nicht ständig mit diesem Verbindungsaufkommen arbeiten. Valkey und Redis OSS verfügen jeweils über einen Single-Thread-Prozess, der auf einer Ereignisschleife basiert, in der eingehende Client-Anfragen sequentiell bearbeitet werden. Das bedeutet, dass die Antwortzeit eines bestimmten Clients mit zunehmender Anzahl verbundener Clients länger wird.

Sie können die folgenden Maßnahmen ergreifen, um einen Verbindungsengpass auf einem Valkey- oder Redis OSS-Server zu vermeiden:
+ Führen Sie Lesevorgänge von Read Replicas aus durch. Dies kann durch die Verwendung der ElastiCache Leser-Endpunkte im deaktivierten Clustermodus oder durch die Verwendung von Replikaten für Lesevorgänge im aktivierten Clustermodus, einschließlich eines serverlosen Caches, erreicht werden.
+ Verteilen Sie den Schreibdatenverkehr auf mehrere Primärknoten. Es gibt zwei Methoden dafür: Sie können einen Valkey- oder Redis-OSS-Cluster mit mehreren Shards und einem Client verwenden, der den Clustermodus unterstützt. Sie können auch im deaktivierten Cluster-Modus mit clientseitigem Sharding auf mehrere Primärknoten schreiben. Dies erfolgt automatisch in einem Serverless-Cache.
+ Verwenden Sie einen Verbindungspool, sofern dieser in Ihrer Client-Bibliothek verfügbar ist.

Im Allgemeinen ist das Erstellen einer TCP-Verbindung im Vergleich zu typischen Valkey- oder Redis OSS-Befehlen ein rechenintensiver Vorgang. Beispielsweise ist die Bearbeitung einer SET/GET Anfrage um eine Größenordnung schneller, wenn eine bestehende Verbindung wiederverwendet wird. Durch die Verwendung eines Client-Verbindungspools mit begrenzter Größe wird der Aufwand für die Verbindungsverwaltung reduziert. Außerdem wird dadurch die Anzahl der gleichzeitig eingehenden Verbindungen von der Client-Anwendung begrenzt.

Das folgende Codebeispiel PHPRedis zeigt, dass für jede neue Benutzeranfrage eine neue Verbindung erstellt wird:

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

Wir haben diesen Code in einer Schleife auf einer Amazon Elastic Compute Cloud (Amazon EC2) -Instance verglichen, die mit einem Graviton2 (m6g.2xlarge) für Redis OSS-Knoten verbunden ist. ElastiCache Client und Server wurden in derselben Availability Zone platziert. Die durchschnittliche Latenz des gesamten Vorgangs betrug 2,82 Millisekunden.

Beim Aktualisieren des Codes und bei Verwendung persistenter Verbindungen sowie eines Verbindungspools betrug die durchschnittliche Latenz des gesamten Vorgangs 0,21 Millisekunden:

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

Erforderliche Konfigurationen für redis.ini:
+ `redis.pconnect.pooling_enabled=1`
+ `redis.pconnect.connection_limit=10`

Der folgende Code ist ein Beispiel für einen [Redis-py-Verbindungspool](https://redis.readthedocs.io/en/stable/):

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

Der folgende Code ist ein Beispiel für einen [Lettuce-Verbindungspool](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);
}
```

# Cluster-Client-Erkennung und exponentielles Backoff (Valkey und Redis OSS)
<a name="BestPractices.Clients.Redis.Discovery"></a>

Wenn Sie im aktivierten Clustermodus eine Verbindung zu einem ElastiCache Valkey- oder Redis-OSS-Cluster herstellen, muss die entsprechende Clientbibliothek clusterfähig sein. Die Clients müssen eine Zuordnung der Hash-Slots zu den entsprechenden Knoten im Cluster abrufen, um Anfragen an die richtigen Knoten zu senden und den zusätzlichen Leistungsaufwand bei der Bearbeitung von Cluster-Umleitungen zu vermeiden. Aus diesem Grund muss der Client in zwei verschiedenen Situationen eine vollständige Liste der Slots und der zugewiesenen Knoten erkennen:
+ Der Client ist initialisiert und muss die anfängliche Slot-Konfiguration auffüllen.
+ Eine MOVED-Umleitung wird vom Server empfangen, z. B. im Fall eines Failovers, bei dem alle vom ehemaligen Primärknoten bereitgestellten Slots vom Replikat übernommen werden, oder beim Re-Sharding, wenn Slots vom primären Quellknoten zum primären Zielknoten verschoben werden.

Die Client-Erkennung erfolgt normalerweise durch Ausgabe eines CLUSTER SLOT- oder CLUSTER NODE-Befehls an den Valkey- oder Redis OSS-Server. Wir empfehlen die CLUSTER SLOT-Methode, da sie das Set der Slot-Bereiche und die zugehörigen Primär- und Replikatknoten an den Client zurückgibt. Dies erfordert kein zusätzliches Parsen durch den Client und ist effizienter.

Abhängig von der Cluster-Topologie kann die Größe der Antwort auf den Befehl CLUSTER SLOT je nach Clustergröße variieren. Größere Cluster mit mehr Knoten erzeugen eine größere Antwort. Daher muss sichergestellt werden, dass die Anzahl der Clients, die die Cluster-Topologie ermitteln, nicht unbegrenzt zunimmt. Wenn beispielsweise die Client-Anwendung startet oder die Verbindung mit dem Server unterbrochen wird und die Cluster-Erkennung durchgeführt werden muss, besteht ein häufiger Fehler darin, dass die Client-Anwendung mehrere Wiederverbindungs- und Erkennungsanforderungen auslöst, ohne dass bei einem erneuten Versuch ein exponentielles Backoff erfolgt. Dies kann dazu führen, dass der Valkey- oder Redis OSS-Server bei einer CPU-Auslastung von 100% über einen längeren Zeitraum nicht reagiert. Der Ausfall verlängert sich, wenn jeder CLUSTER SLOT-Befehl eine große Anzahl von Knoten im Cluster-Bus verarbeiten muss. Aufgrund dieses Verhaltens haben wir in der Vergangenheit mehrere Client-Ausfälle in verschiedenen Sprachen beobachtet, darunter Python (redis-py-cluster) und Java (Lettuce und Redisson).

In einem Serverless-Cache werden viele der Probleme automatisch behoben, da die angekündigte Cluster-Topologie statisch ist und aus zwei Einträgen besteht: einem Schreib- und einem Lese-Endpunkt. Die Cluster-Erkennung wird außerdem automatisch auf mehrere Knoten verteilt, wenn der Cache-Endpunkt verwendet wird. Die folgenden Empfehlungen sind jedoch nach wie vor nützlich.

Wir empfehlen Folgendes, um die Auswirkungen eines plötzlichen Zustroms von Verbindungs- und Erkennungsanforderungen zu minimieren:
+ Implementieren Sie einen Client-Verbindungspool mit einer begrenzten Größe, um die Anzahl der gleichzeitig eingehenden Verbindungen von der Client-Anwendung zu begrenzen.
+ Wenn der Client aufgrund eines Timeouts die Verbindung mit dem Server unterbricht, versuchen Sie es erneut mit exponentiellem Backoff mit Jitter. Dadurch wird vermieden, dass mehrere Clients den Server gleichzeitig überlasten.
+ Verwenden Sie die Anleitung unter [Verbindungsendpunkte finden in ElastiCache](Endpoints.md), um den Cluster-Endpunkt zur Durchführung der Cluster-Erkennung zu finden. Dadurch verteilen Sie die Erkennungslast auf alle Knoten im Cluster (bis zu 90), anstatt einige fest codierte Seed-Knoten im Cluster zu erhalten.

Im Folgenden finden Sie einige Codebeispiele für die exponentielle Backoff-Wiederholungslogik in Redis-py, und Lettuce. PHPRedis

**Beispiel 1 für Backoff-Logik: redis-py**

Redis-py verfügt über einen integrierten Wiederholungsmechanismus, der unmittelbar nach einem Fehler einen erneuten Versuch vornimmt. [Dieser Mechanismus kann durch das `retry_on_timeout` Argument aktiviert werden, das beim Erstellen eines Redis-OSS-Objekts angegeben wird.](https://redis.readthedocs.io/en/stable/examples/connection_examples.html#redis.Redis) Hier demonstrieren wir einen benutzerdefinierten Wiederholungsmechanismus mit exponentiellem Backoff und Jitter. Wir haben eine Pull-Anfrage gesendet, um exponentielles Backoff in [redis-py (\$11494)](https://github.com/andymccurdy/redis-py/pull/1494) nativ zu implementieren. Künftig ist eine manuelle Implementierung möglicherweise nicht mehr erforderlich.

```
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
```

Sie können dann den folgenden Code verwenden, um einen Wert festzulegen:

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

Abhängig von Ihrem Workload möchten Sie möglicherweise den Basis-Backoff-Wert von 1 Sekunde auf einige Dutzende oder Hunderte von Millisekunden für latenzempfindliche Workloads ändern.

**Beispiel 2 für Backoff-Logik: PHPRedis**

PHPRedis verfügt über einen integrierten Wiederholungsmechanismus, der (nicht konfigurierbar) maximal zehnmal versucht. Es gibt eine konfigurierbare Verzögerung zwischen den Wiederholungsversuchen (mit einem Jitter ab dem zweiten Versuch). Weitere Informationen finden Sie im folgenden [Codebeispiel](https://github.com/phpredis/phpredis/blob/b0b9dd78ef7c15af936144c1b17df1a9273d72ab/library.c#L335-L368). [Wir haben eine Pull-Anfrage zur nativen Implementierung des exponentiellen Backoffs in [PHPredis (\$11986)](https://github.com/phpredis/phpredis/pull/1986) eingereicht, die inzwischen zusammengeführt und dokumentiert wurde.](https://github.com/phpredis/phpredis/blob/develop/README.md#retry-and-backoff) Für diejenigen, die die neueste Version von verwenden PHPRedis, ist eine manuelle Implementierung nicht erforderlich, aber wir haben hier die Referenz für die Versionen früherer Versionen aufgenommen. Im Folgenden finden Sie zunächst ein Codebeispiel, das die Verzögerung des Wiederholungsmechanismus konfiguriert:

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

**Beispiel 3 für Backoff-Logik: Lettuce**

Lettuce verfügt über integrierte Wiederholungsmechanismen, die auf den exponentiellen Backoff-Strategien basieren, wie im Beitrag [Exponentielles Backoff und Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) beschrieben. Im Folgenden finden Sie einen Codeauszug, der den vollständigen Jitter-Ansatz zeigt:

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

	}
}
```

# Konfigurieren Sie ein clientseitiges Timeout (Valkey und Redis OSS)
<a name="BestPractices.Clients.Redis.ClientTimeout"></a>

**Konfiguration des clientseitigen Timeouts**

Konfigurieren Sie das clientseitige Timeout so, dass der Server genügend Zeit hat, die Anfrage zu verarbeiten und die Antwort zu generieren. Dies ermöglicht einen Fail-Fast, wenn die Verbindung zum Server nicht hergestellt werden kann. Bestimmte Valkey- oder Redis OSS-Befehle können rechenintensiver sein als andere. Zum Beispiel Lua-Skripte oder MULTI/EXEC Transaktionen, die mehrere Befehle enthalten, die atomar ausgeführt werden müssen. Im Allgemeinen wird ein höheres clientseitiges Timeout empfohlen, um ein Timeout des Clients zu vermeiden, bevor die Antwort vom Server empfangen wird. Dies umfasst:
+ Ausführen von Befehlen über mehrere Tasten
+ Ausführen von MULTI/EXEC Transaktionen oder Lua-Skripten, die aus mehreren einzelnen Valkey- oder Redis-OSS-Befehlen bestehen
+ Lesen von großen Werten
+ Durchführen von Blockiervorgängen wie BLPOP

Im Falle eines Blockiervorgangs wie BLPOP empfiehlt es sich, das Befehls-Timeout auf einen Wert festzulegen, der unter dem Socket-Timeout liegt.

Im Folgenden finden Sie Codebeispiele für die Implementierung eines clientseitigen Timeouts in redis-py, und Lettuce. PHPRedis

**Beispiel 1 für eine Timeout-Konfiguration: redis-py**

Im Folgenden finden Sie ein Codebeispiel für 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)
```

**Beispiel 2 für eine Timeout-Konfiguration: PHPRedis**

Das Folgende ist ein Codebeispiel mit 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
```

**Beispiel 3 für eine Timeout-Konfiguration: Lettuce**

Im Folgenden finden Sie ein Codebeispiel für 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();
		}
	}
}
```

# Konfigurieren Sie ein serverseitiges Leerlauf-Timeout (Valkey und Redis OSS)
<a name="BestPractices.Clients.Redis.ServerTimeout"></a>

Wir haben Fälle beobachtet, in denen mit der Anwendung eines Kunden eine hohe Anzahl inaktiver Clients verbunden war, diese aber keine aktiven Befehle sendet. In solchen Szenarien können Sie alle 65 000 Verbindungen mit einer hohen Anzahl inaktiver Clients ausschöpfen. Zur Vermeidung solcher Szenarien konfigurieren Sie die Timeout-Einstellung auf dem Server entsprechend über [Valkey- und Redis OSS-Parameter](ParameterGroups.Engine.md#ParameterGroups.Redis). Dadurch wird sichergestellt, dass der Server die Verbindung inaktiver Clients aktiv trennt, um eine Erhöhung der Anzahl von Verbindungen zu vermeiden. Diese Einstellung ist für Serverless-Caches nicht verfügbar.

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

Valkey und Redis OSS unterstützen mehr als 200 Befehle, einschließlich solcher zum Ausführen von Lua-Skripten. Bei Lua-Skripten gibt es jedoch mehrere Fallstricke, die sich auf den Arbeitsspeicher und die Verfügbarkeit von Valkey oder Redis OSS auswirken können.

**Nicht parametrisierte Lua-Skripte**

Jedes Lua-Skript wird auf dem Valkey- oder Redis-OSS-Server zwischengespeichert, bevor es ausgeführt wird. Unparametrisierte Lua-Skripten sind einzigartig, was dazu führen kann, dass der Valkey- oder Redis-OSS-Server eine große Anzahl von Lua-Skripten speichert und mehr Speicher verbraucht. Damit dies vermieden wird, stellen Sie sicher, dass alle Lua-Skripte parametrisiert sind, und führen Sie bei Bedarf regelmäßig SCRIPT FLUSH aus, um zwischengespeicherte Lua-Skripte zu bereinigen.

Beachten Sie auch, dass Schlüssel bereitgestellt werden müssen. Wenn kein Wert für den KEY-Parameter angegeben wird, schlägt das Skript fehl. Das wird zum Beispiel nicht funktionieren: 

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

Das wird funktionieren:

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

Das folgende Codebeispiel zeigt, wie parametrisierte Skripte verwendet werden. Zunächst haben wir ein Beispiel für einen nicht parametrisierten Ansatz, der zu drei verschiedenen zwischengespeicherten Lua-Skripten führt. Dieser Ansatz wird nicht empfohlen:

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

Verwenden Sie stattdessen das folgende Muster, um ein einzelnes Skript zu erstellen, das übergebene Parameter akzeptieren kann:

```
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
```

**Lang andauernde Lua-Skripte**

Lua-Skripte können mehrere Befehle atomar ausführen, sodass die Ausführung länger dauern kann als bei einem normalen Valkey- oder Redis OSS-Befehl. Wenn das Lua-Skript nur schreibgeschützte Operationen ausführt, können Sie es zwischendurch beenden. Sobald das Lua-Skript jedoch einen Schreibvorgang ausführt, kann es nicht mehr beendet werden und muss vollständig ausgeführt werden. Ein mutierendes Lua-Skript mit langer Laufzeit kann dazu führen, dass der Valkey- oder Redis-OSS-Server lange Zeit nicht reagiert. Zur Behebung dieses Problems vermeiden Sie lang andauernde Lua-Skripte und testen Sie das Skript in einer Vorproduktionsumgebung.

**Lua-Skript mit Stealth-Schreibvorgängen**

Es gibt mehrere Möglichkeiten, wie ein Lua-Skript weiterhin neue Daten in Valkey oder Redis OSS schreiben kann, selbst wenn Valkey oder Redis OSS beendet ist: `maxmemory`
+ Das Skript startet, wenn sich der Valkey- oder Redis-OSS-Server unten `maxmemory` befindet, und enthält mehrere Schreiboperationen
+ Der erste Schreibbefehl des Skripts verbraucht keinen Speicher (wie DEL), gefolgt von weiteren Schreibvorgängen, die Speicher belegen
+ Sie können dieses Problem beheben, indem Sie auf einem anderen Valkey- oder Redis-OSS-Server eine geeignete Räumungsrichtlinie konfigurieren als. `noeviction` Auf diese Weise kann Redis OSS Objekte entfernen und Speicherplatz zwischen Lua-Skripten freigeben.

# Speichern großer zusammengesetzter Artikel (Valkey und Redis OSS)
<a name="BestPractices.Clients.Redis.LargeItems"></a>

In einigen Szenarien kann eine Anwendung große zusammengesetzte Elemente in Valkey oder Redis OSS speichern (z. B. einen Hash-Datensatz mit mehreren GB). Diese Vorgehensweise wird nicht empfohlen, da sie häufig zu Leistungsproblemen in Valkey oder Redis OSS führt. Der Client kann beispielsweise den Befehl HGETALL ausführen, um die gesamte Hash-Sammlung mit mehreren GB abzurufen. Dies kann zu erheblichem Speicherdruck auf den Valkey- oder Redis-OSS-Server führen, der das große Objekt im Client-Ausgabepuffer zwischenspeichert. Außerdem werden bei der Steckplatzmigration im Clustermodus ElastiCache keine Steckplätze migriert, die Elemente mit einer serialisierten Größe von mehr als 256 MB enthalten.

Zur Lösung der Probleme mit großen Elementen wird Folgendes empfohlen:
+ Teilen Sie das große zusammengesetzte Element in mehrere kleinere Objekte auf. Teilen Sie beispielsweise eine große Hash-Sammlung in einzelne Schlüssel-Wert-Felder auf, wobei das Schlüsselnamensschema die Sammlung angemessen widerspiegelt, z. B. indem Sie ein gemeinsames Präfix im Schlüsselnamen verwenden, um die Sammlung von Elementen zu identifizieren. Wenn Sie atomar auf mehrere Felder in derselben Sammlung zugreifen müssen, können Sie den Befehl MGET verwenden, um mehrere Schlüsselwerte in demselben Befehl abzurufen.
+ Wenn Sie alle Optionen geprüft haben und den großen Sammlungsdatensatz immer noch nicht aufteilen können, versuchen Sie, Befehle zu verwenden, die auf eine Teilmenge der Daten in der Sammlung statt auf die gesamte Sammlung angewendet werden. Vermeiden Sie einen Anwendungsfall, bei dem Sie die gesamte Sammlung mit mehreren GB mit demselben Befehl atomar abrufen müssen. Ein Beispiel ist die Verwendung von HGET- oder HMGET-Befehlen anstelle von HGETALL für Hash-Sammlungen.

# Konfiguration des Lettuce-Clients (Valkey und Redis OSS)
<a name="BestPractices.Clients-lettuce"></a>

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

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

**Topics**
+ [Beispiel: Lettuve-Konfiguration für den Clustermodus, TLS aktiviert](BestPractices.Clients-lettuce-cme.md)
+ [Beispiel: Die Lettuce-Konfiguration für den Cluster-Modus ist deaktiviert, TLS aktiviert](BestPractices.Clients-lettuce-cmd.md)

**Java-DNS-Cache-TTLs**

Die Java Virtual Machine (JVM) speichert DNS-Namensauflösungen zwischen. Wenn die JVM einen Hostnamen in eine IP-Adresse auflöst, speichert sie die IP-Adresse für einen bestimmten Zeitraum, der als (TTL) bezeichnet wird. *time-to-live*

Die Wahl des TTL-Werts ist ein Kompromiss zwischen Latenz auf der einen und Reaktionsfähigkeit auf Änderungen auf der anderen Seite. Bei einer kürzeren TTLs Variante erkennen DNS-Resolver Aktualisierungen im DNS des Clusters schneller. Dadurch kann Ihre Anwendung schneller auf Ersetzungen oder andere Workflows reagieren, denen Ihr Cluster unterzogen wird. Ist die TTL jedoch zu niedrig, erhöht sich das Abfragevolumen, was die Latenz Ihrer Anwendung erhöhen kann. Zwar gibt es keinen korrekten TTL-Wert, ist es bei der Festlegung des TTL-Werts beachtenswert, zu berücksichtigen, wie lange Sie darauf warten können, das eine Änderung wirksam wird.

Da ElastiCache Knoten DNS-Namenseinträge verwenden, die sich ändern können, empfehlen wir Ihnen, Ihre JVM mit einer niedrigen TTL von 5 bis 10 Sekunden zu konfigurieren. Auf diese Weise wird bei Änderung der IP-Adresse eines Knotens sichergestellt, dass Ihre Anwendung die neue IP-Adresse der Ressource durch erneute Abfrage des DNS-Eintrags abrufen und nutzen kann.

Bei einigen Java-Konfigurationen ist die JVM-Standard-TTL so festgelegt, dass DNS-Einträge nie aktualisiert werden, bis die JVM neu gestartet wird.

Einzelheiten zum Festlegen der JVM-TTL finden Sie unter [So legen Sie die JVM-TTL fest](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-jvm-ttl.html#how-to-set-the-jvm-ttl).

**Lettuce-Version**

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

**Endpunkte**

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

**SocketOption**

Aktivieren Sie [KeepAlive](https://lettuce.io/core/release/api/io/lettuce/core/SocketOptions.KeepAliveOptions.html). Durch die Aktivierung dieser Option wird die Notwendigkeit verringert, während der Befehlslaufzeit ausgefallene Verbindungen zu behandeln.

Stellen Sie sicher, dass Sie das [Verbindungs-Timeout](https://lettuce.io/core/release/api/io/lettuce/core/SocketOptions.Builder.html#connectTimeout-java.time.Duration-) entsprechend Ihren Anwendungsanforderungen und Ihrer Workload festlegen. Weitere Informationen finden Sie im Abschnitt „Timeouts“ weiter unten in diesem Thema.

**ClusterClientOption: Client-Optionen mit aktiviertem Clustermodus**

Aktiviert [AutoReconnect](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterClientOptions.Builder.html#autoReconnect-boolean-), wenn die Verbindung unterbrochen wird.

Set [CommandTimeout](https://lettuce.io/core/release/api/io/lettuPrce/core/RedisURI.html#getTimeout--). Weitere Einzelheiten finden Sie im Abschnitt „Timeouts“ weiter unten in diesem Thema.

Legen Sie [nodeFilter](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterClientOptions.Builder.html#nodeFilter-java.util.function.Predicate-) fest, um ausgefallene Knoten aus der Topologie herauszufiltern. Lettuce speichert alle Knoten, die sich in der Ausgabe „Cluster-Knoten“ befinden (einschließlich der Knoten mit PFAIL/FAIL-Status), in den „Partitionen“ des Clients (auch als Shards bekannt). Während der Erstellung der Cluster-Topologie wird versucht, eine Verbindung mit allen Knoten der Partition herzustellen. Dieses Verhalten von Lettuce, bei dem ausgefallene Knoten hinzugefügt werden, kann Verbindungsfehlern (oder Warnungen) verursachen, wenn Knoten aus einem beliebigen Grund ersetzt werden. 

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

Zum Beispiel:

```
final ClusterClientOptions clusterClientOptions = 
    ClusterClientOptions.builder()
    ... // other options
    .nodeFilter(it -> 
        ! (it.is(RedisClusterNode.NodeFlag.FAIL) 
        || it.is(RedisClusterNode.NodeFlag.EVENTUAL_FAIL) 
        || it.is(RedisClusterNode.NodeFlag.HANDSHAKE)
        || it.is(RedisClusterNode.NodeFlag.NOADDR)))
    .validateClusterNodeMembership(false)
    .build();
redisClusterClient.setOptions(clusterClientOptions);
```

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

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

**Anmerkung**  
Cluster mit deaktivierten Cluster-Modus unterstützen die Befehle zur Cluster-Ermittlung nicht und sind nicht mit allen Funktionen zur dynamischen Topologieermittlung des Clients kompatibel.  
Der Clustermodus ist deaktiviert mit ElastiCache ist nicht mit dem von Lettuce kompatibel. `MasterSlaveTopologyRefresh` Stattdessen können Sie für einen deaktivierten Cluster-Modus einen `StaticMasterReplicaTopologyProvider` konfigurieren und die Lese- und Schreibendpunkte des Clusters bereitstellen.  
Weitere Informationen zum Herstellen einer Verbindung mit Clustern mit deaktiviertem Cluster-Modus finden Sie unter [Finden Sie die Endpunkte eines Valkey- oder Redis OSS-Clusters (Cluster-Modus deaktiviert) (Konsole)](Endpoints.md#Endpoints.Find.Redis).  
Wenn Sie die Funktion zur dynamischen Topologieermittlung von Lettuce verwenden möchten, können Sie einen Cluster mit aktiviertem Cluster-Modus mit derselben Shard-Konfiguration wie Ihr vorhandener Cluster erstellen. Für Cluster mit aktiviertem Cluster-Modus empfehlen wir jedoch, mindestens 3 Shards mit mindestens einem Replikat zu konfigurieren, um schnelles Failover zu unterstützen.

Aktivieren Sie [enablePeriodicRefresh](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.Builder.html#enablePeriodicRefresh-java.time.Duration-). Dies ermöglicht eine regelmäßige Aktualisierung der Cluster-Topologie, sodass der Client die Cluster-Topologie in den Intervallen des refreshPeriod-Elements aktualisiert (Standard: 60 Sekunden). Wenn das Element deaktiviert ist, aktualisiert der Client die Cluster-Topologie nur, falls es bei dem Versuch, Befehle für den Cluster auszuführen, zu Fehlern kommt. 

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

Aktivieren Sie [enableAllAdaptiveRefreshTriggers](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.Builder.html#enableAllAdaptiveRefreshTriggers--). Dies ermöglicht eine adaptive Aktualisierung der Topologie, die alle [Trigger](https://lettuce.io/core/6.1.6.RELEASE/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.RefreshTrigger.html) verwendet: MOVED\$1REDIRECT, ASK\$1REDIRECT, PERSISTENT\$1RECONNECTS, UNCOVERED\$1SLOT, UNKNOWN\$1NODE. Adaptive Aktualisierungsauslöser initiieren Aktualisierungen der Topologieansicht auf der Grundlage von Ereignissen, die während Valkey- oder Redis OSS-Clustervorgängen auftreten. Das Aktivieren dieser Option führt zu einer sofortigen Aktualisierung der Topologie, wenn einer der zuvor genannten Trigger auftritt. Die Rate der adaptiv ausgelöste Aktualisierungen ist durch einen Timeout begrenzt, da Ereignisse in großem Umfang auftreten können (Standard-Timeout zwischen Updates: 30).

Aktivieren Sie [closeStaleConnections](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.Builder.html#closeStaleConnections-boolean-). Dadurch können alte Verbindungen beim Aktualisieren der Cluster-Topologie geschlossen werden. [Sie tritt nur in Kraft, wenn. ClusterTopologyRefreshOptions isPeriodicRefreshEnabled ()](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.html#isPeriodicRefreshEnabled--) ist wahr. Wenn es aktiviert ist, kann der Client alte Verbindungen schließen und im Hintergrund neue erstellen. Dadurch wird die Notwendigkeit verringert, während der Befehlslaufzeit ausgefallene Verbindungen zu behandeln.

Aktivieren Sie [dynamicRefreshResources](https://lettuce.io/core/release/api/io/lettuce/core/cluster/ClusterTopologyRefreshOptions.Builder.html#dynamicRefreshSources-boolean-). Wir empfehlen, die dynamicRefreshResources Option für kleine Cluster zu aktivieren und für große Cluster zu deaktivieren. dynamicRefreshResourcesermöglicht die Erkennung von Clusterknoten anhand des bereitgestellten Seed-Knotens (z. B. vom Cluster-Konfigurationsendpunkt). Es verwendet alle erkannten Knoten als Quellen für die Aktualisierung der Cluster-Topologie. 

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

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

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

**ClientResources**

Konfigurieren Sie [DnsResolver](https://lettuce.io/core/release/api/io/lettuce/core/resource/DefaultClientResources.Builder.html#dnsResolver-io.lettuce.core.resource.DnsResolver-) mit [DirContextDnsResolver](https://lettuce.io/core/release/api/io/lettuce/core/resource/DirContextDnsResolver.html). Der DNS-Resolver basiert auf Javas com.sun.jndi.dns. DnsContextFactory.

Konfigurieren Sie [reconnectDelay](https://lettuce.io/core/release/api/io/lettuce/core/resource/DefaultClientResources.Builder.html#reconnectDelay-io.lettuce.core.resource.Delay-) mit exponentiellem Backoff und vollständigem Jitter. Lettuce verfügt über integrierte Wiederholungsmechanismen, die auf den exponentiellen Backoff-Strategien basieren. Einzelheiten finden Sie unter [Exponential Backoff and Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter) im Architecture-Blog. AWS [Weitere Informationen zur Bedeutung einer Backoff-Strategie mit wiederholten Versuchen finden Sie in den Abschnitten zur Backoff-Logik im Blogbeitrag Best Practices im Datenbank-Blog.](https://aws.amazon.com/blogs/database/best-practices-redis-clients-and-amazon-elasticache-for-redis/) AWS 

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

**Timeouts**

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

Verwenden Sie ein dynamisches Befehls-Timeout für verschiedene Befehle. Wir empfehlen, das Befehls-Timeout auf der Grundlage der erwarteten Dauer des Befehls festzulegen. Verwenden Sie beispielsweise ein längeres Timeout für Befehle, die über mehrere Schlüssel hinweg iterieren, z. B. FLUSHDB-, FLUSHALL-, KEYS-, SMEMBERS- oder Lua-Skripts. Verwenden Sie kürzere Timeouts für einzelne Schlüsselbefehle wie SET, GET und HSET.

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

```
private static final Duration META_COMMAND_TIMEOUT = Duration.ofMillis(1000);
private static final Duration DEFAULT_COMMAND_TIMEOUT = Duration.ofMillis(250);
// Socket connect timeout should be lower than command timeout for Lettuce
private static final Duration CONNECT_TIMEOUT = Duration.ofMillis(100);
    
SocketOptions socketOptions = SocketOptions.builder()
    .connectTimeout(CONNECT_TIMEOUT)
    .build();
 

class DynamicClusterTimeout extends TimeoutSource {
     private static final Set<ProtocolKeyword> META_COMMAND_TYPES = ImmutableSet.<ProtocolKeyword>builder()
          .add(CommandType.FLUSHDB)
          .add(CommandType.FLUSHALL)
          .add(CommandType.CLUSTER)
          .add(CommandType.INFO)
          .add(CommandType.KEYS)
          .build();

    private final Duration defaultCommandTimeout;
    private final Duration metaCommandTimeout;

    DynamicClusterTimeout(Duration defaultTimeout, Duration metaTimeout)
    {
        defaultCommandTimeout = defaultTimeout;
        metaCommandTimeout = metaTimeout;
    }

    @Override
    public long getTimeout(RedisCommand<?, ?, ?> command) {
        if (META_COMMAND_TYPES.contains(command.getType())) {
            return metaCommandTimeout.toMillis();
        }
        return defaultCommandTimeout.toMillis();
    }
}

// Use a dynamic timeout for commands, to avoid timeouts during
// cluster management and slow operations.
TimeoutOptions timeoutOptions = TimeoutOptions.builder()
.timeoutSource(
    new DynamicClusterTimeout(DEFAULT_COMMAND_TIMEOUT, META_COMMAND_TIMEOUT))
.build();
```

# Beispiel: Lettuve-Konfiguration für den Clustermodus, TLS aktiviert
<a name="BestPractices.Clients-lettuce-cme"></a>

**Anmerkung**  
Timeouts im folgenden Beispiel beziehen sich auf Tests, bei denen SET/GET Befehle mit Schlüsseln und Werten ausgeführt wurden, die bis zu 20 Byte lang waren. Die Verarbeitungszeit kann bei komplexen Befehlen oder größeren Schlüsseln und Werten länger sein. Sie sollten die Timeouts je nach Anwendungsfall Ihrer Anwendung festlegen. 

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

# Beispiel: Die Lettuce-Konfiguration für den Cluster-Modus ist deaktiviert, TLS aktiviert
<a name="BestPractices.Clients-lettuce-cmd"></a>

**Anmerkung**  
Timeouts im folgenden Beispiel beziehen sich auf Tests, bei denen SET/GET Befehle mit Schlüsseln und Werten ausgeführt wurden, die bis zu 20 Byte lang waren. Die Verarbeitungszeit kann bei komplexen Befehlen oder größeren Schlüsseln und Werten länger sein. Sie sollten die Timeouts je nach Anwendungsfall Ihrer Anwendung festlegen. 

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

## Konfiguration eines bevorzugten Protokolls für Dual-Stack-Cluster (Valkey und Redis OSS)
<a name="network-type-configuring-dual-stack-redis"></a>

Bei Valkey- oder Redis OSS-Clustern, die im Clustermodus aktiviert sind, können Sie mit dem IP Discovery-Parameter steuern, welches Protokoll Clients verwenden, um eine Verbindung zu den Knoten im Cluster herzustellen. Der IP Discovery-Parameter kann entweder auf oder IPv4 gesetzt werden. IPv6 

Für Valkey- oder Redis-OSS-Cluster legt der IP-Discovery-Parameter das IP-Protokoll fest, das in der Ausgabe von [Cluster-Slots ()](https://valkey.io/commands/cluster-slots/), [Cluster-Shards ()](https://valkey.io/commands/cluster-shards/) und [Clusterknoten (](https://valkey.io/commands/cluster-nodes/)) verwendet wird. Diese Befehle werden von Clients verwendet, um die Cluster-Topologie zu ermitteln. Clients verwenden die IPs in diesen Befehlen enthaltenen Befehle, um eine Verbindung zu den anderen Knoten im Cluster herzustellen. 

Eine Änderung vom IP-Discovery führt zu keinen Ausfallzeiten für verbundene Clients. Die VerarbeitWeiterleitung ung der Änderungen wird jedoch einige Zeit dauern. Um festzustellen, wann sich die Änderungen für einen Valkey- oder Redis-OSS-Cluster vollständig verbreitet haben, überwachen Sie die Ausgabe von. `cluster slots` Sobald alle vom Befehl Cluster-Slots zurückgegebenen Knoten das neue Protokoll gemeldet IPs haben, ist die Übertragung der Änderungen abgeschlossen. 

Beispiel mit 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)
```

Beispiel mit 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;
}));
```

# Bewährte Methoden für Kunden (Memcached)
<a name="BestPractices.Clients.memcached"></a>

Erfahren Sie mehr über bewährte Methoden für gängige Szenarien mit ElastiCache Memcached-Clustern.

**Topics**
+ [Konfiguration Ihres ElastiCache Clients für einen effizienten Lastenausgleich (Memcached)](BestPractices.LoadBalancing.md)
+ [Validierte Kunden mit Memcached](network-type-validated-clients-memcached.md)
+ [Konfiguration eines bevorzugten Protokolls für Dual-Stack-Cluster (Memcached)](network-type-configuring-dual-stack-memcached.md)

# Konfiguration Ihres ElastiCache Clients für einen effizienten Lastenausgleich (Memcached)
<a name="BestPractices.LoadBalancing"></a>

**Anmerkung**  
Dieser Abschnitt bezieht sich auf knotenbasierte Memcached-Cluster mit mehreren Knoten.

Um mehrere ElastiCache Memcached-Knoten effektiv nutzen zu können, müssen Sie in der Lage sein, Ihre Cache-Schlüssel auf die Knoten zu verteilen. Eine einfache Methode zum Lastenausgleich eines Clusters mit *n* Knoten besteht darin, den Hash des Objektschlüssels zu berechnen und das Ergebnis mit *n*: zu modifizieren. `hash(key) mod n` Der resultierende Wert (0 bis *n*–1) ist die Nummer des Knotens, auf dem Sie das Objekt platzieren. 

Diese Methode ist einfach und funktioniert gut, solange die Anzahl der Knoten (*n*) konstant bleibt. Wenn Sie einen Knoten zum Cluster hinzufügen oder daraus entfernen, beträgt die Anzahl der zu verschiebenden Schlüssel jedoch jedes Mal *(n - 1) / n* (dabei entspricht *n* der neuen Anzahl von Knoten). Diese Methode führt daher dazu, dass eine große Anzahl von Schlüsseln verschoben werden. Dies ist mit einer großen Anzahl anfänglicher Cache-Fehlelemente verbunden, insbesondere bei einer umfangreichen Anzahl von Knoten. Die Skalierung von 1 auf 2 Knoten führt bestenfalls dazu, dass (2-1) / 2 (50 %) der Schlüssel verschoben werden. Eine Skalierung von 9 auf 10 Knoten hat bestenfalls zur Folge, dass (10–1) / 10 (90 %) der Schlüssel verschoben werden. Ist die Aufwärtsskalierung durch einen sprunghaften Anstieg im Datenverkehr bedingt, ist eine große Anzahl von Cache-Fehlelementen nicht wünschenswert. Eine große Anzahl von Cache-Fehlelementen führt zu Anfragen bei der Datenbank, die aufgrund des sprunghaften Anstiegs im Datenverkehr bereits überlastet ist.

Die Lösung zu diesem Dilemma ist konsistentes Hashing. Beim konsistenten Hashing wird ein Algorithmus verwendet, bei dem jedes Mal, wenn ein Knoten zu einem Cluster hinzugefügt oder daraus entfernt wird, die Anzahl der zu verschiebenden Schlüssel ungefähr *1 / n* beträgt (wobei *n* die neue Anzahl von Knoten ist). Eine Skalierung von 1 auf 2 Knoten hat schlimmstenfalls zur Folge, dass 1/2 (50 Prozent) der Schlüssel verschoben werden. Eine Skalierung von 9 auf 10 Knoten hat zur Folge, dass 1/10 (10 Prozent) der Schlüssel verschoben werden.

Sie als Benutzer steuern, welcher Hashalgorithmus für Mehrknoten-Cluster verwendet wird. Wir empfehlen, dass Sie Ihre Clients zur Verwendung von konsistentem Hashing konfigurieren. Glücklicherweise sind viele Memcached-Clientbibliotheken in den meisten gängigen Sprachen verfügbar, die konsistentes Hashing implementieren. Überprüfen Sie die Dokumentation der von Ihnen verwendeten Bibliothek darauf, ob sie konsistentes Hashing unterstützt und wie es implementiert wird.

Wenn Sie in Java, PHP oder .NET arbeiten, empfehlen wir Ihnen, eine der ElastiCache Amazon-Clientbibliotheken zu verwenden.

## Konsistentes Hashing mithilfe von Java
<a name="BestPractices.LoadBalancing.Java"></a>

Der ElastiCache Memcached Java-Client basiert auf dem Open-Source-Spymemcached-Java-Client, der über integrierte konsistente Hashing-Funktionen verfügt. Die Bibliothek umfasst eine Klasse, die konsistentes Hashing implementiert. KetamaConnectionFactory Konsistentes Hashing ist in spymemcached standardmäßig deaktiviert.

Weitere Informationen finden Sie in der KetamaConnectionFactory Dokumentation unter [KetamaConnectionFactory](https://github.com/RTBHOUSE/spymemcached/blob/master/src/main/java/net/spy/memcached/KetamaConnectionFactory.java).

## Konsistentes Hashing mithilfe von PHP mit Memcached
<a name="BestPractices.LoadBalancing.PHP"></a>

Der ElastiCache Memcached PHP-Client ist ein Wrapper rund um die integrierte Memcached-PHP-Bibliothek. Konsistentes Hashing wird von der Memcached-PHP-Bibliothek standardmäßig deaktiviert.

Verwenden Sie den folgenden Code, um konsistentes Hashing zu aktivieren.

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

Zusätzlich zum obigen Code wird empfohlen, ebenfalls `memcached.sess_consistent_hash` in der Datei php.ini einzuschalten.

 [Weitere Informationen finden Sie in der Dokumentation zur Laufzeitkonfiguration für Memcached PHP unter http://php. net/manual/en/memcached.configuration.php.](http://php.net/manual/en/memcached.configuration.php) Beachten Sie insbesondere den Parameter `memcached.sess_consistent_hash`.

## Konsistentes Hashing mit.NET mit Memcached
<a name="BestPractices.LoadBalancing.dotNET"></a>

Der ElastiCache Memcached.NET-Client ist ein Wrapper für Enyim Memcached. Konsistentes Hashing wird vom Enyim-Memcached-Client standardmäßig aktiviert.

 [Weitere Informationen finden Sie in der Dokumentation unter -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)

# Validierte Kunden mit Memcached
<a name="network-type-validated-clients-memcached"></a>

Die folgenden Clients wurden speziell daraufhin geprüft, ob sie mit allen unterstützten Netzwerktypkonfigurationen für Memcached funktionieren.

Validierte Clients:
+ [AWS ElastiCache Cluster-Client Memcached für](https://github.com/awslabs/aws-elasticache-cluster-client-memcached-for-php) [Php — Version \$13.6.2](https://github.com/awslabs/aws-elasticache-cluster-client-memcached-for-php/tree/v3.2.0)
+ [AWS ElastiCache Cluster Client Memcached für](https://github.com/awslabs/aws-elasticache-cluster-client-memcached-for-java) Java — Neuester Master auf Github

# Konfiguration eines bevorzugten Protokolls für Dual-Stack-Cluster (Memcached)
<a name="network-type-configuring-dual-stack-memcached"></a>

Bei Memcached-Clustern können Sie mit dem IP-Discovery-Parameter das Protokoll steuern, das Clients für die Verbindung mit den Knoten im Cluster verwenden. Der IP Discovery-Parameter kann entweder auf oder IPv4 gesetzt werden. IPv6 

Der IP-Erkennungsparameter steuert das IP-Protokoll, das in der Cluster-Ausgabe der Konfiguration verwendet wird. Dies wiederum bestimmt das IP-Protokoll, das von Clients verwendet wird, die automatische Erkennung ElastiCache für Memcached-Cluster unterstützen.

Eine Änderung vom IP-Discovery führt zu keinen Ausfallzeiten für verbundene Clients. Die Weiterleitung der Änderungen wird jedoch einige Zeit dauern. 

Überwachen Sie die Ausgabe von `getAvailableNodeEndPoints` für Java und für Php überwachen Sie die Ausgabe von `getServerList`. Sobald die Ausgabe dieser Funktionen Berichte IPs für alle Knoten im Cluster enthält, die das aktualisierte Protokoll verwenden, ist die Übertragung der Änderungen abgeschlossen.

Java-Beispiel:

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

Php-Beispiel:

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

Alle vorhandenen Client-Verbindungen, die vor der Aktualisierung von IP Discovery erstellt wurden, werden weiterhin mit dem alten Protokoll verbunden. Alle validierten Clients stellen mithilfe des neuen IP-Protokolls automatisch wieder eine Verbindung mit dem Cluster her, sobald die Änderungen in der Ausgabe der Cluster-Erkennungsbefehle erkannt wurden. Dies hängt jedoch von der Implementierung des Clients ab.

## TLS-fähige ElastiCache Dual-Stack-Cluster
<a name="network-type-configuring-tls-enabled-dual-stack"></a>

Wenn TLS für ElastiCache Cluster aktiviert ist, geben die Cluster-Erkennungsfunktionen (`cluster slots``cluster shards`, und `cluster nodes` für Redis) oder `config get cluster`für Memcached statt Hostnamen zurück. IPs Die Hostnamen werden dann verwendet, anstatt eine Verbindung IPs zum ElastiCache Cluster herzustellen und einen TLS-Handshake durchzuführen. Das bedeutet, dass Clients nicht vom IP-Discovery-Parameter betroffen sind. Bei TLS-fähigen Clustern hat der IP Discovery-Parameter keine Auswirkung auf das bevorzugte IP-Protokoll. Stattdessen wird das verwendete IP-Protokoll dadurch bestimmt, welches IP-Protokoll der Client bei der Auflösung von DNS-Hostnamen bevorzugt.

**Java-Clients**

Wenn Sie eine Verbindung von einer Java-Umgebung aus herstellen, die IPv4 sowohl als auch unterstützt IPv6, wird Java aus IPv6 Gründen der Abwärtskompatibilität standardmäßig IPv4 den Vorzug geben. Die IP-Protokollpräferenz ist jedoch über die JVM-Argumente konfigurierbar. Zu bevorzugen IPv4, akzeptiert die JVM `-Djava.net.preferIPv4Stack=true` und bevorzugt IPv6 gesetzt. `-Djava.net.preferIPv6Stack=true` Die Einstellung `-Djava.net.preferIPv4Stack=true` bedeutet, dass die JVM keine Verbindungen mehr herstellt. IPv6 **Für Valkey oder Redis OSS umfasst dies auch die Verbindungen zu anderen Nicht-Valkey- und Nicht-Redis-OSS-Anwendungen.**

**Einstellungen auf Host-Ebene**

Wenn vom Client oder von der Client-Laufzeit keine Konfigurationsoptionen zum Festlegen einer IP-Protokollpräferenz bereitgestellt wird, hängt das IP-Protokoll bei der DNS-Auflösung im Allgemeinen von der Konfiguration des Hosts ab. Standardmäßig bevorzugen die meisten Hosts den Vorzug, IPv4 aber diese Einstellung kann IPv6 auf Host-Ebene konfiguriert werden. Dies wirkt sich auf alle DNS-Anfragen von diesem Host aus, nicht nur auf Anfragen an ElastiCache Cluster.

**Linux-Hosts**

Für Linux kann eine IP-Protokollpräferenz konfiguriert werden, indem die `gai.conf`-Datei geändert wird. Sie finden die `gai.conf`-Datei unter `/etc/gai.conf`. Wenn keine `gai.conf` angegeben ist, sollte ein Beispiel davon `/usr/share/doc/glibc-common-x.xx/gai.conf` verfügbar sein, das nach `/etc/gai.conf` kopiert werden kann. Die Standardkonfiguration sollte dann unkommentiert sein. Um die Konfiguration zu aktualisieren, die IPv4 bei der Verbindung zu einem ElastiCache Cluster bevorzugt wird, aktualisieren Sie die Priorität für den CIDR-Bereich, der den Cluster umfasst, so dass IPs sie über der Priorität für Standardverbindungen liegt. IPv6 Standardmäßig haben IPv6 Verbindungen eine Priorität von 40. Angenommen, der Cluster befindet sich in einem Subnetz mit dem CIDR 172.31.0. 0:0 /16, würde die folgende Konfiguration dazu führen, dass Clients Verbindungen zu diesem Cluster bevorzugen. 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
```

[Weitere Informationen dazu finden Sie auf der Linux-Manpage `gai.conf`](https://man7.org/linux/man-pages/man5/gai.conf.5.html) 

**Windows-Hosts**

Der Prozess für Windows-Hosts ist ähnlich. Für Windows-Hosts können Sie `netsh interface ipv6 set prefix CIDR_CONTAINING_CLUSTER_IPS PRECEDENCE LABEL` ausführen. Dies hat den gleichen Effekt wie das Ändern der `gai.conf`-Datei für Linux-Hosts.

Dadurch werden die Präferenzrichtlinien aktualisiert, sodass Verbindungen IPv4 IPv6 Verbindungen für den angegebenen CIDR-Bereich vorgezogen werden. Wenn beispielsweise angenommen wird, dass sich der Cluster in einem Subnetz befindet, in dem 172.31.0. 0:0 /16 CIDR ausgeführt wird, würde zu der folgenden Rangfolgetabelle führen, was dazu führen `netsh interface ipv6 set prefix ::ffff:172.31.0.0:0/112 100 15` würde, dass Clients eine Verbindung mit dem Cluster bevorzugen. 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
```

# Verwaltung von reserviertem Speicher für Valkey und Redis OSS
<a name="redis-memory-management"></a>

Reservierter Speicher ist Speicher, der nicht für Daten verwendet werden soll. Bei der Durchführung eines Backups oder Failovers verwenden Valkey und Redis OSS den verfügbaren Speicher, um Schreibvorgänge in Ihrem Cluster aufzuzeichnen, während die Daten des Clusters in die RDB-Datei geschrieben werden. Wenn nicht genügend Speicher für alle Schreibvorgängen zur Verfügung steht, tritt ein Fehler auf. Im Folgenden finden Sie Informationen zu Optionen für die Verwaltung von reserviertem Speicher ElastiCache für Redis OSS und zur Anwendung dieser Optionen.

**Topics**
+ [Wie viel reservierten Speicher benötigen Sie?](#redis-memory-management-need)
+ [Parameter zum Veralten von reserviertem Speicher](#redis-memory-management-parameters)
+ [Angabe Ihres Parameters für die Verwaltung reservierten Arbeitsspeichers](#redis-reserved-memory-management-change)

## Wie viel reservierten Speicher benötigen Sie?
<a name="redis-memory-management-need"></a>

Wenn Sie eine Version von Redis OSS vor 2.8.22 ausführen, reservieren Sie mehr Speicher für Backups und Failover, als wenn Sie Redis OSS 2.8.22 oder höher ausführen. Diese Anforderung ist auf die unterschiedlichen Arten zurückzuführen, mit denen der Backup-Prozess ElastiCache für Redis OSS implementiert wird. Als Faustregel gilt, die Hälfte des `maxmemory` Werts eines Knotentyps für Redis OSS-Overhead für Versionen vor 2.8.22 und ein Viertel für Redis OSS-Versionen 2.8.22 und höher zu reservieren. 

Aufgrund der unterschiedlichen ElastiCache Implementierungsmethoden des Sicherungs- und Replikationsprozesses lautet die Faustregel, 25% des Werts eines Knotentyps mithilfe des Parameters zu reservieren. `maxmemory` `reserved-memory-percent` Dies ist der Standardwert und wird in den meisten Fällen empfohlen.

Wenn die Typen Burstable Micro und Small Instances in der Nähe der `maxmemory` Grenzwerte arbeiten, kann es zu Swap-Nutzung kommen. Um die Betriebssicherheit dieser Instance-Typen bei Backups, Replikationen und hohem Datenaufkommen zu verbessern, empfehlen wir, den Wert des `reserved-memory-percent` Parameters bei kleinen Instance-Typen um bis zu 30% und bei Micro-Instance-Typen um bis zu 50% zu erhöhen.

Für schreibintensive Workloads auf ElastiCache Clustern mit Daten-Tiering empfehlen wir, den verfügbaren Speicher des Knotens auf `reserved-memory-percent` bis zu 50% zu erhöhen.

Weitere Informationen finden Sie hier:
+ [Stellen Sie sicher, dass Sie über genügend Arbeitsspeicher verfügen, um einen Valkey- oder Redis OSS-Snapshot zu erstellen](BestPractices.BGSAVE.md)
+ [So werden Synchronisation und Backup implementiert](Replication.Redis.Versions.md)
+ [Datenzuweisung ElastiCache](data-tiering.md)

## Parameter zum Veralten von reserviertem Speicher
<a name="redis-memory-management-parameters"></a>

Seit dem 16. März 2017 ElastiCache bietet Amazon zwei sich gegenseitig ausschließende Parameter für die Verwaltung Ihres Valkey- oder Redis-OSS-Speichers und`reserved-memory`. `reserved-memory-percent` Keiner dieser Parameter ist Teil der Valkey- oder Redis-OSS-Distribution. 

Je nachdem, wann Sie ElastiCache Kunde wurden, ist der eine oder andere dieser Parameter der Standardparameter für die Speicherverwaltung. Dieser Parameter gilt, wenn Sie einen neuen Valkey- oder Redis OSS-Cluster oder eine neue Replikationsgruppe erstellen und eine Standardparametergruppe verwenden. 
+ Für Kunden, die vor dem 16. März 2017 damit angefangen haben: Wenn Sie einen Redis OSS-Cluster oder eine Redis-OSS-Cluster oder eine Redis-Replikationsgruppe mithilfe der Standardparametergruppe erstellen, lautet Ihr Speicherverwaltungsparameter. `reserved-memory` In diesem Fall werden null (0) Byte Speicher reserviert. 
+ Für Kunden, die am oder nach dem 16. März 2017 angefangen haben: Wenn Sie einen Valkey- oder Redis OSS-Cluster oder eine Replikationsgruppe mithilfe der Standardparametergruppe erstellen, lautet Ihr Speicherverwaltungsparameter. `reserved-memory-percent` In diesem Fall sind 25 Prozent des `maxmemory`-Wertes Ihres Knotens für Nichtdatenzwecke reserviert.

Nachdem Sie sich mit den beiden Speicherverwaltungsparametern Valkey oder Redis OSS vertraut gemacht haben, ziehen Sie es vielleicht vor, den zu verwenden, der nicht Ihr Standard ist oder nicht die Standardwerte enthält. Wenn dies der Fall ist, können Sie zu dem anderen Verwaltungsparameter für reservierten Speicher wechseln. 

Um den Wert dieses Parameters zu ändern, können Sie eine benutzerdefinierte Parametergruppe erstellen und sie ändern, um Ihren bevorzugten Speicherverwaltungsparameter und -wert zu verwenden. Sie können die benutzerdefinierte Parametergruppe dann immer dann verwenden, wenn Sie einen neuen Valkey- oder Redis OSS-Cluster oder eine neue Replikationsgruppe erstellen. Existierende Cluster und Replikationsgruppen können Sie so ändern, dass sie die benutzerdefinierte Parametergruppe verwenden.

 Weitere Informationen finden Sie hier: 
+ [Angabe Ihres Parameters für die Verwaltung reservierten Arbeitsspeichers](#redis-reserved-memory-management-change)
+ [Eine ElastiCache Parametergruppe erstellen](ParameterGroups.Creating.md)
+ [Änderung einer ElastiCache Parametergruppe](ParameterGroups.Modifying.md)
+ [Einen ElastiCache Cluster ändern](Clusters.Modify.md)
+ [Ändern einer Replikationsgruppe](Replication.Modify.md)

### Der Parameter "reserved-memory"
<a name="redis-memory-management-parameters-reserved-memory"></a>

Vor dem 16. März 2017 wurde die gesamte Verwaltung des reservierten Speichers ElastiCache für Redis OSS mithilfe des Parameters durchgeführt. `reserved-memory` Der Standardwert von `reserved-memory` ist 0. Diese Standardeinstellung reserviert keinen Speicher für Valkey- oder Redis OSS-Overhead und ermöglicht es Valkey oder Redis OSS, den gesamten Speicher eines Knotens mit Daten zu verbrauchen. 

Wenn Sie `reserved-memory` ändern, damit ausreichend Speicher für Sicherungen und Failovers zur Verfügung steht, müssen Sie eine benutzerdefinierte Parametergruppe erstellen. In dieser benutzerdefinierten Parametergruppe legen `reserved-memory` Sie einen Wert fest, der für die Valkey- oder Redis OSS-Version, die auf Ihrem Cluster ausgeführt wird, und für den Knotentyp des Clusters geeignet ist. Weitere Informationen finden Sie unter [Wie viel reservierten Speicher benötigen Sie?](#redis-memory-management-need).

Der Parameter `reserved-memory` ist spezifisch für die allgemeine Redis OSS-Distribution ElastiCache und nicht Teil dieser.

Das folgende Verfahren zeigt, wie Sie `reserved-memory` den Speicher auf Ihrem Valkey- oder Redis OSS-Cluster verwalten.

**So reservieren Sie Speicher mithilfe von reserviertem Speicher**

1. Erstellen Sie eine benutzerdefinierte Parametergruppe, indem Sie die Parametergruppenfamilie angeben, die der von Ihnen ausgeführten Engine-Version entspricht, z. B. indem Sie die `redis2.8`-Parametergruppenfamilie angeben. Weitere Informationen finden Sie unter [Eine ElastiCache Parametergruppe erstellen](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. Berechnen Sie, wie viele Byte Speicher für den OSS-Overhead von Valkey oder Redis reserviert werden müssen. Sie finden den Wert von `maxmemory` für Ihren Knotentyp unter [Redis OSS-Knotentyp-spezifische Parameter](ParameterGroups.Engine.md#ParameterGroups.Redis.NodeSpecific).

1. Ändern Sie die benutzerdefinierte Parametergruppe, sodass der Parameter `reserved-memory` der Anzahl von Bytes entspricht, die Sie im vorherigen Schritt berechnet haben. Im folgenden AWS CLI Beispiel wird davon ausgegangen, dass Sie eine Version von Redis OSS vor 2.8.22 ausführen und die Hälfte der Knoten reservieren müssen. `maxmemory` Weitere Informationen finden Sie unter [Änderung einer ElastiCache Parametergruppe](ParameterGroups.Modifying.md).

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

   Sie benötigen für jeden verwendeten Knotentyp eine eigene benutzerdefinierte Parametergruppe, da jeder Knotentyp einen anderen `maxmemory`-Wert hat. Daher benötigt jeder Knotentyp einen anderen Wert für `reserved-memory`.

1. Ändern Sie Ihren Redis OSS-Cluster oder Ihre Redis-Replikationsgruppe so, dass sie Ihre benutzerdefinierte Parametergruppe verwendet.

   Mit dem folgenden CLI-Beispiel wird der Cluster ` my-redis-cluster` geändert, damit er ab sofort die benutzerdefinierte Parametergruppe `redis28-m3xl` verwendet. Weitere Informationen finden Sie unter [Einen ElastiCache Cluster ändern](Clusters.Modify.md).

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

   Mit dem folgenden CLI-Beispiel wird die Replikationsgruppe `my-redis-repl-grp` geändert, damit sie ab sofort die benutzerdefinierte Parametergruppe `redis28-m3xl` verwendet. Weitere Informationen finden Sie unter [Ändern einer Replikationsgruppe](Replication.Modify.md).

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

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

Am 16. März 2017 ElastiCache führte Amazon den Parameter ein `reserved-memory-percent` und stellte ihn in allen Versionen von ElastiCache for Redis OSS zur Verfügung. Der Zweck von `reserved-memory-percent` besteht darin, die Verwaltung des reservierten Speichers für alle Ihre Cluster zu vereinfachen. Dies wird dadurch erreicht, dass Sie eine einzige Parametergruppe für jede Parametergruppenfamilie (wie `redis2.8`) zur Verfügung haben, um den reservierten Speicher Ihrer Cluster unabhängig vom Knotentyp zu verwalten. Der Standardwert für `reserved-memory-percent` ist 25 (25 Prozent).

Der Parameter `reserved-memory-percent` ist spezifisch für die allgemeine Redis OSS-Distribution ElastiCache und nicht Teil davon.

Wenn Ihr Cluster einen Knotentyp aus der R6gd-Familie verwendet und Ihre Speicherauslastung 75 Prozent erreicht, wird Daten-Tiering automatisch ausgelöst. Weitere Informationen finden Sie unter [Datenzuweisung ElastiCache](data-tiering.md).

**Um Speicher zu reservieren mit reserved-memory-percent**  
Gehen Sie wie folgt vor`reserved-memory-percent`, um den Speicher auf Ihrem ElastiCache for Redis OSS-Cluster zu verwalten:
+ Wenn Sie Redis OSS 2.8.22 oder höher ausführen, weisen Sie Ihrem Cluster die Standardparametergruppe zu. Der Standardwert 25 Prozent sollte ausreichen. Falls nicht, führen Sie die folgenden Schritte aus, um den Wert zu ändern.
+ Wenn Sie eine Version von Redis OSS vor 2.8.22 ausführen, müssen Sie wahrscheinlich mehr Speicher als die standardmäßigen 25 Prozent reservieren. `reserved-memory-percent` Führen Sie dazu die folgenden Schritte aus. 

**Um den Prozentwert von zu ändern reserved-memory-percent**

1. Erstellen Sie eine benutzerdefinierte Parametergruppe, indem Sie die Parametergruppenfamilie angeben, die der von Ihnen ausgeführten Engine-Version entspricht, z. B. indem Sie die `redis2.8`-Parametergruppenfamilie angeben. Eine benutzerdefinierte Parametergruppe ist erforderlich, da Sie eine Standardparametergruppe nicht ändern können. Weitere Informationen finden Sie unter [Eine ElastiCache Parametergruppe erstellen](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
   ```

   Da `reserved-memory-percent` Speicher als Prozentanteil von `maxmemory` eines Knotens reserviert, benötigen Sie keine benutzerdefinierte Parametergruppe für jeden Knotentyp.

1. Ändern Sie die benutzerdefinierte Parametergruppe, sodass `reserved-memory-percent` 50 (50 Prozent) beträgt. Weitere Informationen finden Sie unter [Änderung einer ElastiCache Parametergruppe](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. Verwenden Sie diese benutzerdefinierte Parametergruppe für alle Redis OSS-Cluster oder Replikationsgruppen, auf denen eine Version von Redis OSS ausgeführt wird, die älter als 2.8.22 ist.

   Das folgende CLI-Beispiel ändert den Redis OSS-Cluster so`my-redis-cluster`, dass er `redis28-50` ab sofort die benutzerdefinierte Parametergruppe verwendet. Weitere Informationen finden Sie unter [Einen ElastiCache Cluster ändern](Clusters.Modify.md).

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

   Das folgende CLI-Beispiel ändert die Redis OSS-Replikationsgruppe so`my-redis-repl-grp`, dass sie `redis28-50` ab sofort die benutzerdefinierte Parametergruppe verwendet. Weitere Informationen finden Sie unter [Ändern einer Replikationsgruppe](Replication.Modify.md).

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

## Angabe Ihres Parameters für die Verwaltung reservierten Arbeitsspeichers
<a name="redis-reserved-memory-management-change"></a>

Wenn Sie am 16. März 2017 ein aktueller ElastiCache Kunde waren, lautet Ihr Standardparameter für die Verwaltung von reserviertem Speicher `reserved-memory` mit null (0) Byte reserviertem Speicher. Wenn Sie nach dem 16. März 2017 ElastiCache Kunde wurden, ist `reserved-memory-percent` Ihr Standardparameter für die Verwaltung von reserviertem Speicher so, dass 25 Prozent des Speichers des Knotens reserviert sind. Dies gilt unabhängig davon, wann Sie Ihren OSS-Cluster oder Ihre Replikationsgruppe ElastiCache für Redis erstellt haben. Sie können Ihren Parameter für die Verwaltung des reservierten Speichers jedoch entweder mithilfe der ElastiCache API AWS CLI oder ändern.

Die Parameter `reserved-memory` und `reserved-memory-percent` schließen sich gegenseitig aus. Eine Parametergruppe verfügt immer über einen dieser Parameter, niemals jedoch über beide. Sie können den Parameter ändern, den eine Parametergruppe für die Verwaltung von reserviertem Speicher verwendet, indem Sie die Parametergruppe ändern. Die Parametergruppe muss eine benutzerdefinierte Parametergruppe sein, da Sie die Standardparametergruppen nicht ändern können. Weitere Informationen finden Sie unter [Eine ElastiCache Parametergruppe erstellen](ParameterGroups.Creating.md).

**Um zu spezifizieren reserved-memory-percent**  
Um `reserved-memory-percent` als Verwaltungsparameter für reservierten Speicher zu verwenden, ändern Sie eine benutzerdefinierte Parametergruppe mit dem `modify-cache-parameter-group`-Befehl. Verwenden Sie den `parameter-name-values`-Parameter zum Angeben von `reserved-memory-percent` sowie einen Wert dafür.

Mit dem folgenden CLI-Beispiel wird die benutzerdefinierte Parametergruppe `redis32-cluster-on` geändert, sodass sie `reserved-memory-percent` zum Verwalten von reserviertem Speicher verwendet. Für die Parametergruppe muss `ParameterValue` ein Wert zugewiesen werden, um den `ParameterName`-Parameter für die Verwaltung des reservierten Speichers zu verwenden. Weitere Informationen finden Sie unter [Änderung einer ElastiCache Parametergruppe](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"
```

**So geben Sie reserved-memory an**  
Um `reserved-memory` als Verwaltungsparameter für reservierten Speicher zu verwenden, ändern Sie eine benutzerdefinierte Parametergruppe mit dem `modify-cache-parameter-group`-Befehl. Verwenden Sie den `parameter-name-values`-Parameter zum Angeben von `reserved-memory` sowie einen Wert dafür.

Mit dem folgenden CLI-Beispiel wird die benutzerdefinierte Parametergruppe `redis32-m3xl` geändert, sodass sie `reserved-memory` zum Verwalten von reserviertem Speicher verwendet. Für die Parametergruppe muss `ParameterValue` ein Wert zugewiesen werden, um den `ParameterName`-Parameter für die Verwaltung des reservierten Speichers zu verwenden. Da die Engine-Version höher als 2.8.22 ist, wird der Wert auf `3565158400` gesetzt. Dieser Wert entspricht 25 % des Werts von `maxmemory` für `cache.m3.xlarge`. Weitere Informationen finden Sie unter [Änderung einer ElastiCache Parametergruppe](ParameterGroups.Modifying.md).

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

# Bewährte Methoden bei der Arbeit mit nodenbasierten Valkey- und Redis OSS-Clustern
<a name="BestPractices.SelfDesigned"></a>

Multi-AZ-Nutzung, ausreichender Arbeitsspeicher, Clustergrößenänderung und Minimierung von Ausfallzeiten sind alles nützliche Konzepte, die Sie bei der Arbeit mit knotenbasierten Clustern in Valkey oder Redis OSS berücksichtigen sollten. Wir empfehlen Ihnen, sich mit diesen bewährten Methode vertraut zu machen und sie zu befolgen.

**Topics**
+ [Minimierung von Ausfallzeiten mit Multi-AZ](multi-az.md)
+ [Stellen Sie sicher, dass Sie über genügend Arbeitsspeicher verfügen, um einen Valkey- oder Redis OSS-Snapshot zu erstellen](BestPractices.BGSAVE.md)
+ [Online-Größenanpassung von Clustern](best-practices-online-resharding.md)
+ [Minimieren der Ausfallzeit während der Wartung](BestPractices.MinimizeDowntime.md)

# Minimierung von Ausfallzeiten mit Multi-AZ
<a name="multi-az"></a>

Es gibt eine Reihe von Fällen, in denen ElastiCache Valkey oder Redis OSS möglicherweise einen Primärknoten ersetzen müssen. Dazu gehören bestimmte Arten von geplanten Wartungsarbeiten und der unwahrscheinliche Fall eines Ausfalls eines Primärknotens oder einer Availability Zone.

Dieser Austausch führt zu einer gewissen Ausfallzeit für den Cluster, aber wenn Multi-AZ aktiviert ist, wird die Ausfallzeit minimiert. Die Rolle des primären Knotens wird automatisch auf eines der Read Replicas übertragen. Es ist nicht erforderlich, einen neuen Primärknoten zu erstellen und bereitzustellen, da dies transparent ElastiCache gehandhabt wird. Dieser Failover und die Replikatheraufstufung stellen sicher, dass Sie weiter in den neuen primären Knoten schreiben können, sobald die Heraufstufung abgeschlossen wurde.

Weitere Informationen [Minimierung von Ausfallzeiten durch die Verwendung ElastiCache von Multi-AZ mit Valkey und Redis OSS](AutoFailover.md) über Multi-AZ und die Minimierung von Ausfallzeiten finden Sie unter.

# Stellen Sie sicher, dass Sie über genügend Arbeitsspeicher verfügen, um einen Valkey- oder Redis OSS-Snapshot zu erstellen
<a name="BestPractices.BGSAVE"></a>

**Snapshots und Synchronisationen in Valkey 7.2 und höher sowie Redis OSS Version 2.8.22 und höher**  
Valkey unterstützt standardmäßig Snapshots und Synchronisationen. Redis OSS 2.8.22 führt einen forkless-Speicherprozess ein, der es Ihnen ermöglicht, einen größeren Teil Ihres Speichers für die Nutzung durch Ihre Anwendung zuzuweisen, ohne dass es bei Synchronisationen und Speichervorgängen zu einer erhöhten Swap-Nutzung kommt. Weitere Informationen finden Sie unter [So werden Synchronisation und Backup implementiert](Replication.Redis.Versions.md).

**Redis OSS-Snapshots und Synchronisationen vor Version 2.8.22**

Wenn Sie mit ElastiCache for Redis OSS arbeiten, ruft Redis OSS in einer Reihe von Fällen einen Schreibbefehl im Hintergrund auf:
+ Beim Erstellen eines Snapshots für eine Sicherung
+ Beim Synchronisieren von Replikaten mit dem primären Cluster in einer Replikationsgruppe
+ Wenn Sie die Funktion „Nur Dateien anhängen“ (AOF) für Redis OSS aktivieren.
+ Beim Hochstufen eines Replikats zu einem primären (was eine primäre/Replikat-Synchronisierung verursacht).

Immer wenn Redis OSS einen Schreibvorgang im Hintergrund ausführt, müssen Sie über ausreichend verfügbaren Speicher verfügen, um den Prozessaufwand zu bewältigen. Wenn nicht genügend Arbeitsspeicher verfügbar ist, schlägt der Vorgang fehl. Aus diesem Grund ist es wichtig, bei der Erstellung Ihres Redis OSS-Clusters einen Knoteninstanztyp auszuwählen, der über ausreichend Speicher verfügt.

## Schreibvorgang im Hintergrund und Speichernutzung mit Valkey und Redis OSS
<a name="BestPractices.BGSAVE.Process"></a>

Immer wenn ein Schreibvorgang im Hintergrund aufgerufen wird, forken Valkey und Redis OSS seinen Prozess ab (denken Sie daran, dass diese Engines Single-Threading verwenden). Ein Fork speichert Ihre Daten auf der Festplatte in einer Redis OSS .rdb-Snapshot-Datei. Die andere Vergabelung führt alle Lese- und Schreibvorgänge durch. Um sicherzustellen, dass es sich bei Ihrem point-in-time Snapshot um einen Snapshot handelt, werden alle Datenaktualisierungen und Ergänzungen in einen vom Datenbereich getrennten Bereich des verfügbaren Speichers geschrieben.

Solange genügend Arbeitsspeicher zum Aufzeichnen aller Schreibvorgänge verfügbar ist, während die Daten dauerhaft auf dem Datenträger erhalten bleiben, treten keine Probleme aufgrund von Speichermangel auf. Wenn vermehrt Probleme aufgrund von Speichermangel auftreten, treffen beliebige der folgenden Situationen ein:
+ Ihre Anwendung führt viele Schreibvorgänge aus und benötigt daher eine große Menge an verfügbarem Arbeitsspeicher zum Akzeptieren neuer oder aktualisierter Daten.
+ Es ist sehr wenig Arbeitsspeicher zum Schreiben neuer oder aktualisierter Daten verfügbar.
+ Die dauerhafte Erhaltung eines großen Datensatzes auf der Festplatte dauert eine lange Zeit und erfordert eine große Anzahl von Schreibvorgängen.

Das folgende Diagramm veranschaulicht die Speichernutzung beim Ausführen eines Hintergrundschreibvorgangs.

![\[Abbildung: Diagramm der Speichernutzung während eines Hintergrundschreibvorgangs.\]](http://docs.aws.amazon.com/de_de/AmazonElastiCache/latest/dg/images/ElastiCache-bgsaveMemoryUseage.png)


Informationen zu den Auswirkungen einer Sicherung auf die Leistung finden Sie unter [Auswirkungen von Backups knotenbasierter Cluster auf die Leistung](backups.md#backups-performance).

[Weitere Informationen darüber, wie Valkey und Redis OSS Snapshots durchführen, finden Sie unter http://valkey.io.](http://valkey.io)

Weitere Informationen zu Regionen und Availability Zones finden Sie unter [Auswahl von Regionen und Verfügbarkeitszonen für ElastiCache](RegionsAndAZs.md). 

## Vermeidung von Speichermangel beim Ausführen eines Hintergrundschreibvorgangs
<a name="BestPractices.BGSAVE.memoryFix"></a>

Immer wenn ein Schreibvorgang im Hintergrund wie `BGSAVE` oder aufgerufen `BGREWRITEAOF` wird, muss mehr Speicher verfügbar sein, als durch Schreibvorgänge während des Vorgangs verbraucht wird, um zu verhindern, dass der Prozess fehlschlägt. Im schlimmsten Fall wird während des Schreibvorgangs im Hintergrund jeder Datensatz aktualisiert und einige neue Datensätze werden dem Cache hinzugefügt. Aus diesem Grund empfehlen wir, den Wert `reserved-memory-percent` auf 50 (50 Prozent) für Redis OSS-Versionen vor 2.8.22 oder 25 (25 Prozent) für Valkey und alle Redis OSS-Versionen 2.8.22 und höher festzulegen. 

Der Wert `maxmemory` gibt den für die Daten und den Betriebsaufwand verfügbaren Arbeitsspeicher an. Da der Parameter `reserved-memory` in der Standardparametergruppe nicht geändert werden kann, müssen Sie eine benutzerdefinierte Parametergruppe für den Cluster erstellen. Der Standardwert für `reserved-memory` ist 0, was es Redis OSS ermöglicht, den gesamten *maximalen Speicher mit Daten zu verbrauchen, sodass möglicherweise zu wenig Speicher* für andere Zwecke übrig bleibt, z. B. für einen Schreibvorgang im Hintergrund. Informationen zu `maxmemory`-Werten nach Knoten-Instance-Typ finden Sie unter [Redis OSS-Knotentyp-spezifische Parameter](ParameterGroups.Engine.md#ParameterGroups.Redis.NodeSpecific).

Sie können `reserved-memory` Parameter auch verwenden, um den Speicherverbrauch auf der Box zu reduzieren.

Weitere Informationen zu Valkey- und Redis-spezifischen Parametern finden Sie unter. ElastiCache [Valkey- und Redis OSS-Parameter](ParameterGroups.Engine.md#ParameterGroups.Redis)

Weitere Informationen zum Erstellen und Ändern von Parametergruppen finden Sie unter [Eine ElastiCache Parametergruppe erstellen](ParameterGroups.Creating.md) und [Änderung einer ElastiCache Parametergruppe](ParameterGroups.Modifying.md).

# Online-Größenanpassung von Clustern
<a name="best-practices-online-resharding"></a>

*Resharding* umfasst das Hinzufügen und Entfernen von Shards oder Knoten für den Cluster sowie die Neuverteilung von Schlüsselräumen. Daher haben viele Aspekte Einfluss auf die Resharding-Operation, z. B. Workload des Clusters, Speichernutzung und allgemeine Datengröße. Für optimale Ergebnisse empfehlen wir, dass Sie die allgemeinen bewährten Methoden zu Clustern für eine gleichmäßige Verteilung von Workload-Verteilung befolgen. Außerdem empfehlen wir, die folgenden Schritte durchzuführen.

Vor dem Beginn des Resharding sollten Sie Folgendes durchführen:
+ **Testen Sie Ihre Anwendung** – Testen Sie das Verhalten Ihrer Anwendung während des Reshardings nach Möglichkeit in einer Staging-Umgebung.
+ **Erhalten Sie frühzeitige Benachrichtigungen bei Skalierungsproblemen** – Resharding ist ein rechenintensiver Vorgang. Aus diesem Grund empfehlen wir, beim Resharding die CPU-Auslastung bei Multicore-Instances unter 80 Prozent und bei Single-Core-Instances unter 50 Prozent zu halten. Überwachen Sie ElastiCache die OSS-Metriken von Redis und initiieren Sie das Resharding, bevor Ihre Anwendung Skalierungsprobleme beobachtet. Die Überwachung folgender Metriken ist nützlich: `CPUUtilization`, `NetworkBytesIn`, `NetworkBytesOut`, `CurrConnections`, `NewConnections`, `FreeableMemory`, `SwapUsage` und `BytesUsedForCacheItems`.
+ **Stellen Sie vor dem Hochskalieren sicher, dass ausreichend freier Speicher verfügbar ist** – Stellen Sie beim Hochskalieren sicher, dass der freie Speicher auf den beizubehaltenden Shards mindestens das 1,5-fache des Arbeitsspeichers beträgt, der auf den Shards verwendet wird, die Sie entfernen möchten.
+ **Initiieren Sie Resharding außerhalb der Spitzenzeiten** – Diese Vorgehensweise hilft, die Auswirkungen auf die Latenz und den Durchsatz auf den Client während des Resharding-Vorgangs zu reduzieren. Außerdem wird das Resharding schneller abgeschlossen, da bei der Slot-Verteilung mehr Ressourcen verwendet werden können.
+ **Überprüfen Sie das Client-Timeout-Verhalten** – Einige Clients stellen möglicherweise eine höhere Latenz während der Online-Cluster-Größenänderung fest. Es kann helfen, bei Ihrer Client-Bibliothek einen höheren Timeout zu konfigurieren, da dem System so Zeit zur Verbindungsherstellung unter höheren Lastbedingungen auf dem Server gegeben wird. Manchmal wird eine große Anzahl an Verbindungen zum Server geöffnet. Fügen Sie in diesen Fällen exponentielles Backoff hinzu, um Logik erneut zu verbinden. Hierdurch wird verhindert, dass ein Schub neuer Verbindungen den Server gleichzeitig erreicht.
+ **Laden Sie Ihre Funktionen auf jeden Shard** — Beim Skalieren Ihres Clusters ElastiCache werden die Funktionen, die in einem der vorhandenen Knoten geladen wurden (zufällig ausgewählt), automatisch auf die neuen Knoten repliziert. Wenn Ihr Cluster über Valkey 7.2 und höher oder Redis OSS 7.0 oder höher verfügt und Ihre Anwendung [Functions](https://valkey.io/topics/functions-intro/) verwendet, empfehlen wir, alle Ihre Funktionen vor dem Skalieren auf alle Shards zu laden, damit Ihr Cluster nicht mit unterschiedlichen Funktionen auf verschiedenen Shards endet.

Beachten Sie nach dem Resharding Folgendes:
+ Die Skalierung nach oben ist möglicherweise nur zum Teil erfolgreich, wenn auf den Ziel-Shards nicht ausreichend Arbeitsspeicher verfügbar ist. In diesem Fall prüfen Sie den verfügbaren Speicher und wiederholen Sie ggf. die Operation. Die Daten auf den Ziel-Shards werden nicht gelöscht.
+ Die Befehle `FLUSHALL` und `FLUSHDB` werden in Lua-Skripten während eines Resharding-Vorgangs nicht unterstützt. Vor Redis OSS 6 wurde der `BRPOPLPUSH` Befehl nicht unterstützt, wenn er auf dem zu migrierenden Steckplatz ausgeführt wird.

# Minimieren der Ausfallzeit während der Wartung
<a name="BestPractices.MinimizeDowntime"></a>

Die Konfiguration des Cluster-Modus ist am besten im Rahmen verwalteter oder nicht verwalteter Operationen verfügbar. Es wird empfohlen, einen im Cluster-Modus unterstützten Client zu verwenden, der eine Verbindung mit dem Clusterermittlungsendpunkt herstellt. Bei deaktiviertem Cluster-Modus empfehlen wir, den primären Endpunkt für alle Schreiboperationen zu verwenden. 

Für Lesevorgänge können Anwendungen Verbindungen zu jedem Knoten im Cluster herstellen. Im Gegensatz zum primären Endpunkt werden Knotenendpunkte auf bestimmte Endpunkte aufgelöst. Wenn Sie eine Änderung am Cluster vornehmen, wie z. B. Hinzufügen oder Löschen eines Replikats, müssen Sie die Knotenendpunkte in Ihrer Anwendung aktualisieren. Bei deaktiviertem Cluster-Modus empfehlen wir daher, den Reader-Endpunkt für Leseaktivitäten zu verwenden.

Wenn im Cluster aktiviert AutoFailover ist, kann sich der primäre Knoten ändern. Daher sollte die Anwendung die Rolle des Knotens bestätigen und alle Leseendpunkte aktualisieren. Dadurch wird sichergestellt, dass Sie keine große Belastung des primären Knotens verursachen. Bei AutoFailover deaktivierter Option ändert sich die Rolle des Knotens nicht. Die Ausfallzeiten bei verwalteten oder nicht verwalteten Vorgängen sind jedoch höher als bei Clustern mit AutoFailover aktivierter Option.

 Vermeiden Sie es, Leseanforderungen an einen einzelnen Read-Replica-Knoten weiterzuleiten, da dessen Nichtverfügbarkeit zu einem Leseausfall führen könnte. Entweder Sie greifen auf das Lesen vom Primärknoten zurück oder stellen sicher, dass Sie über mindestens zwei Read Replicas verfügen, um Leseunterbrechungen während der Wartung zu vermeiden. 

# Caching-Strategien für Memcached
<a name="Strategies"></a>

Im folgenden Thema finden Sie Strategien zum Auffüllen und Verwalten Ihres Memcached-Caches.

Welche Strategien Sie zum Auffüllen und Verwalten Ihres Cache implementieren müssen, hängt von den zwischengespeicherten Daten und den Zugriffsmustern auf diese Daten ab. Zum Beispiel möchten Sie wahrscheinlich nicht dieselbe Strategie für eine Top-10-Bestenliste auf einer Spieleseite und für trendige Nachrichten verwenden. Im Rest dieses Abschnitts besprechen wir gängige Cache-Wartungsstrategien und ihre Vor- und Nachteile.

**Topics**
+ [Read Replicas](#Strategies.ReadReplicas)
+ [Lazy Loading](#Strategies.LazyLoading)
+ [Write-Through](#Strategies.WriteThrough)
+ [Hinzufügen von TTL](#Strategies.WithTTL)
+ [Verwandte Themen](#Strategies.SeeAlso)

## Read Replicas
<a name="Strategies.ReadReplicas"></a>

Sie können die Leistung ElastiCache serverloser Caches häufig erheblich verbessern, indem Sie Replikate erstellen und aus ihnen lesen, anstatt sie vom primären Cache-Knoten aus zu lesen. Weitere Informationen finden Sie unter [Bewährte Methoden für die Verwendung von Read Replicas](ReadReplicas.md).

## Lazy Loading
<a name="Strategies.LazyLoading"></a>

Wie der Name schon sagt, ist *Lazy Loading* (“langsames Laden“) eine Caching-Strategie, die Daten nur bei Bedarf in den Cache lädt. Es funktioniert folgendermaßen. 

Amazon ElastiCache ist ein speicherinterner Schlüsselwertspeicher, der sich zwischen Ihrer Anwendung und dem Datenspeicher (Datenbank) befindet, auf den sie zugreift. Immer wenn Ihre Anwendung Daten anfordert, sendet sie die Anfrage zuerst an den Cache. ElastiCache Wenn die Daten im Cache vorhanden und aktuell sind, gibt ElastiCache die Daten an Ihre Anwendung zurück. Wenn die Daten nicht im Cache vorhanden sind oder abgelaufen sind, fordert Ihre Anwendung die Daten von Ihrem Datenspeicher an. Ihr Datenspeicher gibt die Daten dann an Ihre Anwendung zurück. Als nächstes schreibt Ihre Anwendung die vom Speicher empfangenen Daten in den Cache. Auf diese Weise können sie bei der nächsten Anforderung schneller abgerufen werden.

Ein *Cache-Treffer* tritt auf, wenn sich Daten im Cache befinden und nicht abgelaufen sind:

1. Die Anwendung fordert Daten aus dem Cache an.

1. Der Cache gibt die Daten an die Anwendung zurück.

Ein *Cache-Fehltreffer* tritt auf, wenn sich Daten nicht im Cache befinden oder abgelaufen sind:

1. Die Anwendung fordert Daten vom Cache an.

1. Der Cache enthält die angeforderten Daten nicht und gibt daher `null` zurück.

1. Ihre Anwendung fordert die Daten an und erhält sie aus der Datenbank.

1. Ihre Anwendung aktualisiert den Cache mit den neuen Daten.

### Vor- und Nachteile von Lazy Loading
<a name="Strategies.LazyLoading.Evaluation"></a>

Die Vorteile von Lazy Loading sind:
+ Es werden nur die angeforderten Daten im Cache abgelegt.

  Da die meisten Daten nie angefordert werden, wird durch Lazy Loading vermieden, dass der Cache mit nicht angeforderten Daten gefüllt wird.
+ Knotenfehler sind für Ihre Anwendung nicht fatal.

  Wenn ein Knoten ausfällt und durch einen neuen, leeren Knoten ersetzt wird, funktioniert Ihre Anwendung weiterhin, allerdings mit erhöhter Latenz. Wenn Anforderungen an den neuen Knoten gestellt werden, führt jeder Cache-Fehltreffer zu einer Abfrage der Datenbank. Gleichzeitig wird die Datenkopie dem Cache hinzugefügt, so dass nachfolgende Anforderungen aus dem Cache abgerufen werden.

Die Nachteile von Lazy Loading sind:
+ Bei Cache-Fehlschlägen gibt es Verzögerungen. Jeder Cache-Fehltreffer führt zu drei Übertragungsvorgängen: 

  1. Anfängliche Anforderung von Daten aus dem Cache

  1. Abfrage der Daten aus der Datenbank

  1. Schreiben der Daten in den Cache

   Diese Fehltreffer können zu einer merklichen Verzögerung beim Eingang der Daten in die Anwendung führen.
+ Veraltete Daten.

  Wenn Daten nur bei einem Cache-Fehltreffer in den Cache geschrieben werden, können Daten im Cache veraltet sein. Dieses Ergebnis tritt auf, weil der Cache nicht aktualisiert wird, wenn Daten in der Datenbank geändert werden. Um dieses Problem zu beheben, können Sie die [Write-Through](#Strategies.WriteThrough) und [Hinzufügen von TTL](#Strategies.WithTTL)-Strategien anwenden.

### Beispiel für Lazy Loading Pseudocode
<a name="Strategies.LazyLoading.CodeExample"></a>

Im Folgenden finden Sie ein Pseudocode-Beispiel für Lazy Loading-Logik.

```
// *****************************************
// 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
```

In diesem Beispiel sieht der Anwendungscode, der die Daten abruft, wie folgt aus.

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

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

Die Write-Through-Strategie fügt dem Cache Daten hinzu oder aktualisiert Daten im Cache, wenn Daten in die Datenbank geschrieben werden.

### Vor- und Nachteile von Write-Through
<a name="Strategies.WriteThrough.Evaluation"></a>

Die Vorteile von Write-Through sind:
+ Die Daten im Cache sind nie veraltet.

  Da die Daten im Cache jedes Mal aktualisiert werden, wenn sie in die Datenbank geschrieben werden, sind die Daten im Cache immer aktuell.
+ Schreibstrafe im Vergleich zu Lesestrafe.

  Jeder Schreibvorgang umfasst zwei Übertragungsvorgänge: 

  1. Ein Schreibvorgang in den Cache

  1. Ein Schreibvorgang in die Datenbank

   Dadurch wird die Latenz des Prozesses erhöht. Endbenutzer tolerieren im Allgemeinen Latenz beim Aktualisieren von Daten eher als beim Abrufen. Aktualisierungen werden als arbeits- und zeitintensiver wahrgenommen.

Die Nachteile von Write-Through sind:
+ Fehlende Daten.

  Wenn Sie einen neuen Knoten hochfahren, sei es aufgrund eines Knotenfehlers oder einer horizontalen Skalierung, fehlen Daten. Diese Daten fehlen weiterhin, bis sie in der Datenbank hinzugefügt oder aktualisiert werden. Sie können dies minimieren, indem Sie [Lazy Loading](#Strategies.LazyLoading) mit Write-Through implementieren.
+ Cache-Änderung.

  Die meisten Daten werden nie gelesen, was eine Verschwendung von Ressourcen darstellt. Durch [Hinzufügen eines Time-to-Live-Werts (TTL)](#Strategies.WithTTL) können Sie verschwendeten Speicherplatz minimieren.

### Beispiel für Write-Through-Pseudocode
<a name="Strategies.WriteThrough.CodeExample"></a>

Das Folgende ist ein Pseudocode-Beispiel für Write-Through-Logik.

```
// *****************************************
// 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
```

In diesem Beispiel sieht der Anwendungscode, der die Daten abruft, wie folgt aus.

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

## Hinzufügen von TTL
<a name="Strategies.WithTTL"></a>

Lazy Loading ermöglicht veraltete Daten, schlägt jedoch nicht wegen leeren Knoten fehl. Write-Through stellt sicher, dass die Daten immer frisch sind, kann aber bei leeren Knoten fehlschlagen und den Cache mit überflüssigen Daten füllen. Indem Sie jedem Schreibvorgang einen Time-to-Live-Wert (TTL) hinzufügen, können Sie die Vorteile jeder Strategie nutzen. Gleichzeitig können Sie das Überladen des Caches mit zusätzlichen Daten weitgehend vermeiden.

*Time to Live (TTL)* ist ein ganzzahliger Wert, der die Anzahl der Sekunden angibt, bis der Schlüssel abläuft. Valkey oder Redis OSS können Sekunden oder Millisekunden für diesen Wert angeben. Memcached gibt diesen Wert in Sekunden an. Wenn eine Anwendung versucht, einen abgelaufenen Schlüssel zu lesen, gilt der Schlüssel als nicht gefunden. Die Datenbank wird nach dem Schlüssel abgefragt und der Cache aktualisiert. Dieser Ansatz garantiert nicht, dass ein Wert nicht veraltet ist. Er verhindert jedoch, dass die Daten zu veraltet werden, und erfordert, dass Werte im Cache gelegentlich aus der Datenbank aktualisiert werden.

[Weitere Informationen finden Sie unter den OSS-Befehlen [Valkey und Redis](https://valkey.io/commands) oder den Memcached-Befehlen. `set`](https://www.tutorialspoint.com/memcached/memcached_set_data.htm)

### Beispiele für TTL Pseudocode
<a name="Strategies.WithTTL.CodeExample"></a>

Das Folgende ist ein Pseudocode-Beispiel für Write-Through-Logik mit 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
```

Das Folgende ist ein Pseudocode-Beispiel für Lazy-Loading-Logik mit 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
```

In diesem Beispiel sieht der Anwendungscode, der die Daten abruft, wie folgt aus.

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

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

## Verwandte Themen
<a name="Strategies.SeeAlso"></a>
+ [In-Memory-Datastore](elasticache-use-cases.md#elasticache-use-cases-data-store)
+ [Auswählen einer Engine und einer Version](SelectEngine.md)
+ [Skalierung ElastiCache](Scaling.md)