À propos du passage de Redis au cluster Redis

À propos du passage de Redis au cluster Redis

S'agissant d'un produit qui se développe depuis plus d'une décennie, il n'est pas du tout surprenant d'y trouver des technologies obsolètes. Mais que se passerait-il si, dans six mois, vous deviez maintenir la charge 10 fois plus élevée et que le coût des chutes augmentait des centaines de fois ? Dans ce cas, vous avez besoin d’un ingénieur Highload sympa. Mais en l’absence de femme de ménage, ils m’ont confié le soin de résoudre le problème. Dans la première partie de l'article, je vais vous expliquer comment nous sommes passés de Redis au cluster Redis, et dans la deuxième partie, je vous donnerai des conseils sur la façon de commencer à utiliser le cluster et à quoi faire attention lors de son utilisation.

Choix technologique

Est-ce si grave ? Redis séparé (Redis autonome) dans une configuration de 1 maître et N esclaves ? Pourquoi est-ce que j’appelle cela une technologie obsolète ?

Non, Redis n'est pas si mal... Cependant, il existe certaines lacunes qui ne peuvent être ignorées.

  • Premièrement, Redis ne prend pas en charge les mécanismes de reprise après sinistre après une panne du maître. Pour résoudre ce problème, nous avons utilisé une configuration avec transfert automatique des VIP vers un nouveau maître, changeant le rôle de l'un des esclaves et basculant le reste. Ce mécanisme a fonctionné, mais on ne peut pas le qualifier de solution fiable. Premièrement, de fausses alarmes se sont produites, et deuxièmement, il était jetable et, après son fonctionnement, des actions manuelles étaient nécessaires pour charger le ressort.

  • Deuxièmement, le fait de n’avoir qu’un seul maître a entraîné le problème du sharding. Nous avons dû créer plusieurs clusters indépendants « 1 maître et N esclaves », puis répartir manuellement les bases de données entre ces machines et espérer que demain l'une des bases de données ne gonflera pas tellement qu'elle devra être déplacée vers une instance distincte.

Quelles sont les options?

  • La solution la plus chère et la plus riche est Redis-Enterprise. Il s'agit d'une solution en boîte avec un support technique complet. Malgré le fait que cela semble idéal d'un point de vue technique, cela ne nous convenait pas pour des raisons idéologiques.
  • Cluster Redis. Prêt à l'emploi, le basculement principal et le partitionnement sont pris en charge. L'interface n'est presque pas différente de la version standard. Cela semble prometteur, nous parlerons des pièges plus tard.
  • Tarantool, Memcache, Aerospike et autres. Tous ces outils font à peu près la même chose. Mais chacun a ses propres défauts. Nous avons décidé de ne pas mettre tous nos œufs dans le même panier. Nous utilisons Memcache et Tarantool pour d'autres tâches et, pour l'avenir, je dirai que dans notre pratique, ils ont posé davantage de problèmes.

Spécificités d'utilisation

Jetons un coup d'œil aux problèmes que nous avons historiquement résolus avec Redis et aux fonctionnalités que nous avons utilisées :

  • Cache avant les requêtes vers des services distants comme 2GIS | Golang

    GET SET MGET MSET "SELECT DB"

  • Cache avant MYSQL | PHP

    GET SET MGET MSET SCAN "CLE PAR MOTIF" "SELECT DB"

  • Le stockage principal pour le service de travail avec les sessions et les coordonnées du pilote | Golang

    GET SET MGET MSET "SELECT DB" "AJOUTER GEO KEY" "GET GEO KEY" SCAN

Comme vous pouvez le constater, pas de mathématiques supérieures. Quelle est alors la difficulté ? Examinons chaque méthode séparément.

méthode
description
Caractéristiques du cluster Redis
décision

SE METTRE
Touche d'écriture/lecture

MGET MSET
Écrire/lire plusieurs clés
Les clés seront sur différents nœuds. Les bibliothèques prêtes à l'emploi ne peuvent effectuer plusieurs opérations qu'au sein d'un seul nœud
Remplacez MGET par un pipeline d'opérations N GET

SÉLECTIONNER LA BD
Sélectionnez la base avec laquelle nous travaillerons
Ne prend pas en charge plusieurs bases de données
Mettez tout dans une seule base de données. Ajouter des préfixes aux clés

SCAN
Parcourez toutes les clés de la base de données
Puisque nous avons une seule base de données, parcourir toutes les clés du cluster coûte trop cher
Maintenez un invariant dans une clé et effectuez un HSCAN sur cette clé. Ou refuser complètement

GEO
Opérations avec une géoclé
La clé géographique n'est pas fragmentée

CLÉ PAR MOTIF
Recherche d'une clé par motif
Puisque nous avons une seule base de données, nous rechercherons dans toutes les clés du cluster. Trop cher
Refuser ou maintenir l'invariant, comme dans le cas de SCAN

Redis vs Redis-cluster

Que perd-on et que gagne-t-on en passant à un cluster ?

  • Inconvénients : on perd les fonctionnalités de plusieurs bases de données.
    • Si nous voulons stocker des données logiquement indépendantes dans un cluster, nous devrons fabriquer des béquilles sous forme de préfixes.
    • Nous perdons toutes les opérations « de base », telles que SCAN, DBSIZE, CLEAR DB, etc.
    • Les multi-opérations sont devenues beaucoup plus difficiles à mettre en œuvre car elles peuvent nécessiter l'accès à plusieurs nœuds.
  • avantages:
    • Tolérance aux pannes sous forme de basculement maître.
    • Sharding côté Redis.
    • Transférez des données entre les nœuds de manière atomique et sans temps d'arrêt.
    • Ajoutez et redistribuez de la capacité et des charges sans temps d'arrêt.

Je conclurais que si vous n'avez pas besoin de fournir un niveau élevé de tolérance aux pannes, alors passer à un cluster n'en vaut pas la peine, car cela peut être une tâche non triviale. Mais si vous choisissez initialement entre une version séparée et une version cluster, alors vous devriez choisir un cluster, car ce n'est pas pire et, en plus, vous soulagera d'une partie des maux de tête

Se préparer à déménager

Commençons par les conditions requises pour déménager :

  • Cela devrait être transparent. Un arrêt complet de service pendant 5 minutes ne nous convient pas.
  • Cela devrait être aussi sûr et progressif que possible. Je veux avoir un certain contrôle sur la situation. Nous ne voulons pas tout abandonner d’un coup et prier pour le bouton de restauration.
  • Perte de données minimale lors du déplacement. Nous comprenons qu'il sera très difficile de se déplacer de manière atomique, nous autorisons donc une certaine désynchronisation entre les données dans Redis régulier et clusterisé.

Maintenance des clusters

Juste avant le déménagement, nous devrions réfléchir à la possibilité de soutenir le cluster :

  • Graphiques. Nous utilisons Prometheus et Grafana pour représenter graphiquement la charge du processeur, l'utilisation de la mémoire, le nombre de clients, le nombre d'opérations GET, SET, AUTH, etc.
  • Compétence. Imaginez que demain vous aurez un énorme cluster sous votre responsabilité. S'il se brise, personne d'autre que vous ne peut le réparer. S’il commence à ralentir, tout le monde courra vers vous. Si vous avez besoin d'ajouter des ressources ou de redistribuer la charge, revenez vers vous. Afin de ne pas devenir gris à 25 ans, il convient de prévoir ces cas et de vérifier au préalable comment la technologie se comportera sous certaines actions. Parlons-en plus en détail dans la section « Expertise ».
  • Surveillance et alertes. Lorsqu’un cluster tombe en panne, vous voulez être le premier informé. Ici, nous nous sommes limités à une notification indiquant que tous les nœuds renvoient les mêmes informations sur l'état du cluster (oui, cela se produit différemment). Et d'autres problèmes peuvent être détectés plus rapidement grâce aux alertes des services clients Redis.

Déplacer

Comment nous allons nous déplacer :

  • Tout d'abord, vous devez préparer une bibliothèque pour travailler avec le cluster. Nous avons pris go-redis comme base pour la version Go et l'avons légèrement modifié à notre convenance. Nous avons implémenté des méthodes multiples via des pipelines et avons également légèrement corrigé les règles de répétition des demandes. La version PHP a eu plus de problèmes, mais nous avons finalement opté pour php-redis. Ils ont récemment introduit le support des clusters et cela semble bien à notre avis.
  • Ensuite, vous devez déployer le cluster lui-même. Cela se fait littéralement en deux commandes basées sur le fichier de configuration. Nous discuterons du paramètre plus en détail ci-dessous.
  • Pour un déplacement progressif, nous utilisons le mode sec. Puisque nous avons deux versions de la bibliothèque avec la même interface (une pour la version standard, l'autre pour le cluster), cela ne coûte rien de créer un wrapper qui fonctionnera avec une version distincte et dupliquera en parallèle toutes les requêtes au cluster, comparez les réponses et écrivez les écarts dans les journaux (dans notre cas dans NewRelic). Ainsi, même si la version du cluster tombe en panne lors du déploiement, notre production ne sera pas affectée.
  • Après avoir déployé le cluster en mode sec, nous pouvons regarder sereinement le graphique des écarts de réponses. Si le taux d’erreur évolue lentement mais sûrement vers une petite constante, alors tout va bien. Pourquoi y a-t-il encore des divergences ? Parce que l'enregistrement dans une version séparée a lieu un peu plus tôt que dans le cluster et qu'en raison du microlag, les données peuvent diverger. Il ne reste plus qu'à regarder les journaux de divergences, et si elles s'expliquent toutes par la non-atomicité de l'enregistrement, alors nous pouvons passer à autre chose.
  • Vous pouvez maintenant changer de mode sec dans la direction opposée. Nous allons écrire et lire à partir du cluster et le dupliquer dans une version distincte. Pour quoi? Au cours de la semaine prochaine, j'aimerais observer le travail du cluster. S'il s'avère soudainement qu'il y a des problèmes en période de charge maximale, ou si nous n'avons pas pris en compte quelque chose, nous avons toujours un retour d'urgence à l'ancien code et aux données actuelles grâce au mode sec.
  • Il ne reste plus qu'à désactiver le mode sec et à démonter la version séparée.

Compétence

Tout d’abord, brièvement sur la conception du cluster.

Tout d’abord, Redis est un magasin clé-valeur. Des chaînes arbitraires sont utilisées comme clés. Des nombres, des chaînes et des structures entières peuvent être utilisés comme valeurs. Ces derniers sont très nombreux, mais pour comprendre la structure générale, cela n'a pas d'importance pour nous.
Le niveau d'abstraction suivant après les clés est celui des slots (SLOTS). Chaque clé appartient à l'un des 16 383 emplacements. Il peut y avoir n'importe quel nombre de clés à l'intérieur de chaque emplacement. Ainsi, toutes les clés sont divisées en 16 383 ensembles disjoints.
À propos du passage de Redis au cluster Redis

Ensuite, il doit y avoir N nœuds maîtres dans le cluster. Chaque nœud peut être considéré comme une instance Redis distincte qui sait tout sur les autres nœuds du cluster. Chaque nœud maître contient un certain nombre d'emplacements. Chaque emplacement appartient à un seul nœud maître. Tous les emplacements doivent être répartis entre les nœuds. Si certains emplacements ne sont pas attribués, les clés qui y sont stockées seront inaccessibles. Il est logique d'exécuter chaque nœud maître sur une machine logique ou physique distincte. Il convient également de rappeler que chaque nœud ne fonctionne que sur un seul cœur, et si vous souhaitez exécuter plusieurs instances Redis sur la même machine logique, assurez-vous qu'elles s'exécutent sur des cœurs différents (nous n'avons pas essayé cela, mais en théorie, cela devrait fonctionner). . Essentiellement, les nœuds maîtres fournissent un partitionnement régulier, et davantage de nœuds maîtres permettent d'évoluer les requêtes d'écriture et de lecture.

Une fois que toutes les clés sont réparties entre les emplacements et que les emplacements sont dispersés entre les nœuds maîtres, un nombre arbitraire de nœuds esclaves peut être ajouté à chaque nœud maître. Au sein de chacune de ces liaisons maître-esclave, la réplication normale fonctionnera. Les esclaves sont nécessaires pour faire évoluer les demandes de lecture et pour le basculement en cas de panne du maître.
À propos du passage de Redis au cluster Redis

Parlons maintenant des opérations qu'il vaudrait mieux pouvoir faire.

Nous accéderons au système via Redis-CLI. Étant donné que Redis ne dispose pas d'un seul point d'entrée, vous pouvez effectuer les opérations suivantes sur n'importe lequel des nœuds. À chaque point, j'attire séparément l'attention sur la possibilité d'effectuer l'opération sous charge.

  • La première et la plus importante chose dont nous avons besoin est le fonctionnement des nœuds du cluster. Il renvoie l'état du cluster, affiche une liste de nœuds, leurs rôles, la répartition des emplacements, etc. Plus d'informations peuvent être obtenues à l'aide des informations sur le cluster et des emplacements de cluster.
  • Ce serait bien de pouvoir ajouter et supprimer des nœuds. À cette fin, il existe des opérations de rencontre de cluster et d’oubli de cluster. Veuillez noter que l'oubli de cluster doit être appliqué à CHAQUE nœud, à la fois maîtres et réplicas. Et cluster meet ne doit être appelé que sur un seul nœud. Cette différence peut être déconcertante, il est donc préférable de s'en informer avant de mettre en service votre cluster. L'ajout d'un nœud se fait en toute sécurité en combat et n'affecte en rien le fonctionnement du cluster (ce qui est logique). Si vous envisagez de supprimer un nœud du cluster, vous devez vous assurer qu'il ne reste aucun emplacement dessus (sinon vous risquez de perdre l'accès à toutes les clés de ce nœud). Ne supprimez pas non plus un maître qui a des esclaves, sinon un vote inutile pour un nouveau maître sera effectué. Si les nœuds n'ont plus d'emplacements, alors c'est un petit problème, mais pourquoi avons-nous besoin de choix supplémentaires si nous pouvons d'abord supprimer les esclaves.
  • Si vous devez forcer l'échange des positions du maître et de l'esclave, la commande de basculement du cluster fera l'affaire. Lorsque vous l'appelez au combat, vous devez comprendre que le maître ne sera pas disponible pendant l'opération. Généralement, le changement se produit en moins d’une seconde, mais n’est pas atomique. Vous pouvez vous attendre à ce que certaines requêtes adressées au maître échouent pendant cette période.
  • Avant de supprimer un nœud du cluster, il ne doit rester aucun emplacement dessus. Il est préférable de les redistribuer à l'aide de la commande cluster reshard. Les slots seront transférés d’un maître à un autre. L'ensemble de l'opération peut prendre plusieurs minutes, cela dépend du volume de données transférées, mais le processus de transfert est sécurisé et n'affecte en rien le fonctionnement du cluster. Ainsi, toutes les données peuvent être transférées d’un nœud à un autre directement sous charge, et sans se soucier de leur disponibilité. Cependant, il y a aussi des subtilités. Premièrement, le transfert de données est associé à une certaine charge sur les nœuds destinataires et expéditeurs. Si le nœud destinataire est déjà fortement chargé sur le processeur, vous ne devez pas le charger en recevant de nouvelles données. Deuxièmement, dès qu'il ne reste plus un seul slot sur le maître émetteur, tous ses esclaves iront immédiatement vers le maître vers lequel ces slots ont été transférés. Et le problème est que tous ces esclaves voudront synchroniser les données en même temps. Et vous aurez de la chance s’il s’agit d’une synchronisation partielle plutôt que complète. Tenez-en compte et combinez les opérations de transfert de slots et de désactivation/transfert d'esclaves. Ou espérer que vous disposez d’une marge de sécurité suffisante.
  • Que faire si, lors du transfert, vous constatez que vous avez perdu vos créneaux quelque part ? J'espère que ce problème ne vous affecte pas, mais si c'est le cas, il existe une opération de correction du cluster. À tout le moins, elle dispersera les emplacements sur les nœuds dans un ordre aléatoire. Je recommande de vérifier son fonctionnement en supprimant d'abord le nœud avec des emplacements distribués du cluster. Étant donné que les données des emplacements non alloués sont déjà indisponibles, il est trop tard pour s'inquiéter des problèmes liés à la disponibilité de ces emplacements. À son tour, l’opération n’affectera pas les slots distribués.
  • Une autre opération utile est le moniteur. Il permet de voir en temps réel la liste complète des requêtes arrivant au nœud. De plus, vous pouvez le récupérer et savoir s’il existe le trafic nécessaire.

Il convient également de mentionner la procédure de basculement maître. Bref, ça existe, et, à mon avis, ça marche très bien. Cependant, ne pensez pas que si vous débranchez le cordon d'alimentation d'une machine dotée d'un nœud maître, Redis basculera immédiatement et les clients ne remarqueront pas la perte. Dans ma pratique, la commutation se produit en quelques secondes. Pendant ce temps, certaines données seront indisponibles : l'indisponibilité du maître est détectée, les nœuds votent pour un nouveau, les esclaves sont commutés, les données sont synchronisées. La meilleure façon de vous assurer que le programme fonctionne est d’organiser des exercices locaux. Soulevez le cluster sur votre ordinateur portable, donnez-lui une charge minimale, simulez un crash (par exemple en bloquant les ports) et évaluez la vitesse de commutation. À mon avis, ce n'est qu'après avoir joué de cette manière pendant un jour ou deux que vous pourrez avoir confiance dans le fonctionnement de la technologie. Eh bien, ou espérer que le logiciel utilisé par la moitié d’Internet fonctionne probablement.

Configuration

Souvent, la configuration est la première chose dont vous avez besoin pour commencer à travailler avec l’outil. Et quand tout fonctionne, vous ne voulez même pas toucher à la configuration. Il faut un certain effort pour se forcer à revenir aux paramètres et à les parcourir attentivement. Dans ma mémoire, nous avons eu au moins deux échecs graves dus à une inattention à la configuration. Portez une attention particulière aux points suivants :

  • délai 0
    Temps après lequel les connexions inactives sont fermées (en secondes). 0 - ne ferme pas
    Toutes nos bibliothèques n’ont pas été en mesure de fermer correctement les connexions. En désactivant ce paramètre, nous risquons d'atteindre la limite du nombre de clients. D'un autre côté, si un tel problème existe, la résiliation automatique des connexions perdues le masquera et nous ne le remarquerons peut-être pas. De plus, vous ne devez pas activer ce paramètre lorsque vous utilisez des connexions persistantes.
  • Enregistrer xy et annexe uniquement oui
    Enregistrement d'un instantané RDB.
    Nous discuterons en détail des problèmes RDB/AOF ci-dessous.
  • stop-writes-on-bgsave-error non & slave-serve-stale-data oui
    Si cette option est activée, si l'instantané RDB est interrompu, le maître cessera d'accepter les demandes de modification. Si la connexion avec le maître est perdue, l'esclave peut continuer à répondre aux requêtes (oui). Ou cessera de répondre (non)
    Nous ne sommes pas satisfaits de la situation dans laquelle Redis se transforme en citrouille.
  • repl-ping-esclave-période 5
    Passé ce délai, nous commencerons à craindre que le maître soit en panne et il est temps d'effectuer la procédure de basculement.
    Vous devrez trouver manuellement un équilibre entre les faux positifs et le déclenchement d'un basculement. Dans notre pratique, cela dure 5 secondes.
  • repl-backlog-size 1024 Mo & epl-backlog-ttl 0
    Nous pouvons stocker exactement autant de données dans un tampon pour une réplique ayant échoué. Si le tampon est épuisé, vous devrez effectuer une synchronisation complète.
    La pratique suggère qu'il est préférable de fixer une valeur plus élevée. Il existe de nombreuses raisons pour lesquelles une réplique peut commencer à prendre du retard. S'il est en retard, il est fort probable que votre maître ait déjà du mal à s'en sortir, et une synchronisation complète sera la goutte d'eau qui a fait déborder le vase.
  • clients maximum 10000
    Nombre maximum de clients ponctuels.
    D'après notre expérience, il est préférable de fixer une valeur plus élevée. Redis gère très bien 10 XNUMX connexions. Assurez-vous simplement qu'il y a suffisamment de sockets sur le système.
  • politique de mémoire maximale volatile-ttl
    Règle selon laquelle les clés sont supprimées lorsque la limite de mémoire disponible est atteinte.
    Ce qui est important ici, ce n’est pas la règle elle-même, mais la compréhension de la manière dont cela se produira. Redis peut être félicité pour sa capacité à fonctionner normalement lorsque la limite de mémoire est atteinte.

Problèmes RDB et AOF

Bien que Redis lui-même stocke toutes les informations dans la RAM, il existe également un mécanisme permettant de sauvegarder les données sur le disque. Plus précisément, trois mécanismes :

  • RDB-snapshot - un instantané complet de toutes les données. Définissez à l'aide de la configuration SAVE XY et indique « Enregistrez un instantané complet de toutes les données toutes les X secondes si au moins Y clés ont changé. »
  • Fichier à ajouter uniquement : une liste d'opérations dans l'ordre dans lequel elles sont effectuées. Ajoute de nouvelles opérations entrantes au fichier toutes les X secondes ou toutes les Y opérations.
  • RDB et AOF sont une combinaison des deux précédents.

Toutes les méthodes ont leurs avantages et leurs inconvénients, je ne les énumérerai pas toutes, j'attirerai juste votre attention sur des points qui, à mon avis, ne sont pas évidents.

Tout d’abord, l’enregistrement d’un instantané RDB nécessite l’appel de FORK. S'il y a beaucoup de données, cela peut bloquer tout Redis pendant une période de quelques millisecondes à une seconde. De plus, le système doit allouer de la mémoire pour un tel instantané, ce qui conduit à la nécessité de conserver une double réserve de RAM sur la machine logique : si 8 Go sont alloués pour Redis, alors 16 Go devraient être disponibles sur la machine virtuelle avec il.

Deuxièmement, il existe des problèmes de synchronisation partielle. En mode AOF, lorsque l'esclave est reconnecté, au lieu d'une synchronisation partielle, une synchronisation complète peut être effectuée. Pourquoi cela se produit, je ne pouvais pas comprendre. Mais cela vaut la peine de s'en souvenir.

Ces deux points nous amènent déjà à nous demander si nous avons vraiment besoin de ces données sur le disque si tout est déjà dupliqué par des esclaves. Les données ne peuvent être perdues que si tous les esclaves tombent en panne, et il s'agit d'un problème de niveau « incendie dans le DC ». En guise de compromis, vous pouvez proposer de sauvegarder les données uniquement sur les esclaves, mais dans ce cas, vous devez vous assurer que ces esclaves ne deviendront jamais maîtres lors d'une reprise après sinistre (pour cela, il existe un paramètre de priorité des esclaves dans leur configuration). Pour nous-mêmes, dans chaque cas spécifique, nous réfléchissons à la nécessité de sauvegarder les données sur le disque, et le plus souvent la réponse est « non ».

Conclusion

En conclusion, j'espère avoir pu donner une idée générale du fonctionnement du redis-cluster pour ceux qui n'en ont pas du tout entendu parler, et également attirer l'attention sur certains points non évidents pour ceux qui l'ont utilisé pendant longtemps.
Merci pour votre temps et, comme toujours, les commentaires sur le sujet sont les bienvenus.

Source: habr.com

Ajouter un commentaire