Cette page fournit des conseils pour utiliser Memorystore pour Redis de manière optimale. Elle souligne également les problèmes potentiels à éviter.
Pour obtenir la liste des scénarios de dépannage, consultez la page Dépannage.
Exportation RDB
Lorsque vous exportez une sauvegarde RDB, suivez les conseils ci-dessous :
- Exécutez une exportation pendant une période présentant un faible taux d'écriture.
- Si vous procédez à l'exportation pendant une période présentant un taux d'écriture élevé, abaissez temporairement la configuration de
maxmemoryà 50 % de la capacité de l'instance afin de maintenir une surcharge suffisante pour une opération réussie.
Opérations exigeantes en ressources
Pour les instances Redis de niveau standard, les opérations suivantes utilisent de la mémoire supplémentaire pendant toute la durée de l'opération :
- Mise à niveau de la version
- Scaling à la hausse/à la baisse
- Basculement manuel
- Importation/Exportation
En raison de la réplication, les opérations de mise à niveau de la version, de scaling et de basculement manuel utilisent de la mémoire supplémentaire (pour les instances de niveau standard). Ces opérations suivent le processus de réplication décrit dans la section Comportement de la mise à niveau des instances de niveau standard.
Les opérations d'importation et d'exportation nécessitent de la mémoire supplémentaire en raison du processus Redis dupliqué et de la gestion de données de copie pour écriture associées à ces opérations.
Afin de limiter les inconvénients des opérations exigeantes en ressources, vous devez effectuer les opérations suivantes :
- Abaisser la configuration de maxmemory à 80 % de la capacité de l'instance pendant la durée de l'opération. Cela permet de maintenir une surcharge suffisante pour une opération réussie.
- Surveillez la métrique "Taux d'utilisation de la mémoire système" et assurez-vous qu'elle est inférieure à 80% avant d'exécuter l'une de ces opérations.
- Exécuter ces opérations pendant les périodes où le trafic de l'instance est faible (par exemple, la nuit, le week-end, etc.).
- Mettre en place une logique de nouvelle tentative avec un intervalle exponentiel entre les tentatives avant d'exécuter ces opérations.
Opérations et scénarios nécessitant une nouvelle tentative de connexion
Les opérations et scénarios suivants interrompent la connexion réseau entre votre réseau et l'instance Redis :
- Mise à niveau de la version
- Scaling à la hausse/à la baisse
- Importation…
- Basculement manuel
- Maintenance du système
- La rotation des autorités de certification pour les instances Redis pour lesquelles le chiffrement en transit est activé
- Basculement d'urgence
Ces opérations modifient votre instance, ce qui nécessite une interruption temporaire de la connexion. Vous devez mettre en place une logique de nouvelle tentative avec un intervalle exponentiel entre les tentatives avant de pouvoir exécuter ces opérations, afin que votre application se reconnecte automatiquement et continue à fonctionner normalement.
Maintenance de routine
Les instances Memorystore pour Redis font l'objet d'une maintenance périodique. Pour en savoir plus, consultez la stratégie de maintenance de Memorystore pour Redis.
Mettez en œuvre les bonnes pratiques suivantes pour vous préparer à la maintenance de routine :
- Définissez un intervalle de maintenance indiquant quand les mises à jour de maintenance peuvent avoir lieu.
- Planifiez les intervalles de maintenance pour les périodes de faible trafic d'instance et de surcharge de mémoire suffisante. Pour en savoir plus, consultez la section Impact des mises à jour de maintenance.
- Activez les notifications d'intervalles de maintenance pour être informé des prochains événements.
- Vous devez mettre en place une logique de nouvelle tentative avec un intervalle exponentiel entre les tentatives.
- Pour les instances de niveau Standard, vous pouvez simuler un événement de maintenance à l'aide du basculement manuel pour voir comment le basculement provoqué par la maintenance affecte votre application.
- Pour les instances de niveau de base, vous pouvez simuler l'impact d'une mise à jour de maintenance en changeant temporairement d'échelle pour l'instance et en choisissant une taille plus grande. Une fois que vous avez observé l'impact, vous pouvez revenir à la taille d'origine.
Gestion de la mémoire
La gestion de la mémoire peut être difficile en raison de la fragmentation de la mémoire bien connue qui se produit avec Redis Open Source. Nous vous recommandons d'abaisser la configuration de maxmemory de votre instance pour vous donner de la surcharge en cas de saturation de la mémoire.
Le meilleur moyen de surveiller la saturation de la mémoire sur votre instance Memorystore est d'utiliser la métrique du taux d'utilisation de la mémoire système. Pour obtenir un guide détaillé sur la gestion de la mémoire pour Memorystore pour Redis, consultez Bonnes pratiques pour la gestion de la mémoire.
Gérer les connexions inactives
Au fil du temps, il est possible que le nombre de connexions à votre instance Memorystore augmente si les connexions ne sont pas correctement fermées. Cela peut avoir des conséquences négatives sur les performances, en particulier si vous utilisez le chiffrement en transit, qui impose des limites sur le nombre maximum de connexions en fonction de votre niveau de capacité. Pour éviter cela, nous vous recommandons d'utiliser le paramètre de configuration Redis timeout, qui vous permet de définir le nombre de secondes avant l'arrêt automatique des connexions clientes inactives.
Noms de ressources Access Transparency
Les données sensibles ne doivent pas être stockées dans les noms de ressources Memorystore pour Redis. Par noms de ressources, nous entendons les noms d'instances Memorystore pour Redis et les métadonnées d'instance, telles que les tags. Il n'est pas garanti que les données stockées dans les noms de ressources soient protégées par Google Cloud Access Transparency. Elles peuvent également être en conflit avec les exigences de conformité Access Transparency de votre organisation.
Connecteur d'accès au VPC sans serveur requis pour certains environnements sans serveur
Certains environnements sans serveur nécessitent un connecteur d'accès au VPC sans serveur pour se connecter à Memorystore pour Redis. Si vous souhaitez vous connecter à l'aide de l'un de ces environnements, configurez le connecteur d'accès au VPC sans serveur pour votre projet.
Mise en réseau
Nous vous recommandons d'utiliser le mode de connexion d'accès aux services privés. Memorystore pour Redis utilise deux modes de connexion : l'accès aux services privés et l'appairage direct. Le mode de connexion d'accès aux services privés simplifie la gestion des plages d'adresses IP et vous permet d'utiliser un VPC partagé si vous le souhaitez.
Une fois que vous avez créé une instance, le mode de connexion ne peut plus être modifié.
Pour en savoir plus, consultez la page Mise en réseau.
Surveillance et alertes
Nous vous recommandons d'utiliser la surveillance et les alertes, car elles vous fournissent des signaux clés sur l'utilisation de la mémoire de votre instance Redis. Elles vous donnent également un aperçu de l'efficacité de réponse de votre instance Redis aux requêtes de cache entrantes.
Vous devez configurer les alertes par défaut suivantes :
- Définir une alerte Cloud Monitoring pour l'utilisation de la mémoire
- Définir une alerte Cloud Monitoring pour le taux d'utilisation de la mémoire système
Bonnes pratiques concernant l'utilisation du processeur
L'utilisation incorrecte de commandes Redis coûteuses entraîne une latence élevée, une absence de réponse ou des problèmes de connectivité. Les instances de niveau standard offrent une haute disponibilité lors de la reprise après sinistre et s'appuient sur la réplication asynchrone entre les nœuds principal et de réplique. Si l'un des nœuds effectue un traitement de commande coûteux qui bloque le thread principal Redis, la réplication peut être affectée. Si le problème persiste et qu'une panne se produit dans un emplacement, les données les plus récentes écrites dans cet emplacement peuvent ne pas être disponibles dans l'autre emplacement.
Nous vous recommandons d'utiliser Cloud Monitoring pour définir des alertes pour la métrique Secondes de processeur du thread principal (redis.googleapis.com/stats/cpu_utilization_main_thread). Vous pourrez ainsi vous assurer que l'utilisation du processeur ne dépasse pas 0,8 seconde pour le nœud principal ni 0,5 seconde pour chaque nœud répliqué lorsque la réplique est désignée comme réplique en lecture.
Si votre instance Redis dépasse les valeurs recommandées, nous vous conseillons de la mettre à l'échelle vers un niveau de capacité supérieur ou de suivre les instructions de dépannage pour éviter les opérations gourmandes en ressources processeur.
Si votre instance connaît une utilisation élevée du processeur ou si ses ressources sont épuisées (par exemple, en raison d'un nombre trop important de connexions), elle peut se comporter de manière anormale et des métriques externes peuvent manquer.
Commandes gourmandes en ressources
Nous vous recommandons vivement d'éviter d'utiliser des commandes Redis gourmandes en ressources. L'utilisation de ces commandes peut entraîner les problèmes de performances suivants :
- Latence élevée et délais avant expiration des clients
- Pression sur la mémoire causée par des commandes qui augmentent l'utilisation de la mémoire
- Perte de données lors de la réplication et de la synchronisation des nœuds, car le thread principal Redis est bloqué
- Vérifications de l'état affamées, observabilité et réplication
Le tableau suivant liste des exemples de commandes Redis gourmandes en ressources et vous propose des alternatives plus efficaces.
| Catégorie | Commande gourmande en ressources | Alternative économe en ressources |
|---|---|---|
| Exécuter pour l'ensemble de l'espace de clés | KEYS |
SCAN |
| Exécuter pour une collection de clés de longueur variable | LRANGE |
Limitez la taille de la plage que vous utilisez pour une requête. |
ZRANGE |
Limitez la taille de la plage que vous utilisez pour une requête. | |
HGETALL |
HSCAN |
|
SMEMBERS |
SSCAN |
|
| Bloquer l'exécution d'un script | EVAL |
Assurez-vous que votre script ne s'exécute pas indéfiniment. |
EVALSHA |
Assurez-vous que votre script ne s'exécute pas indéfiniment. | |
| Supprimer des fichiers et des liens | DEL |
UNLINK |
| Publier et s'abonner | PUBLISH |
SPUBLISH |
SUBSCRIBE |
SSUBSCRIBE |
Bonnes pratiques concernant le client Redis
Cette section fournit des conseils pour utiliser de manière optimale votre client Redis.
Détecter et gérer les connexions qui ne répondent pas
Nous vous recommandons vivement de configurer votre application cliente pour détecter les connexions non réactives à Memorystore pour Redis. Lorsqu'une connexion qui ne répond pas est détectée, le client doit la réinitialiser. Pour créer une application résiliente, nous vous recommandons les configurations client suivantes :
- Configurez les paramètres de message keep-alive TCP : définissez les paramètres
TCP keepalive time,TCP keepalive intervaletTCP keepalive probesafin que les clients détectent et abandonnent de manière proactive les connexions qui ne répondent pas, même lorsqu'elles sont inactives. Par exemple, si vous définissez le paramètreTCP keepalive timesur 30 secondes,TCP keepalive intervalsur 10 secondes etTCP keepalive probessur 3, les clients réinitialisent les connexions inactives qui ne répondent pas en une minute. - Configurer les délais d'inactivité TCP : définissez ce délai d'inactivité dans vos clients pour réinitialiser les connexions qui ont des requêtes en attente et qui ne répondent plus. Par exemple, si vous définissez le délai avant expiration sur 15 secondes, les clients réinitialisent les connexions non réactives qui ont des requêtes en attente après 15 secondes.
Bonnes pratiques spécifiques aux clients
Si vous effectuer un scaling horizontal de vos applications, vous pouvez rencontrer des erreurs READONLY sur les commandes d'écriture. Memorystore pour Redis utilise un déploiement non Sentinel avec des points de terminaison statiques, et les clients ne reçoivent pas d'informations sur les rôles dynamiques à l'avance.
Si vous utilisez une seule connexion client pour vos points de terminaison principaux et de réplique, votre client peut envoyer accidentellement des commandes d'écriture à la réplique en lecture seule. La réplique renvoie une erreur READONLY, car elle ne peut pas traiter les commandes d'écriture.
Pour éviter le mauvais routage des écritures, n'utilisez pas une seule connexion pour les lectures et les écritures. Séparez plutôt vos opérations en créant les instances client distinctes suivantes :
- Client principal : se connecter uniquement au point de terminaison principal
- Client de réplique : ne se connecter qu'au point de terminaison de la réplique
Les onglets suivants vous montrent comment configurer les différents modèles en Go, Java, Node.js et Python.
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()