Auf dieser Seite finden Sie eine Anleitung zur optimalen Verwendung von Memorystore for Redis. Diese Seite weist auch auf mögliche Probleme hin.
Eine Liste mit Szenarien zur Fehlerbehebung finden Sie unter Fehlerbehebung.
Best Practices für Hochverfügbarkeit und Datenbeständigkeit
Wir empfehlen, die Standard-Stufe als primären Mechanismus für Hochverfügbarkeit (HA) zu verwenden. Die Standard-Stufe bietet eine hochverfügbare Instanz mit mehreren Replikaten und ermöglicht eine schnelle Wiederherstellung durch automatisches Failover, wenn die primäre Instanz ausfällt. Darüber hinaus bietet die Aktivierung von RDB-Snapshots auf Instanzen der Standard-Stufe zusätzlichen Schutz vor Knotenausfällen.
In einigen Szenarien möchten Sie möglicherweise auch sicherstellen, dass Sie Daten aus Snapshot-Sicherungen wiederherstellen können. In diesen Szenarien können Sicherungen und die Möglichkeit, Daten aus RDB-Snapshots wiederherzustellen, zusätzlichen Schutz vor Datenverlust bieten.
Wenn Sie RDB-Snapshots aktivieren und Ihre Daten wiederherstellen müssen, kann Memorystore for Redis dies aus dem neuesten Snapshot tun. Diese Snapshots sind nur für die interne Systemwiederherstellung bestimmt und Sie können nicht darauf zugreifen.
Einschränkungen der Haltbarkeit und Best Practices
Obwohl die Standard-Stufe Hochverfügbarkeit durch Replikation und automatisches Failover bietet, garantiert Hochverfügbarkeit keine vollständige Datendauerhaftigkeit. Memorystore for Redis kann auch bei aktivierter Hochverfügbarkeit keine vollständige Datendauerhaftigkeit bei bestimmten katastrophalen Ereignissen wie vorübergehenden regionalen Ausfällen bieten.
Zum Schutz Ihrer Daten und für ein grundlegendes Maß an Persistenz sind RDB-Snapshots standardmäßig aktiviert, wenn Sie eine Memorystore for Redis-Instanz über die Google Cloud Console erstellen.
Für Produktionsarbeitslasten sollten Sie die folgenden Best Practices beachten, um die Datenstabilität weiter zu verbessern:
- Notfallwiederherstellung: Memorystore for Redis unterstützt keine regionenübergreifende Replikation. Wenn Ihre Notfallwiederherstellungsstrategie eine regionenübergreifende Replikation für echte regionale Ausfallsicherheit erfordert, empfehlen wir die Verwendung einer Memorystore for Valkey-Instanz. Weitere Informationen zum Konfigurieren und Verwalten von sekundären Instanzen in verschiedenen Regionen finden Sie in der Dokumentation zu Memorystore for Valkey unter Mit regionenübergreifender Replikation arbeiten.
- Maximale Beständigkeit: Wenn Ihre Anwendung die höchstmögliche Datenbeständigkeit erfordert, empfehlen wir die Verwendung einer Memorystore for Valkey-Instanz, die mit regionenübergreifender Replikation, automatischen täglichen Sicherungen und AOF-Persistenz (Append-Only File) konfiguriert ist. Diese Kombination bietet den zuverlässigsten Schutz vor Datenverlust. Weitere Informationen finden Sie in der Dokumentation zu Memorystore for Valkey unter Persistenz – Übersicht.
Best Practices für die Kapazitätsplanung
Damit Sie Ressourcen erfolgreich bereitstellen und robuste Architekturen erstellen können, empfehlen wir die folgenden Best Practices für die Kapazitätsplanung:
- An mehreren Standorten bereitstellen: Wenn Sie aufgrund vorübergehender Ressourceneinschränkungen keine Instanz in Ihrer bevorzugten Zone erstellen können, versuchen Sie, die Instanz entweder in einer anderen Zone innerhalb derselben Region oder in einer anderen Region zu erstellen.
- Regionsübergreifenden Zugriff verwenden: Konfigurieren Sie Ihre Clients so, dass sie auf Ihre Instanzen in verschiedenen Regionen zugreifen können. Wenn Sie aufgrund lokaler Ressourcenbeschränkungen eine Instanz in einer anderen Region bereitstellen müssen, können Ihre Clients eine Verbindung zur Instanz herstellen.
- Andere Kapazitätsstufe auswählen: Wenn aufgrund der Größe einer Instanz Ressourcenbeschränkungen auftreten, wählen Sie entweder eine andere Kapazitätsstufe aus oder ändern Sie die Größe der Instanz. Weitere Informationen finden Sie unter Leistung der Kapazitätsstufe.
RDB-Export
Beachten Sie beim Exportieren einer RDB-Sicherung die folgende Anleitung:
- Während eines niedrigen Schreibsatzes exportieren.
- Wenn Sie während einer Periode mit hoher Schreibrate exportieren, senken Sie die
maxmemory-Konfiguration vorübergehend auf 50 % der Instanzkapazität, um genügend Overhead für eine erfolgreiche Operation bereitzustellen.
Ressourcenintensive Vorgänge
Bei Redis-Instanzen der Standardstufe verwenden die folgenden Vorgänge zusätzlichen Speicher für die Dauer des Vorgangs:
Durch ein Upgrade der Version, des Autoscaling und des manuellen Failovers wird aufgrund der Replikation zusätzlicher Speicher (für Instanzen der Standardstufe) verbraucht. Diese Vorgänge folgen dem Replikationsprozess, wie unter Standardverhalten der Instanz-Upgrade beschrieben.
Import- und Exportvorgänge erfordern zusätzlichen Arbeitsspeicher, da diese Vorgänge mit einem verzweigten Redis-Prozess und Copy-on-Write-Datenmanagement verbunden sind.
Zur Verringerung der Nachteile ressourcenintensiver Vorgänge sollten Sie Folgendes tun:
- Verringern Sie die maxmemory-Konfiguration auf 80 % der Instanzkapazität für die Dauer des Vorgangs. Dies ist ein ausreichender Overhead für einen erfolgreichen Vorgang.
- Überwachen Sie den Messwert für das Verhältnis der Systemspeichernutzung und achten Sie darauf, dass dieser Messwert unter 80% liegt, bevor Sie einen dieser Vorgänge ausführen.
- Führen Sie diese Vorgänge in Zeiten mit geringem Instanz-Traffic aus (z. B. nachts oder am Wochenende).
- Richten Sie eine Wiederholungslogik mit exponentiellem Backoff ein, bevor Sie diese Vorgänge ausführen.
Vorgänge und Szenarien, für die eine Verbindungswiederholung erforderlich ist
Folgende Vorgänge und Szenarien unterbrechen die Netzwerkverbindung zwischen Ihrem Netzwerk und der Redis-Instanz:
- Versionsupgrade
- Hoch-/Herunterskalieren
- Wird importiert...
- Manueller Failover
- Systemwartung
- Rotation von Zertifizierungsstellen für Redis-Instanzen mit aktivierter Verschlüsselung während der Übertragung
- Notfall-Failover
Durch diese Vorgänge wird Ihre Instanz geändert, sodass eine vorübergehende Verbindungsunterbrechung notwendig ist. Sie müssen eine Wiederholungslogik mit exponentiellem Backoff eingerichtet haben, bevor diese Vorgänge ausgeführt werden, damit Ihre Anwendung automatisch wieder eine Verbindung herstellt und weiterhin normal funktioniert.
Routinewartung
Memorystore for Redis-Instanzen werden regelmäßig gewartet. Weitere Informationen finden Sie in der Wartungsrichtlinie für Memorystore for Redis.
Setzen Sie folgende Best Practices ein, um auf routinemäßige Wartungen vorbereitet zu sein:
- Legen Sie ein Wartungsfenster fest, in dem Wartungsupdates stattfinden können.
- Planen Sie Wartungsfenster für Zeiten mit geringem Instanz-Traffic und ausreichendem Speicher-Overhead. Weitere Informationen finden Sie unter Auswirkungen von Wartungsupdates.
- Aktivieren Sie Benachrichtigungen zu Wartungsfenstern, um über bevorstehende Wartungen informiert zu werden.
- Es ist eine Wiederholungslogik mit exponentiellem Backoff erforderlich.
- Für Instanzen der Standard-Stufe können Sie ein Wartungsereignis mithilfe eines manuellen Failovers simulieren, um zu sehen, wie sich das durch die Wartung verursachte Failover auf Ihre Anwendung auswirkt.
- Bei Instanzen der Basisstufe können Sie die Auswirkungen eines Wartungsupdates simulieren, indem Sie die Instanz vorübergehend auf eine größere Größe skalieren. Nachdem Sie die Auswirkungen beobachtet haben, können Sie die Größe wieder auf die ursprüngliche Größe reduzieren.
Speicherverwaltung
Die Speicherverwaltung kann aufgrund der bekannten Speicherfragmentierung, die bei Open-Source-Redis auftritt, eine Herausforderung sein. Wir empfehlen Ihnen, die Konfiguration von maxmemory für Ihre Instanz zu senken, um sich im Falle eines hohen Arbeitsspeichers durch Overhead zu kümmern.
Die beste Möglichkeit, die Arbeitsspeicherauslastung Ihrer Memorystore-Instanz zu überwachen, ist die Verwendung des Messwerts „Verhältnis der Arbeitsspeichernutzung des Systems“. Eine ausführliche Anleitung zur Speicherverwaltung für Memorystore for Redis finden Sie unter Best Practices für die Speicherverwaltung.
Inaktive Verbindungen verwalten
Im Laufe der Zeit kann die Anzahl der Verbindungen zu Ihrer Memorystore-Instanz zunehmen, wenn Verbindungen nicht ordnungsgemäß beendet werden. Dies kann sich negativ auf die Leistung auswirken, insbesondere wenn Sie die Verschlüsselung während der Übertragung verwenden. Hierbei gelten maximale Verbindungslimits entsprechend Ihrer Kapazitätsstufe. Um dies zu vermeiden, empfehlen wir die Verwendung des Redis-Konfigurationsparameters timeout, mit dem Sie die Anzahl der Sekunden festlegen können, bevor inaktive Clientverbindungen automatisch beendet werden.
Access Transparency-Ressourcennamen
Sensible Daten sollten nicht in Memorystore for Redis-Ressourcennamen gespeichert werden. Mit Ressourcennamen meinen wir Memorystore for Redis-Instanznamen und Instanzmetadaten wie Tags. In Ressourcennamen gespeicherte Daten sind nicht unbedingt durch Google Cloud Access Transparency geschützt und können gegen die Access Transparency-Compliance-Anforderungen Ihrer Organisation verstoßen.
Connector für serverlosen VPC-Zugriff für einige serverlose Umgebungen erforderlich
Einige serverlose Umgebungen erfordern einen Connector für serverlosen VPC-Zugriff, um eine Verbindung zu Memorystore for Redis herzustellen. Richten Sie den Connector für serverlosen VPC-Zugriff für Ihr Projekt ein, wenn Sie eine Verbindung über eine dieser Umgebungen herstellen möchten.
Netzwerk
Wir empfehlen, den Verbindungsmodus für private Dienste den Verbindungsmodus zu verwenden. Memorystore for Redis verwendet zwei Verbindungsmodi: Zugriff auf private Dienste und Direct Peering. Mit dem Verbindungsmodus für den Zugriff auf private Dienste wird die Verwaltung von IP-Bereichen vereinfacht und Sie können bei Bedarf eine freigegebene VPC verwenden.
Der Verbindungsmodus kann nach dem Erstellen einer Instanz nicht mehr geändert werden.
Weitere Informationen finden Sie unter Netzwerk.
Monitoring und Warnungen
Wir empfehlen die Verwendung von Monitoring und Benachrichtigungen, da Sie so wichtige Signale zur Arbeitsspeichernutzung Ihrer Redis-Instanz erhalten. Sie geben außerdem Aufschluss darüber, wie effizient Ihre Redis-Instanz auf eingehende Cache-Anfragen reagiert.
Sie sollten folgende Standardwarnungen einrichten:
- Cloud Monitoring-Benachrichtigung für die Arbeitsspeichernutzung festlegen
- Cloud Monitoring-Benachrichtigung für die Systemarbeitsspeichernutzung festlegen
Best Practices für die CPU-Nutzung
Die unsachgemäße Verwendung teurer Redis-Befehle führt zu hoher Latenz, mangelnder Reaktionsfähigkeit oder Verbindungsproblemen. Instanzen der Standard-Stufe bieten Hochverfügbarkeit während der Notfallwiederherstellung und basieren auf asynchroner Replikation zwischen primären und Replikatknoten. Wenn einer der Knoten einen rechenintensiven Befehl verarbeitet, der den Redis-Hauptthread blockiert, kann sich das auf die Replikation auswirken. Wenn das Problem weiterhin besteht und ein Standortausfall auftritt, sind die zuletzt am Standort des Ausfalls geschriebenen Daten möglicherweise nicht am anderen Standort verfügbar.
Wir empfehlen, Cloud Monitoring zu verwenden, um Benachrichtigungen für den Messwert CPU-Sekunden des Hauptthreads (redis.googleapis.com/stats/cpu_utilization_main_thread) festzulegen. So können Sie sicherstellen, dass die CPU-Auslastung 0,8 Sekunden für den primären Knoten oder 0,5 Sekunden für jeden Replikatknoten nicht überschreitet, wenn das Replikat als Lesereplikat festgelegt ist.
Wenn Ihre Redis-Instanz die empfohlenen Werte überschreitet, sollten Sie die Instanz auf eine höhere Kapazitätsstufe skalieren oder der Anleitung zur Fehlerbehebung folgen, um CPU-intensive Vorgänge zu vermeiden.
Wenn Ihre Instanz eine hohe CPU-Auslastung aufweist oder die Ressourcen der Instanz erschöpft sind (z. B. durch zu viele Verbindungen), kann es zu Fehlern bei der Instanz kommen und externe Messwerte fehlen.
Ressourcenintensive Befehle
Wir empfehlen dringend, keine ressourcenintensiven Redis-Befehle zu verwenden. Die Verwendung dieser Befehle kann zu folgenden Leistungsproblemen führen:
- Hohe Latenz und Client-Zeitüberschreitungen
- Arbeitsspeichermangel, der durch Befehle verursacht wird, die die Arbeitsspeichernutzung erhöhen
- Datenverlust während der Knotenreplikation und ‑synchronisierung, weil der Redis-Hauptthread blockiert ist
- Nicht ausgeführte Systemdiagnosen, Beobachtbarkeit und Replikation
In der folgenden Tabelle sind Beispiele für ressourcenintensive Redis-Befehle aufgeführt und es werden ressourceneffiziente Alternativen vorgeschlagen.
| Kategorie | Ressourcenintensiver Befehl | Ressourceneffiziente Alternative |
|---|---|---|
| Für den gesamten Schlüsselbereich ausführen | KEYS |
SCAN |
| Für einen Schlüsselsatz mit variabler Länge ausführen | LRANGE |
Begrenzen Sie die Größe des Bereichs, den Sie für eine Abfrage verwenden. |
ZRANGE |
Begrenzen Sie die Größe des Bereichs, den Sie für eine Abfrage verwenden. | |
HGETALL |
HSCAN |
|
SMEMBERS |
SSCAN |
|
| Ausführung eines Scripts blockieren | EVAL |
Achten Sie darauf, dass Ihr Script nicht unendlich lange ausgeführt wird. |
EVALSHA |
Achten Sie darauf, dass Ihr Script nicht unendlich lange ausgeführt wird. | |
| Dateien und Links entfernen | DEL |
UNLINK |
| Veröffentlichen und abonnieren | PUBLISH |
SPUBLISH |
SUBSCRIBE |
SSUBSCRIBE |
Best Practices für Redis-Clients
In diesem Abschnitt finden Sie eine Anleitung zur optimalen Verwendung Ihres Redis-Clients.
Nicht reagierende Verbindungen erkennen und verarbeiten
Wir empfehlen dringend, Ihre Clientanwendung so zu konfigurieren, dass nicht reagierende Verbindungen zu Memorystore for Redis erkannt werden. Wenn eine nicht reagierende Verbindung erkannt wird, muss der Client sie zurücksetzen. Zum Erstellen einer ausfallsicheren Anwendung empfehlen wir die folgenden Clientkonfigurationen:
- TCP-Keep-Alive-Parameter konfigurieren: Legen Sie die Parameter
TCP keepalive time,TCP keepalive intervalundTCP keepalive probesso fest, dass Clients nicht reagierende Verbindungen proaktiv erkennen und trennen, auch wenn die Verbindungen inaktiv sind. Wenn Sie beispielsweise den ParameterTCP keepalive timeauf 30 Sekunden,TCP keepalive intervalauf 10 Sekunden undTCP keepalive probesauf 3 festlegen, setzen Clients nicht reagierende inaktive Verbindungen innerhalb einer Minute zurück. - TCP-Nutzerzeitlimits konfigurieren: Legen Sie dieses Zeitlimit in Ihren Clients fest, um Verbindungen mit ausstehenden Anfragen zurückzusetzen, die nicht mehr reagieren. Wenn Sie das Zeitlimit beispielsweise auf 15 Sekunden festlegen, setzen Clients nicht reagierende Verbindungen mit ausstehenden Anfragen nach 15 Sekunden zurück.
Clientspezifische Best Practices
Wenn Sie Ihre Anwendungen horizontal skalieren, können bei Schreibbefehlen READONLY-Fehler auftreten. Memorystore for Redis verwendet eine Nicht-Sentinel-Bereitstellung mit statischen Endpunkten. Clients erhalten keine dynamischen Rolleninformationen im Voraus.
Wenn Sie eine einzelne Clientverbindung sowohl für den primären als auch für den Replikatendpunkt verwenden, sendet Ihr Client möglicherweise versehentlich Schreibbefehle an das Replikat mit Lesezugriff. Das Replikat gibt den Fehler READONLY zurück, da es keine Schreibbefehle verarbeiten kann.
Verwenden Sie nicht dieselbe Verbindung für Lese- und Schreibvorgänge, um eine fehlerhafte Weiterleitung von Schreibvorgängen zu vermeiden. Teilen Sie stattdessen Ihre Vorgänge auf, indem Sie die folgenden separaten Clientinstanzen erstellen:
- Primärer Client: Nur mit dem primären Endpunkt verbinden
- Replikatclient: Nur mit dem Replikatendpunkt verbinden
Auf den folgenden Tabs wird gezeigt, wie Sie die separaten Vorlagen in Go, Java, Node.js und Python konfigurieren.
Go
package main import ( "context" "fmt" "github.com/redis/go-redis/v9" ) func main() { ctx := context.Background() // Initialize the primary client connecting only to the primary endpoint primaryClient := redis.NewClient(&redis.Options{ Addr: "PRIMARY_HOST:6379", Password: "YOUR_PASSWORD", DB: 0, }) defer primaryClient.Close() // Initialize the replica client connecting only to the replica endpoint replicaClient := redis.NewClient(&redis.Options{ Addr: "REPLICA_HOST:6379", Password: "YOUR_PASSWORD", DB: 0, }) defer replicaClient.Close() // Use the primary client for all mutating commands err := primaryClient.Set(ctx, "example_key", "example_value", 0).Err() if err != nil { fmt.Printf("Failed to write to primary: %v\n", err) } // Use the replica client for all read-only commands val, err := replicaClient.Get(ctx, "example_key").Result() if err != nil { fmt.Printf("Failed to read from replica: %v\n", err) } else { fmt.Printf("Successfully read value: %s\n", val) } }
Java
@Bean public RedisConnectionFactory primaryConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("PRIMARY_HOST", 6379); config.setPassword(RedisPassword.of("YOUR_PASSWORD")); return new LettuceConnectionFactory(config); } @Bean public RedisConnectionFactory replicaConnectionFactory() { RedisStaticMasterReplicaConfiguration config = new RedisStaticMasterReplicaConfiguration("PRIMARY_HOST", 6379); config.addNode("REPLICA_HOST", 6379); config.setPassword(RedisPassword.of("YOUR_PASSWORD")); LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .readFrom(ReadFrom.REPLICA_PREFERRED) .build(); return new LettuceConnectionFactory(config, clientConfig); } @Bean public RedisTemplate<String, Object> primaryRedisTemplate( @Qualifier("primaryConnectionFactory") RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); return template; } @Bean public RedisTemplate<String, Object> replicaRedisTemplate( @Qualifier("replicaConnectionFactory") RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); return template; }
Node.js
import { createClient } from 'redis'; async function main() { // Initialize the primary client connecting only to the primary endpoint const primaryClient = createClient({ url: 'redis://PRIMARY_HOST:6379', password: 'YOUR_PASSWORD' }); // Initialize the replica client connecting only to the replica endpoint const replicaClient = createClient({ url: 'redis://REPLICA_HOST:6379', password: 'YOUR_PASSWORD' }); primaryClient.on('error', (err) => console.error('Primary Client Error', err)); replicaClient.on('error', (err) => console.error('Replica Client Error', err)); await primaryClient.connect(); await replicaClient.connect(); // Use the primary client for all mutating commands try { await primaryClient.set('example_key', 'example_value'); console.log('Successfully wrote to primary'); } catch (err) { console.error('Failed to write to primary:', err); } // Use the replica client for all read-only commands try { const val = await replicaClient.get('example_key'); console.log(`Successfully read value: ${val}`); } catch (err) { console.error('Failed to read from replica:', err); } await primaryClient.disconnect(); await replicaClient.disconnect(); } main();
Python
import redis def main(): # Initialize the primary client connecting only to the primary endpoint primary_client = redis.Redis( host='PRIMARY_HOST', port=6379, password='YOUR_PASSWORD', decode_responses=True ) # Initialize the replica client connecting only to the replica endpoint replica_client = redis.Redis( host='REPLICA_HOST', port=6379, password='YOUR_PASSWORD', decode_responses=True ) # Use the primary client for all mutating commands try: primary_client.set('example_key', 'example_value') print('Successfully wrote to primary') except redis.RedisError as e: print(f'Failed to write to primary: {e}') # Use the replica client for all read-only commands try: val = replica_client.get('example_key') print(f'Successfully read value: {val}') except redis.RedisError as e: print(f'Failed to read from replica: {e}') if __name__ == '__main__': main()