Bonnes pratiques pour Memorystore pour Redis

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.

Bonnes pratiques concernant la haute disponibilité et la durabilité des données

Nous vous recommandons d'utiliser le niveau Standard comme mécanisme principal pour la haute disponibilité (HA). Le niveau Standard fournit une instance disponibilité élevée avec plusieurs instances répliquées et permet une récupération rapide à l'aide du basculement automatique en cas de défaillance de l'instance principale. De plus, l'activation des instantanés RDB sur les instances de niveau Standard offre une protection supplémentaire contre les défaillances de nœuds.

Dans certains cas, vous pouvez également vous assurer que vous pouvez récupérer des données à partir de sauvegardes d'instantanés. Dans ces scénarios, les sauvegardes et la possibilité de restaurer des données à partir d'instantanés RDB peuvent fournir une protection supplémentaire contre la perte de données.

Si vous activez les instantanés RDB et que vous devez récupérer vos données, Memorystore pour Redis peut le faire à partir du dernier instantané. Ces instantanés sont destinés uniquement à la récupération du système interne et vous ne pouvez pas y accéder.

Limites de durabilité et bonnes pratiques

Bien que le niveau Standard fournisse une haute disponibilité via la réplication et le basculement automatique, la haute disponibilité ne garantit pas une durabilité totale des données. Memorystore pour Redis ne peut pas assurer une durabilité totale des données, même lorsque la haute disponibilité est activée, lors de certains événements catastrophiques, tels que des défaillances régionales temporaires.

Pour protéger vos données et fournir un niveau de persistance de référence, les instantanés RDB sont activés par défaut lorsque vous créez une instance Memorystore pour Redis à l'aide de la console Google Cloud .

Pour les charges de travail de production, tenez compte des bonnes pratiques suivantes pour améliorer davantage la résilience de vos données :

  • Reprise après sinistre : Memorystore pour Redis n'est pas compatible avec la réplication interrégionale. Si votre stratégie de reprise après sinistre nécessite une réplication interrégionale pour une véritable résilience régionale, nous vous recommandons d'utiliser une instance Memorystore pour Valkey. Pour en savoir plus sur la configuration et la gestion des instances secondaires dans plusieurs régions, consultez Utiliser la réplication interrégionale dans la documentation Memorystore pour Valkey.
  • Durabilité maximale : si votre application nécessite le niveau de durabilité des données le plus élevé possible, nous vous recommandons d'utiliser une instance Memorystore pour Valkey configurée avec la réplication interrégionale, des sauvegardes quotidiennes automatisées et la persistance des fichiers AOF (Append-Only File). Cette combinaison offre la protection la plus robuste contre la perte de données. Pour en savoir plus, consultez la section Présentation de la persistance dans la documentation de Memorystore pour Valkey.

Bonnes pratiques de planification de la capacité

Pour vous assurer que vous pouvez provisionner des ressources et créer des architectures résilientes, nous vous recommandons de suivre les bonnes pratiques de planification de la capacité suivantes :

  • Déployer sur plusieurs emplacements : si vous ne parvenez pas à créer une instance dans votre zone préférée en raison de contraintes de ressources temporaires, essayez de créer l'instance dans une autre zone de la même région ou dans une autre région.
  • Utiliser l'accès interrégional : configurez vos clients pour qu'ils accèdent à vos instances situées dans différentes régions. Si vous devez provisionner une instance située dans une autre région en raison de contraintes de ressources locales, vos clients peuvent se connecter à l'instance.
  • Choisissez un autre niveau de capacité : si vous rencontrez des contraintes de ressources en raison de la taille d'une instance, sélectionnez un autre niveau de capacité ou redimensionnez l'instance. Pour en savoir plus, consultez Performances des niveaux de capacité.

Exportation RDB

Lorsque vous exportez une sauvegarde RDB, suivez les conseils ci-dessous :

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 :

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 :

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 :

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 :

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.

La meilleure façon de surveiller la pression de la mémoire sur votre instance Memorystore consiste à utiliser la métrique "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, et elles peuvent entrer en conflit avec les exigences de conformité d'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 :

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 fournissent une haute disponibilité lors de la reprise après sinistre et s'appuient sur la réplication asynchrone entre les nœuds principaux et les instances répliquées. Si l'un des nœuds traite une commande coûteuse qui bloque le thread principal Redis, la réplication peut être affectée. Si le problème persiste et qu'une panne se produit, les données les plus récentes écrites à l'emplacement de la panne risquent de ne pas être disponibles à 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) afin de vous assurer que l'utilisation du processeur ne dépasse pas 0,8 seconde pour le nœud principal ou 0,5 seconde pour chaque instance répliquée, lorsque l'instance répliquée est désignée comme instance répliquée avec accès en lecture.

Si votre instance Redis dépasse les valeurs recommandées, nous vous conseillons de mettre à l'échelle l'instance vers un niveau de capacité supérieur ou de suivre les instructions de dépannage pour éviter les opérations gourmandes en ressources de processeur.

Si votre instance utilise beaucoup de ressources de processeur ou si ses ressources sont épuisées (par exemple, en raison d'un trop grand nombre de connexions), elle peut ne pas fonctionner correctement et des métriques externes peuvent être manquantes.

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 du client
  • Saturation de 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 d'état, observabilité et réplication insuffisantes

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 les clients Redis

Cette section fournit des conseils pour utiliser votre client Redis de manière optimale.

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 qui ne répondent pas à 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 TCP keep-alive : définissez les paramètres TCP keepalive time, TCP keepalive interval et TCP keepalive probes de sorte que les clients détectent et suppriment 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ètre TCP keepalive time sur 30 secondes, TCP keepalive interval sur 10 secondes et TCP keepalive probes sur 3, les clients réinitialisent les connexions inactives qui ne répondent pas dans un délai d'une minute.
  • Configurer les délais avant expiration TCP de l'utilisateur : définissez ce délai avant expiration 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 qui ne répondent pas et qui ont des requêtes en attente après 15 secondes.

Bonnes pratiques spécifiques au client

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 de rôle dynamiques à l'avance. Si vous utilisez une seule connexion client pour vos points de terminaison principal et d'instance répliquée, votre client peut envoyer accidentellement des commandes d'écriture à l'instance répliquée en lecture seule. L'instance répliquée renvoie une erreur READONLY, car elle ne peut pas traiter les commandes d'écriture.

Pour éviter les erreurs de routage des écritures, n'utilisez pas une seule connexion pour les lectures et les écritures. Divisez plutôt vos opérations en créant les instances client distinctes suivantes :

  • Client principal : se connecter uniquement au point de terminaison principal
  • Client d'instance répliquée : se connecte uniquement au point de terminaison de l'instance répliquée.

Les onglets suivants vous montrent comment configurer les modèles distincts 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()