Maison > base de données > Redis > Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

青灯夜游
Libérer: 2021-10-15 11:15:01
avant
2383 Les gens l'ont consulté

Cet article vous présentera les connaissances pertinentes de la distribution Redis et vous guidera à travers la réplication maître-esclave, Sentinel et le clustering, afin de faire passer votre niveau Redis à un niveau supérieur !

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

1. Réplication maître-esclave

1. Introduction

La réplication maître-esclave est la pierre angulaire de la distribution Redis et la garantie de la haute disponibilité de Redis. Dans Redis, le serveur en cours de réplication est appelé serveur maître (Master) et le serveur répliquant le serveur maître est appelé serveur esclave (Slave). [Recommandations associées : Tutoriel vidéo Redis]

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

La configuration de la réplication maître-esclave est très simple. Il existe trois méthodes (IP-adresse IP du serveur principal/PORT-port du service Redis du serveur principal) :

  • .

    Fichier de configuration ——Dans le fichier redis.conf, configurez la commande slaveof ip port

  • ——Entrez le client Redis pour exécuter slaveof ip port

  • Paramètres de démarrage——./redis-server --slaveof ip port

2 , L'évolution de la réplication maître-esclave

Le mécanisme de réplication maître-esclave de Redis n'était pas aussi parfait que la version 6.x au début, mais il a été itéré de version en version. Il a généralement connu trois versions d'itérations :

  • Avant la 2.8

  • 2.8~4.0

  • Après la 4.0

Au fur et à mesure que la version grandit, le mécanisme de réplication maître-esclave Redis s'améliore progressivement mais leur ; Essentiellement, elles tournent autour des deux opérations de synchronisation (sync) et de propagation de commandes :

  • Synchronisation (sync) : fait référence à la mise à jour de l'état des données du serveur esclave vers l'état actuel des données du serveur principal, ce qui se produit principalement dans Initialisation ou synchronisation complète ultérieure.

  • Propagation de la commande : lorsque l'état des données du serveur maître est modifié (écriture/suppression, etc.) et que l'état des données entre le maître et l'esclave est incohérent, le service maître propage la commande de modification des données à l'esclave serveur, permettant au maître de L'état entre les serveurs esclaves est restauré pour être cohérent.

2.1 Avant la version 2.8

2.1.1 Synchronisation

Avant la version 2.8, la synchronisation du serveur esclave vers le serveur maître nécessite que la commande sync du serveur vers le serveur maître soit terminée :

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

  • Reçu du serveur À la commande slaveof ip prot envoyée par le client, le serveur esclave crée une connexion socket au serveur maître basée sur ip:port

  • Une fois la socket connectée avec succès au serveur maître, le serveur esclave associera une connexion socket dédiée au serveur maître. Gestionnaire d'événements de fichiers utilisé pour gérer le travail de réplication, gérer les fichiers RDB ultérieurs et les commandes propagées envoyées par le serveur maître

  • Démarrer la réplication, envoyer les commandes de synchronisation du serveur au serveur maître

    .
  • Le serveur maître reçoit la commande sync. Après cela, exécutez la commande bgsave, le sous-processus du fork de processus principal du serveur principal générera un fichier RDB et enregistrera en même temps toutes les opérations d'écriture après l'instantané RDB. est généré dans le tampon

  • Après l'exécution de la commande bgsave, le serveur principal générera Le fichier RDB est envoyé au serveur esclave Après avoir reçu le fichier RDB du serveur esclave, il effacera d'abord toutes ses propres données, puis chargez le fichier RDB et mettez à jour son propre état de données avec l'état des données du fichier RDB du serveur maître

  • Le serveur maître Envoyez la commande d'écriture du tampon au serveur esclave, recevez la commande du serveur et exécutez il.

  • L'étape de synchronisation de la réplication maître-esclave est terminée

2.1.2 Propagation des commandes

Une fois le travail de synchronisation terminé, le maître-esclave doit maintenir la cohérence de l'état des données grâce à la propagation des commandes. Comme le montre la figure ci-dessous, une fois le travail de synchronisation entre les serveurs maître et esclave actuels terminé, le service maître supprime K6 après avoir reçu l'instruction DEL K6 du client. À ce moment, K6 existe toujours sur le serveur esclave et le. L'état des données maître-esclave est incohérent. Afin de maintenir l'état cohérent des serveurs maître et esclave, le serveur maître propagera les commandes qui entraînent le changement de son propre état des données vers le serveur esclave pour exécution. Lorsque le serveur esclave exécute également la même commande, l'état des données entre les deux. les serveurs maître et esclave resteront cohérents.

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

2.1.3 Défauts

D'après ce qui précède, nous ne voyons aucun défaut dans la réplication maître-esclave des versions antérieures à la 2.8. C'est parce que nous n'avons pas pris en compte les fluctuations du réseau. Les frères qui comprennent la distribution doivent avoir entendu parler de la théorie CAP.La théorie CAP est la pierre angulaire des systèmes de stockage distribués.Dans la théorie CAP, P (partition réseau de partition) doit exister, et la réplication maître-esclave Redis ne fait pas exception. Lorsqu'une panne de réseau se produit entre les serveurs maître et esclave, entraînant l'échec de la communication entre le serveur esclave et le serveur maître pendant un certain temps. Lorsque le serveur esclave se reconnecte au serveur maître, si l'état des données du serveur maître. change pendant cette période, des incohérences dans l'état des données du serveur maître-esclave se produiront entre les serveurs. Dans les versions de réplication maître-esclave antérieures à Redis 2.8, la manière de résoudre cette incohérence d'état des données consiste à renvoyer la commande de synchronisation. Bien que la synchronisation puisse garantir la cohérence de l'état des données des serveurs maître et esclave, il est évident que la synchronisation est une opération très gourmande en ressources.

exécution de la commande de synchronisation, les ressources requises par les serveurs maître et esclave :

  • Le serveur maître exécute BGSAVE pour générer des fichiers RDB, qui occuperont beaucoup de ressources CPU, E/S disque et mémoire

  • Le Le serveur maître enverra les fichiers RDB générés. Le donner au serveur esclave occupera beaucoup de bande passante réseau

  • La réception et le chargement du fichier RDB à partir du serveur entraîneront le blocage du serveur esclave et l'empêcheront de fournir des services

  • .

Comme le montrent les trois points ci-dessus, la commande sync entraînera non seulement le maître. Une diminution de la réactivité du serveur entraînera également le refus du serveur esclave de fournir des services externes pendant cette période.

2.2 Version 2.8-4.0

2.2.1 Améliorations

Pour les versions antérieures à la 2.8, Redis a amélioré la synchronisation de l'état des données après la reconnexion du serveur après la 2.8. La direction de l'amélioration est de réduire l'apparition d'une resynchronisation complète et d'utiliser autant que possible la resynchronisation partielle. Après la version 2.8, la commande psync est utilisée à la place de la commande sync pour effectuer les opérations de synchronisation. La commande psync a à la fois des fonctions de synchronisation complète et incrémentielle :

  • La synchronisation complète est cohérente avec la version précédente (sync)

  • Incrémentielle. synchronisation Pour la réplication après déconnexion et reconnexion, différentes mesures seront prises selon la situation ; si les conditions le permettent, seule une partie des données manquantes au service sera quand même envoyée.

2.2.2 Comment implémenter psync

Afin d'obtenir une synchronisation incrémentielle après déconnexion et reconnexion du serveur, Redis ajoute trois paramètres auxiliaires :

  • replication offset (replication offset)

  • Backlog buffer ( arriéré de réplication)

  • ID d'exécution du serveur (id d'exécution)

2.2.2.1 Décalage de réplication

Un décalage de réplication sera maintenu à la fois dans le serveur maître et dans le serveur esclave

  • Le serveur maître envoie données au service esclave, répartissant N octets de données, et le décalage de réplication du service maître augmente de N

  • Le serveur esclave reçoit les données envoyées par le serveur maître, reçoit N octets de données, et le serveur esclave Le le décalage de réplication augmente de N

La situation normale de synchronisation est la suivante :

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

En comparant si les décalages de réplication entre les serveurs maître et esclave sont égaux, vous pouvez savoir si l'état des données entre le maître et les serveurs esclaves sont cohérents. Supposons que A/B se propage normalement à ce moment et que le serveur esclave C est déconnecté, alors la situation suivante se produira :

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Évidemment, après que le décalage de réplication soit disponible, après que le serveur esclave C soit déconnecté et reconnecté , le serveur maître enverra uniquement les 100 octets de données manquants du serveur. Mais comment le serveur maître sait-il quelles données manquent sur le serveur esclave ?

2.2.2.2 Tampon de backlog de copie

Le tampon de backlog de copie est une file d'attente de longueur fixe avec une taille par défaut de 1 Mo. Lorsque l'état des données du serveur maître change, le serveur maître synchronise les données avec le serveur esclave et enregistre une copie dans le tampon du backlog de réplication.

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Afin de faire correspondre le décalage, le tampon du backlog de copie stocke non seulement le contenu des données, mais enregistre également le décalage correspondant à chaque octet :

复制积压缓冲区+字节值+Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Lorsque le serveur esclave est déconnecté et reconnecté Enfin, l'esclave Le serveur envoie son propre décalage de réplication (offset) au serveur maître via la commande psync. Le serveur maître peut utiliser ce décalage pour déterminer s'il doit effectuer une propagation incrémentielle ou une synchronisation complète.

  • Si les données à offset offset+1 sont toujours dans le tampon du backlog de copie, effectuez une opération de synchronisation incrémentielle

  • Sinon, effectuez une opération de synchronisation complète, cohérente avec la synchronisation

La taille du tampon de copie par défaut de Redis est de 1 Mo. Comment la définir si vous devez la personnaliser ? Évidemment, nous souhaitons utiliser la synchronisation incrémentielle autant que possible, mais nous ne voulons pas que le tampon occupe trop d'espace mémoire. Nous pouvons ensuite définir la taille du tampon de backlog de réplication S en estimant le temps de reconnexion T après la déconnexion du service esclave Redis et la taille de mémoire M des commandes d'écriture reçues par le serveur maître Redis par seconde.

S = 2 * M * T

Notez que l'expansion 2 fois ici vise à laisser une certaine marge pour garantir que la plupart des déconnexions et reconnexions peuvent utiliser la synchronisation incrémentielle.

2.2.2.3 Serveur exécutant l'ID

Après avoir vu cela, pensez-vous à nouveau que la synchronisation incrémentielle de la déconnexion et de la reconnexion peut être réalisée ci-dessus, pourquoi avez-vous encore besoin d'exécuter l'ID ? En fait, il existe une autre situation qui n'a pas été prise en compte, c'est-à-dire que lorsque le serveur maître tombe en panne, un serveur esclave est élu comme nouveau serveur maître. Dans ce cas, nous pouvons le distinguer en comparant l'ID en cours d'exécution.

  • L'ID d'exécution (run id) est constitué de 40 chaînes hexadécimales aléatoires générées automatiquement au démarrage du serveur. Le service maître et le serveur esclave génèreront l'ID d'exécution

  • Lorsque le serveur esclave synchronise celui du serveur maître pour le. la première fois Lorsque les données sont générées, le serveur maître enverra son propre ID d'exécution au serveur esclave, et le serveur esclave l'enregistrera dans le fichier RDB

  • Lorsque le serveur esclave sera déconnecté et reconnecté, le serveur esclave enverra l'ID d'exécution du serveur maître précédemment enregistré sur le serveur maître. Si l'ID d'exécution du serveur correspond, cela prouve que le serveur principal n'a pas changé, vous pouvez essayer la synchronisation incrémentielle

  • Si l'ID d'exécution du serveur ne correspond pas, effectuez une synchronisation complète. synchronisation

2.2.3 PPsync complète

Complet Le processus psync est très complexe, et il a été très complet dans la version de réplication maître-esclave 2.8-4.0. Les paramètres envoyés par la commande psync sont les suivants :

psync

Lorsque le serveur esclave n'a répliqué aucun serveur maître (ce n'est pas la première fois que le maître-esclave réplique, car le serveur maître peut changer, mais la première copie complète de la synchronisation du serveur esclave), le serveur esclave enverra :

psync ? SLAVEOF 127.0.0.1 est reçu du serveur 6379 La commande

renvoie OK du serveur à l'initiateur de la commande (il s'agit d'une opération asynchrone, retournez d'abord OK, puis enregistrez l'adresse et les informations de port) Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Enregistrer l'adresse IP et les informations de port du serveur vers l'hôte maître et le port maître

一次完整的Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.Le serveur esclave initie activement une connexion socket au serveur maître en fonction de l'hôte maître et du port maître. En même temps, le service esclave le fera. associez un gestionnaire d'événements de fichier spécifiquement utilisé pour la copie de fichiers à cette connexion socket pour une utilisation ultérieure de la copie de fichier RDB et d'autres travaux

  • Le serveur maître reçoit la demande de connexion socket du serveur esclave, crée une connexion socket correspondante pour la demande, et regarde un client du serveur esclave (dans la réplication maître-esclave, le serveur maître et le serveur esclave sont en fait clients et serveurs l'un de l'autre)

  • La connexion socket est établie. Le serveur esclave envoie activement une commande PING. au service maître. Si le serveur maître renvoie PONG dans le délai d'attente spécifié, cela prouve que la connexion socket est disponible, sinon elle est déconnectée et reconnectée. Si le serveur maître a défini un mot de passe (masterauth), alors le serveur esclave envoie. la commande AUTH masterauth au serveur maître pour l'authentification. Notez que si le serveur esclave envoie un mot de passe mais que le service maître ne définit pas de mot de passe, le serveur maître enverra une erreur aucun mot de passe n'est défini ; si le serveur maître demande un mot de passe mais que le serveur esclave n'envoie pas de mot de passe, le maître ; le serveur enverra une erreur NOAUTH ; si les mots de passe ne correspondent pas, le serveur maître envoie une erreur de mot de passe invalide.

  • Le serveur esclave envoie le port d'écoute REPLCONF xxxx (xxxx représente le port du serveur esclave) au serveur maître. Après avoir reçu la commande, le serveur principal enregistrera les données. Lorsque le client utilise la réplication INFO pour interroger les informations maître-esclave, il peut renvoyer les données

  • Envoyer la commande psync depuis le serveur. les deux situations de psync dans l'image ci-dessus

  • Le serveur maître et le serveur esclave sont clients l'un de l'autre, effectuant des requêtes/réponses de données

  • Le serveur maître et le serveur esclave utilisent le mécanisme de paquet de battement de coeur pour déterminer si la connexion est déconnectée. Le serveur esclave envoie une commande au serveur maître toutes les 1 seconde, REPLCONF ACL offset (offset de réplication du serveur esclave). Ce mécanisme peut assurer la synchronisation correcte des données entre le maître et l'esclave. Si les offsets ne sont pas égaux, le maître. le serveur prendra des mesures de synchronisation incrémentielle/complète pour garantir un état cohérent des données entre le maître et l'esclave (le choix incrémentiel/complet dépend du fait que les données à offset+1 sont toujours dans le tampon du backlog de réplication)

2.3 version 4.0

Redis version 2.8-4.0 a encore quelques améliorations à apporter. La synchronisation incrémentielle peut-elle être effectuée lorsque le serveur principal est commuté ? Par conséquent, la version Redis 4.0 a été optimisée pour résoudre ce problème et psync a été mis à niveau vers psync2.0. pync2.0 a abandonné l'ID d'exécution du serveur et a utilisé replid et replid2 à la place. Replid stocke l'ID d'exécution du serveur principal actuel, et replid2 enregistre l'ID d'exécution du serveur principal précédent.

  • décalage de réplication

  • arriéré de réplication

  • identifiant d'exécution du serveur maître (replid)

  • dernier serveur maître exécutant l'identifiant (replid2)

Grâce à replid et replid2, nous pouvons résoudre le problème de l'incrémentation synchronisation lors du changement de serveur principal :

  • Si replid est égal à l'identifiant d'exécution du serveur principal actuel, alors déterminez la méthode de synchronisation synchronisation incrémentielle/complète

  • Si le replid n'est pas égal, déterminez si réplicad2 est égaux (qu'ils appartiennent au serveur esclave du serveur maître précédent). S'ils sont égaux, vous pouvez toujours choisir une synchronisation incrémentielle/complète. S'ils ne sont pas égaux, vous ne pouvez effectuer qu'une synchronisation complète.

2. Sentinel

1 Introduction

La réplication maître-esclave jette les bases de la distribution Redis, mais la réplication maître-esclave ordinaire ne peut pas atteindre une haute disponibilité. Dans le mode de réplication maître-esclave ordinaire, si le serveur maître tombe en panne, le personnel d'exploitation et de maintenance ne peut changer que manuellement le serveur maître. Évidemment, cette solution n'est pas recommandée. En réponse à la situation ci-dessus, Redis a officiellement lancé une solution à haute disponibilité capable de résister aux pannes de nœuds : Redis Sentinel. Redis Sentinel : un système Sentinel composé d'une ou plusieurs instances Sentinel. Il peut surveiller n'importe quel nombre de serveurs maîtres et esclaves. Lorsque le serveur maître surveillé tombe en panne, le serveur maître sera automatiquement hors ligne et le serveur esclave sera mis à niveau vers un nouveau maître. serveur.

L'exemple suivant : lorsque l'ancien maître est hors ligne pendant une durée supérieure à la limite supérieure de la durée hors ligne définie par l'utilisateur, le système Sentinel effectuera une opération de basculement sur l'ancien maître. L'opération de basculement comprend trois étapes :

  • .

    Sélectionner les données dans l'esclave Le dernier sert de nouveau maître

  • Envoie de nouvelles instructions de réplication à d'autres esclaves, permettant à d'autres serveurs esclaves de devenir les nouveaux esclaves du maître

  • Continuer à surveiller l'ancien maître, et s'il passe en ligne, définissez l'ancien maître sur le nouveau maître esclave

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Cet article est basé sur la liste de ressources suivante :

6 379/ 263796379/26379
Adresse IP Rôle du nœud Port
192.168.211.104 Redis Master/ Sentinelle 192.168.211.105 Redis Esclave/ Sentinelle
192.168.211.106 Esclave Redis/Sentinelle

2. Initialisation de Sentinel et connexion réseau

Il n'y a rien de particulièrement magique dans Sentinel. Il s'agit d'un serveur Redis plus simple. Lorsque Sentinel démarre, il chargera différentes tables de commandes et fichiers de configuration, donc en substance, Sentinel est un service Redis. moins de commandes et quelques fonctions spéciales. Lorsqu'un Sentinel démarre, il doit suivre les étapes suivantes :

  • Initialiser le serveur Sentinel

  • Remplacer le code Redis ordinaire par le code spécifique à Sentinel

  • Initialiser l'état Sentinel

  • Selon le fichier de configuration Sentinel donné par l'utilisateur, initialiser la liste des serveurs maîtres surveillés par Sentinel

  • Créer une connexion réseau au serveur maître

  • Obtenir les informations du serveur esclave en fonction du service maître, créer une connexion réseau pour le serveur esclave

  • Obtenir des informations Sentinel basées sur la publication/l'abonnement, créer une connexion réseau entre Sentinel

2.1 Initialiser le serveur Sentinel

Sentinel est essentiellement un serveur Redis, donc démarrer Sentinel nécessite le démarrage d'un serveur Redis, mais Sentinel n'a pas besoin de lire les fichiers RDB/AOF pour restaurer l'état des données.

2.2 Remplacer le code Redis ordinaire par du code spécifique à Sentinel

Sentinel est utilisé pour moins de commandes Redis. La plupart des commandes ne sont pas prises en charge par le client Sentinel, et Sentinel a certaines fonctions spéciales, qui nécessitent que Sentinel utilise Redis au démarrage. Le code utilisé par le serveur est remplacé par du code spécifique à Sentinel. Pendant cette période, Sentinel chargera une table de commandes différente de celle du serveur Redis ordinaire. Sentinel ne prend pas en charge les commandes telles que SET et DBSIZE ; il conserve la prise en charge de PING, PSUBSCRIBE, SUBSCRIBE, UNSUBSCRIBE, INFO et d'autres commandes fournissent des garanties pour le travail de Sentinel ;

2.3 Initialisation de l'état de Sentinel

Après avoir chargé le code unique de Sentinel, Sentinel initialisera la structure sentinelState, qui est utilisée pour stocker les informations d'état liées à Sentinel, dont la plus importante est le dictionnaire maître.

struct sentinelState {
   
    //当前纪元,故障转移使用
 uint64_t current_epoch; 
  
    // Sentinel监视的主服务器信息 
    // key -> 主服务器名称 
    // value -> 指向sentinelRedisInstance指针
    dict *masters; 
    // ...
} sentinel;
Copier après la connexion

2.4 Initialiser la liste des serveurs maîtres surveillés par Sentinel

La liste des serveurs maîtres surveillés par Sentinel est stockée dans le dictionnaire des maîtres de sentinelState Lorsque sentinelState est créé, la liste des serveurs maîtres surveillés par Sentinel commence à être initialisée.

  • La clé de masters est le nom du service principal

  • La valeur de masters est un pointeur vers sentinelRedisInstance

Le nom du serveur principal est spécifié par notre fichier de configuration sentinel.conf Le main. le nom du serveur est redis-master comme suit (voici la configuration d'un maître et de deux esclaves) :

daemonize yes
port 26379
protected-mode no
dir "/usr/local/soft/redis-6.2.4/sentinel-tmp"
sentinel monitor redis-master 192.168.211.104 6379 2
sentinel down-after-milliseconds redis-master 30000
sentinel failover-timeout redis-master 180000
sentinel parallel-syncs redis-master 1
Copier après la connexion

l'instance sentinelRedisInstance enregistre les informations du serveur Redis (le serveur maître, le serveur esclave et les informations Sentinel sont tous enregistrés dans cette instance ).

typedef struct sentinelRedisInstance {
 
    // 标识值,标识当前实例的类型和状态。如SRI_MASTER、SRI_SLVAE、SRI_SENTINEL
    int flags;
    
    // 实例名称 主服务器为用户配置实例名称、从服务器和Sentinel为ip:port
    char *name;
    
    // 服务器运行ID
    char *runid;
    
    //配置纪元,故障转移使用
 uint64_t config_epoch; 
    
    // 实例地址
    sentinelAddr *addr;
    
    // 实例判断为主观下线的时长 sentinel down-after-milliseconds redis-master 30000
    mstime_t down_after_period; 
    
    // 实例判断为客观下线所需支持的投票数 sentinel monitor redis-master 192.168.211.104 6379 2
    int quorum;
    
    // 执行故障转移操作时,可以同时对新的主服务器进行同步的从服务器数量 sentinel parallel-syncs redis-master 1
    int parallel-syncs;
    
    // 刷新故障迁移状态的最大时限 sentinel failover-timeout redis-master 180000
 mstime_t failover_timeout;
    
    // ...
} sentinelRedisInstance;
Copier après la connexion

Selon la configuration ci-dessus d'un maître et de deux esclaves, vous obtiendrez la structure d'instance suivante :

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

2.5 Créez une connexion réseau au serveur maître

Une fois la structure d'instance initialisée, Sentinel commencera à créez une connexion réseau avec le Master, dans cette étape Sentinel deviendra le client du Master. Une connexion de commande et une connexion d'abonnement seront créées entre Sentinel et Master :

  • La connexion de commande est utilisée pour obtenir des informations maître-esclave

  • La connexion d'abonnement est utilisée pour la diffusion d'informations entre Sentinel, chaque Sentinel et le maître qu'il surveille Les serveurs esclaves s'abonneront au canal _sentinel_:hello (à noter qu'aucune connexion d'abonnement n'est créée entre Sentinels, ils obtiennent les informations initiales des autres Sentinels en s'abonnant au canal _sentinel_:hello)

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Sentinel crée un connexion de commande Une fois terminé, une commande INFO est envoyée au Maître toutes les 10 secondes. Deux aspects de la connaissance peuvent être obtenus grâce aux informations de réponse du Maître :

  • Les propres informations du Maître

  • Les informations de l'esclave sous le Maître

. Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

2.6 Créer une connexion réseau avec le serveur esclave

Obtenez les informations du serveur esclave en fonction du service maître. Sentinel peut créer une connexion réseau avec l'esclave et des connexions d'abonnement seront également créées entre Sentinel et l'esclave.

SlaveVous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

当Sentinel和Slave之间创建网络连接之后,Sentinel成为了Slave的客户端,Sentinel也会每隔10秒钟通过INFO指令请求Slave获取服务器信息。 到这一步Sentinel获取到了Master和Slave的相关服务器数据。这其中比较重要的信息如下:

  • 服务器ip和port

  • 服务器运行id run id

  • 服务器角色role

  • 服务器连接状态mater_link_status

  • Slave复制偏移量slave_repl_offset(故障转移中选举新的Master需要使用)

  • Slave优先级slave_priority

此时实例结构信息如下所示:

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

2.7 创建Sentinel之间的网络连接

此时是不是还有疑问,Sentinel之间是怎么互相发现对方并且相互通信的,这个就和上面Sentinel与自己监视的主从之间订阅_sentinel_:hello频道有关了。 Sentinel会与自己监视的所有Master和Slave之间订阅_sentinel_:hello频道,并且Sentinel每隔2秒钟向_sentinel_:hello频道发送一条消息,消息内容如下:

PUBLISH sentinel:hello ",,,,,,,"

其中s代码Sentinel,m代表Master;ip表示IP地址,port表示端口、runid表示运行id、epoch表示配置纪元。

多个Sentinel在配置文件中会配置相同的主服务器ip和端口信息,因此多个Sentinel均会订阅_sentinel_:hello频道,通过频道接收到的信息就可获取到其他Sentinel的ip和port,其中有如下两点需要注意:

  • 如果获取到的runid与Sentinel自己的runid相同,说明消息是自己发布的,直接丢弃

  • 如果不相同,则说明接收到的消息是其他Sentinel发布的,此时需要根据ip和port去更新或新增Sentinel实例数据

Sentinel之间不会创建订阅连接,它们只会创建命令连接:

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

此时实例结构信息如下所示:

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

3、Sentinel工作

Sentinel最主要的工作就是监视Redis服务器,当Master实例超出预设的时限后切换新的Master实例。这其中有很多细节工作,大致分为检测Master是否主观下线、检测Master是否客观下线、选举领头Sentinel、故障转移四个步骤。

3.1 检测Master是否主观下线

Sentinel每隔1秒钟,向sentinelRedisInstance实例中的所有Master、Slave、Sentinel发送PING命令,通过其他服务器的回复来判断其是否仍然在线。

sentinel down-after-milliseconds redis-master 30000
Copier après la connexion

在Sentinel的配置文件中,当Sentinel PING的实例在连续down-after-milliseconds配置的时间内返回无效命令,则当前Sentinel认为其主观下线。Sentinel的配置文件中配置的down-after-milliseconds将会对其sentinelRedisInstance实例中的所有Master、Slave、Sentinel都适应。

无效指令指的是+PONG、-LOADING、-MASTERDOWN之外的其他指令,包括无响应

如果当前Sentinel检测到Master处于主观下线状态,那么它将会修改其sentinelRedisInstance的flags为SRI_S_DOWN

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

3.2 检测Master是否客观下线

当前Sentinel认为其下线只能处于主观下线状态,要想判断当前Master是否客观下线,还需要询问其他Sentinel,并且所有认为Master主观下线或者客观下线的总和需要达到quorum配置的值,当前Sentinel才会将Master标志为客观下线。

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

当前Sentinel向sentinelRedisInstance实例中的其他Sentinel发送如下命令:

SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>
Copier après la connexion
Copier après la connexion
  • ip:被判断为主观下线的Master的IP地址

  • port:被判断为主观下线的Master的端口

  • current_epoch:当前sentinel的配置纪元

  • runid:当前sentinel的运行id,runid

current_epoch和runid均用于Sentinel的选举,Master下线之后,需要选举一个领头Sentinel来选举一个新的Master,current_epoch和runid在其中发挥着重要作用,这个后续讲解。

接收到命令的Sentinel,会根据命令中的参数检查主服务器是否下线,检查完成后会返回如下三个参数:

  • down_state:检查结果1代表已下线、0代表未下线

  • leader_runid:返回*代表判断是否下线,返回runid代表选举领头Sentinel

  • leader_epoch:当leader_runid返回runid时,配置纪元会有值,否则一直返回0

  • 当Sentinel检测到Master处于主观下线时,询问其他Sentinel时会发送current_epoch和runid,此时current_epoch=0,runid=*

  • 接收到命令的Sentinel返回其判断Master是否下线时down_state = 1/0,leader_runid = *,leader_epoch=0

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

3.3 选举领头Sentinel

down_state返回1,证明接收is-master-down-by-addr命令的Sentinel认为该Master也主观下线了,如果down_state返回1的数量(包括本身)大于等于quorum(配置文件中配置的值),那么Master正式被当前Sentinel标记为客观下线。 此时,Sentinel会再次发送如下指令:

SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid>
Copier après la connexion
Copier après la connexion

此时的runid将不再是0,而是Sentinel自己的运行id(runid)的值,表示当前Sentinel希望接收到is-master-down-by-addr命令的其他Sentinel将其设置为领头Sentinel。这个设置是先到先得的,Sentinel先接收到谁的设置请求,就将谁设置为领头Sentinel。 发送命令的Sentinel会根据其他Sentinel回复的结果来判断自己是否被该Sentinel设置为领头Sentinel,如果Sentinel被其他Sentinel设置为领头Sentinel的数量超过半数Sentinel(这个数量在sentinelRedisInstance的sentinel字典中可以获取),那么Sentinel会认为自己已经成为领头Sentinel,并开始后续故障转移工作(由于需要半数,且每个Sentinel只会设置一个领头Sentinel,那么只会出现一个领头Sentinel,如果没有一个达到领头Sentinel的要求,Sentinel将会重新选举直到领头Sentinel产生为止)。

3.4 故障转移

故障转移将会交给领头sentinel全权负责,领头sentinel需要做如下事情:

  • 从原先master的slave中,选择最佳的slave作为新的master

  • 让其他slave成为新的master的slave

  • 继续监听旧master,如果其上线,则将其设置为新的master的slave

这其中最难的一步是如果选择最佳的新Master,领头Sentinel会做如下清洗和排序工作:

  • 判断slave是否有下线的,如果有从slave列表中移除

  • 删除5秒内未响应sentinel的INFO命令的slave

  • 删除与下线主服务器断线时间超过down_after_milliseconds * 10 的所有从服务器

  • 根据slave优先级slave_priority,选择优先级最高的slave作为新master

  • 如果优先级相同,根据slave复制偏移量slave_repl_offset,选择偏移量最大的slave作为新master

  • 如果偏移量相同,根据slave服务器运行id run id排序,选择run id最小的slave作为新master

新的Master产生后,领头sentinel会向已下线主服务器的其他从服务器(不包括新Master)发送SLAVEOF ip port命令,使其成为新master的slave。

到这里Sentinel的的工作流程就算是结束了,如果新master下线,则循环流程即可!

三、集群

1、简介

Redis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)进行数据共享,Redis集群主要实现了以下目标:

  • 在1000个节点的时候仍能表现得很好并且可扩展性是线性的。

  • 没有合并操作(多个节点不存在相同的键),这样在 Redis 的数据模型中最典型的大数据值中也能有很好的表现。

  • Sécurité en écriture, le système essaie de sauvegarder toutes les opérations d'écriture effectuées par les clients connectés à la majorité des nœuds. Cependant, Redis ne peut pas garantir que les données ne seront pas perdues du tout. La réplication maître-esclave asynchrone et synchrone entraînera de toute façon une perte de données.

  • Disponibilité, si le nœud maître est indisponible, le nœud esclave peut remplacer le nœud maître.

Concernant l'apprentissage du cluster Redis, si vous n'avez aucune expérience, il est recommandé de lire ces trois articles (série chinoise) : Tutoriel cluster Redis

Tutoriel cluster REDIS -- Informations chinoises Redis station -- Groupe d'utilisateurs Redis China (CRUG)

Spécification du cluster Redis

Spécification du cluster REDIS -- Station d'information chinoise Redis -- Groupe d'utilisateurs Redis China (CRUG)

Déploiement du pseudo-cluster esclave Redis3 maître 3

CentOS 7 Il suffit de cinq étapes simples pour installer Redis Cluster (pseudo-cluster de 3 maîtres et 3 esclaves) sur une seule machine_Blog de Li Zipin - Blog CSDN

Le contenu suivant s'appuie sur la structure à trois maîtres et trois esclaves du figure ci-dessous :

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Liste des ressources :

NodeIPslot range
Maître[0]192.168.211. :6319Emplacements 0 - 5460
Maître[1]192.168.211.107:6329Emplacements 5461 - 10922
Maître[2] 192.168.211.107:6339Emplacements 10923 - 16383
Esclave[0] 192.168.211.107:6369
Esclave[1]192.168.211.107:6349
Esclave[2] 192.168.211.107: 6359

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

2、集群内部

Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念。Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,这种结构很容易添加或者删除节点。集群的每个节点负责一部分hash槽,比如上面资源清单的集群有3个节点,其槽分配如下所示:

  • 节点 Master[0] 包含 0 到 5460 号哈希槽

  • 节点 Master[1] 包含5461 到 10922 号哈希槽

  • 节点 Master[2] 包含10923到 16383 号哈希槽

深入学习Redis集群之前,需要了解集群中Redis实例的内部结构。当某个Redis服务节点通过cluster_enabled配置为yes开启集群模式之后,Redis服务节点不仅会继续使用单机模式下的服务器组件,还会增加custerState、clusterNode、custerLink等结构用于存储集群模式下的特殊数据。

如下三个数据承载对象一定要认真看,尤其是结构中的注释,看完之后集群大体上怎么工作的,心里就有数了,嘿嘿嘿;

2.1 clsuterNode

clsuterNode用于存储节点信息,比如节点的名字、IP地址、端口信息和配置纪元等等,以下代码列出部分非常重要的属性:

typedef struct clsuterNode {

    // 创建时间
    mstime_t ctime;
    
    // 节点名字,由40位随机16进制的字符组成(与sentinel中讲的服务器运行id相同)
    char name[REDIS_CLUSTER_NAMELEN];
    
    // 节点标识,可以标识节点的角色和状态
    // 角色 -> 主节点或从节点 例如:REDIS_NODE_MASTER(主节点) REDIS_NODE_SLAVE(从节点)
    // 状态 -> 在线或下线 例如:REDIS_NODE_PFAIL(疑似下线) REDIS_NODE_FAIL(下线) 
    int flags;
    
    // 节点配置纪元,用于故障转移,与sentinel中用法类似
    // clusterState中的代表集群的配置纪元
    unit64_t configEpoch;
    
    // 节点IP地址
    char ip[REDIS_IP_STR_LEN];
    
    // 节点端口
    int port;
    
    // 连接节点的信息
    clusterLink *link;
    
    // 一个2048字节的二进制位数组
    // 位数组索引值可能为0或1
    // 数组索引i位置值为0,代表节点不负责处理槽i
    // 数组索引i位置值为1,代表节点负责处理槽i
    unsigned char slots[16384/8];
    
    // 记录当前节点处理槽的数量总和
    int numslots;
    
    // 如果当前节点是从节点
    // 指向当前从节点的主节点
    struct clusterNode *slaveof;
    
    // 如果当前节点是主节点
    // 正在复制当前主节点的从节点数量
    int numslaves;
    
    // 数组——记录正在复制当前主节点的所有从节点
    struct clusterNode **slaves;
    
} clsuterNode;
Copier après la connexion

上述代码中可能不太好理解的是slots[16384/8],其实可以简单的理解为一个16384大小的数组,数组索引下标处如果为1表示当前槽属于当前clusterNode处理,如果为0表示不属于当前clusterNode处理。clusterNode能够通过slots来识别,当前节点处理负责处理哪些槽。 初始clsuterNode或者未分配槽的集群中的clsuterNode的slots如下所示:

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

假设集群如上面我给出的资源清单,此时代表Master[0]的clusterNode的slots如下所示:

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

clusterLink是clsuterNode中的一个属性,用于存储连接节点所需的相关信息,比如套接字描述符、输入输出缓冲区等待,以下代码列出部分非常重要的属性:

typedef struct clusterState {

    // 连接创建时间
    mstime_t ctime;
   
    // TCP 套接字描述符
    int fd;
    
    // 输出缓冲区,需要发送给其他节点的消息缓存在这里
    sds sndbuf;
    
    // 输入缓冲区,接收打其他节点的消息缓存在这里
    sds rcvbuf;
    
    // 与当前clsuterNode节点代表的节点建立连接的其他节点保存在这里
    struct clusterNode *node;
} clusterState;
Copier après la connexion

2.3 custerState

每个节点都会有一个custerState结构,这个结构中存储了当前集群的全部数据,比如集群状态、集群中的所有节点信息(主节点、从节点)等等,以下代码列出部分非常重要的属性:

typedef struct clusterState {

    // 当前节点指针,指向一个clusterNode
    clusterNode *myself;
    
    // 集群当前配置纪元,用于故障转移,与sentinel中用法类似
    unit64_t currentEpoch;
    
    // 集群状态 在线/下线
    int state;
    
    // 集群中处理着槽的节点数量总和
    int size;
    
    // 集群节点字典,所有clusterNode包括自己
    dict *node;
    
    // 集群中所有槽的指派信息
    clsuterNode *slots[16384];
    
    // 用于槽的重新分配——记录当前节点正在从其他节点导入的槽
    clusterNode *importing_slots_from[16384];
    
    // 用于槽的重新分配——记录当前节点正在迁移至其他节点的槽
    clusterNode *migrating_slots_to[16384];
    
    // ...
    
} clusterState;
Copier après la connexion

在custerState有三个结构需要认真了解的,第一个是slots数组,clusterState中的slots数组与clsuterNode中的slots数组是不一样的,在clusterNode中slots数组记录的是当前clusterNode所负责的槽,而clusterState中的slots数组记录的是整个集群的每个槽由哪个clsuterNode负责,因此集群正常工作的时候clusterState的slots数组每个索引指向负责该槽的clusterNode,集群槽未分配之前指向null。

如图展示资源清单中的集群clusterState中的slots数组与clsuterNode中的slots数组:

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Redis集群中使用两个slots数组的原因是出于性能的考虑:

  • 当我们需要获取整个集群中clusterNode分别负责什么槽时,只需要查询clusterState中的slots数组即可。如果没有clusterState的slots数组,则需要遍历所有的clusterNode结构,这样显然要慢一些

  • 此外clusterNode中的slots数组也有存在的必要,因为集群中任意一个节点之间需要知道彼此负责的槽,此时节点之间只需要互相传输clusterNode中的slots数组结构就行。

第二个需要认真了解的结构是node字典,该结构虽然简单,但是node字典中存储了所有的clusterNode,这也是Redis集群中的单个节点获取其他主节点、从节点信息的主要位置,因此我们也需要注意一下。 第三个需要认真了解的结构是importing_slots_from[16384]数组和migrating_slots_to[16384],这两个数组在集群重新分片时需要使用,需要重点了解,后面再说吧,这里说的话顺序不太对。

3. Travail en cluster

3.1 Comment attribuer des créneaux ?

Le cluster Redis dispose d'un total de 16384 emplacements. Comme le montre la liste des ressources ci-dessus, nous sommes dans un cluster avec trois maîtres et trois esclaves. Chaque nœud maître est responsable de son propre emplacement correspondant. Je l'ai spécifié lors du processus de déploiement des trois maîtres et des trois esclaves ci-dessus. L'emplacement est attribué au nœud maître correspondant, car le cluster Redis lui-même a divisé les emplacements pour nous en interne. Mais si nous voulons attribuer l'emplacement nous-mêmes. , comment devrions-nous l'organiser? Nous pouvons envoyer la commande suivante au nœud pour attribuer un ou plusieurs slots au nœud actuel :

CLUSTER ADDSLOTS

Par exemple, si nous voulons attribuer les slots 0 et 1 au Master[0], nous il faut penser au Maître [0] Le nœud peut envoyer la commande suivante :

CLUSTER ADDSLOTS 0 1

Lorsque le nœud se voit attribuer un emplacement, le tableau d'emplacements du clusterNode sera mis à jour et le nœud sera mis à jour les slots dont il est responsable du traitement, qui est le tableau slots. Le message est envoyé aux autres nœuds du cluster. Après avoir reçu le message, les autres nœuds mettront à jour le tableau slots du clusterNode correspondant et le tableau solts du clusterState.

3.2 Comment ADDSLOTS est-il implémenté au sein du cluster Redis ?

C'est en fait relativement simple. Lorsque nous envoyons la commande CLUSTER ADDSLOTS à un nœud du cluster Redis, le nœud actuel confirmera d'abord si les emplacements attribués au nœud actuel ne sont pas attribués à d'autres nœuds via le tableau d'emplacements dans clusterState. Si elle a été attribuée, une exception sera levée directement et l'erreur sera renvoyée au client attribué. Si tous les emplacements attribués au nœud actuel ne sont pas attribués à d'autres nœuds, le nœud actuel s'attribue ces emplacements. Il y a trois étapes principales pour l'affectation :

  • Mettre à jour le tableau d'emplacements de clusterState, pointer les emplacements spécifiés[i] vers le clusterNode actuel

  • Mettre à jour le tableau d'emplacements de clusterNode, mettre à jour la valeur aux emplacements spécifiés[i ] à 1

  • Envoyez des messages à d'autres nœuds du cluster et envoyez le tableau d'emplacements de clusterNode à d'autres nœuds. Après avoir reçu le message, les autres nœuds mettent également à jour le tableau d'emplacements correspondant de clusterState et le tableau d'emplacements de clusterNode

.

3.3 Il y a tellement de nœuds dans le cluster, comment le client sait-il quel nœud demander ?

Avant de comprendre ce problème, vous devez d'abord connaître un point. Comment le cluster Redis calcule-t-il à quel emplacement appartient la clé actuelle ? Selon le site officiel, Redis n'utilise pas réellement d'algorithme de hachage cohérent. Au lieu de cela, chaque clé demandée est vérifiée par CRC16, puis le modulo 16384 est utilisé pour déterminer dans quel emplacement la placer.

HASH_SLOT = CRC16(key) mod 16384

A ce moment, lorsque le client se connecte pour envoyer une requête à un nœud, le nœud recevant actuellement la commande calculera d'abord l'emplacement i auquel la clé actuelle appartient via un algorithme, après le calcul, le nœud actuel déterminera si le slot i du clusterState est responsable de lui-même. S'il en est responsable, le nœud actuel répondra à la demande du client. pour le nœud actuel, il passera par les étapes suivantes :

  • Le nœud renvoie une erreur de redirection MOVED au client. Dans l'erreur de redirection MOVED, l'IP et le port calculés du clusterNode qui gère correctement la clé seront renvoyés. au client

  • Lorsque le client reçoit l'erreur de redirection MOVED renvoyée par le nœud, la commande sera transmise au nœud correct en fonction de l'adresse IP et du port. L'ensemble du processus est transparent pour le programmeur et est complété conjointement par le. serveur et client du cluster Redis.

3.4 Que faire si je souhaite réattribuer l'emplacement attribué au nœud A vers le nœud B ?

Cette question couvre en fait de nombreux problèmes, comme la suppression de certains nœuds dans le cluster Redis, l'ajout de nœuds, etc. Elle peut se résumer au déplacement du slot de hachage d'un nœud à un autre nœud. Et ce qui est très intéressant à propos du cluster Redis, c'est qu'il prend en charge l'allocation en ligne (non-stop), qui est officiellement appelée reconfiguration en ligne du cluster (reconfiguration en direct).

Jetons un coup d'œil aux instructions du CLUSTER avant de les mettre en œuvre. Une fois que vous aurez compris les instructions, vous pourrez les utiliser :

  • CLUSTER ADDSLOTS slot1 [slot2] … [slotN]

  • CLUSTER DELSLOTS slot1 [ slot2] … [slotN]

  • CLUSTER SETSLOT slot NODE node

  • CLUSTER SETSLOT slot MIGRATING node

  • CLUSTER SETSLOT slot IMPORTING node

CLUSTER 用于槽分配的指令主要有如上这些,ADDSLOTS 和DELSLOTS主要用于槽的快速指派和快速删除,通常我们在集群刚刚建立的时候进行快速分配的时候才使用。CLUSTER SETSLOT slot NODE node也用于直接给指定的节点指派槽。如果集群已经建立我们通常使用最后两个来重分配,其代表的含义如下所示:

  • 当一个槽被设置为 MIGRATING,原来持有该哈希槽的节点仍会接受所有跟这个哈希槽有关的请求,但只有当查询的键还存在原节点时,原节点会处理该请求,否则这个查询会通过一个 -ASK 重定向(-ASK redirection)转发到迁移的目标节点。

  • 当一个槽被设置为 IMPORTING,只有在接受到 ASKING 命令之后节点才会接受所有查询这个哈希槽的请求。如果客户端一直没有发送 ASKING 命令,那么查询都会通过 -MOVED 重定向错误转发到真正处理这个哈希槽的节点那里。

上面这两句话是不是感觉不太看的懂,这是官方的描述,不太懂的话我来给你通俗的描述,整个流程大致如下步骤:

  • redis-trib(集群管理软件redis-trib会负责Redis集群的槽分配工作),向目标节点(槽导入节点)发送CLUSTER SETSLOT slot IMPORTING node命令,目标节点会做好从源节点(槽导出节点)导入槽的准备工作。

  • redis-trib随即向源节点发送CLUSTER SETSLOT slot MIGRATING node命令,源节点会做好槽导出准备工作

  • redis-trib随即向源节点发送CLUSTER GETKEYSINSLOT slot count命令,源节点接收命令后会返回属于槽slot的键,最多返回count个键

  • redis-trib会根据源节点返回的键向源节点依次发送MIGRATE ip port key 0 timeout命令,如果key在源节点中,将会迁移至目标节点。

  • 迁移完成之后,redis-trib会向集群中的某个节点发送CLUSTER SETSLOT slot NODE node命令,节点接收到命令后会更新clusterNode和clusterState结构,然后节点通过消息传播槽的指派信息,至此集群槽迁移工作完成,且集群中的其他节点也更新了新的槽分配信息。

3.5 如果客户端访问的key所属的槽正在迁移怎么办?

优秀的你总会想到这种并发情况,牛皮呀!大佬们!

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

这个问题官方也考虑了,还记得我们在聊clusterState结构的时候么?importing_slots_from和migrating_slots_to就是用来处理这个问题的。

typedef struct clusterState {

    // ...
    
    // 用于槽的重新分配——记录当前节点正在从其他节点导入的槽
    clusterNode *importing_slots_from[16384];
    
    // 用于槽的重新分配——记录当前节点正在迁移至其他节点的槽
    clusterNode *migrating_slots_to[16384];
    
    // ...
    
} clusterState;
Copier après la connexion
  • 当节点正在导出某个槽,则会在clusterState中的migrating_slots_to数组对应的下标处设置其指向对应的clusterNode,这个clusterNode会指向导入的节点。

  • 当节点正在导入某个槽,则会在clusterState中的importing_slots_from数组对应的下标处设置其指向对应的clusterNode,这个clusterNode会指向导出的节点。

有了上述两个相互数组,就能判断当前槽是否在迁移了,而且从哪里迁移来,要迁移到哪里去?搞笑不就是这么简单……

此时,回到问题中,如果客户端请求的key刚好属于正在迁移的槽。那么接收到命令的节点首先会尝试在自己的数据库中查找键key,如果这个槽还没迁移完成,且当前key刚好也还没迁移完成,那就直接响应客户端的请求就行。如果该key已经不在了,此时节点会去查询migrating_slots_to数组对应的索引槽,如果索引处的值不为null,而是指向了某个clusterNode结构,那说明这个key已经被迁移到这个clusterNode了。这个时候节点不会继续在处理指令,而是返回ASKING命令,这个命令也会携带导入槽clusterNode对应的ip和port。客户端在接收到ASKING命令之后就需要将请求转向正确的节点了,不过这里有一点需要注意的地方**(因此我放个表情包在这里,方便读者注意)。**

Vous présente la réplication maître-esclave, Sentinel et le clustering dans Redis.

Comme mentionné précédemment, lorsqu'un nœud constate que l'emplacement actuel n'appartient pas à son propre traitement, il renvoie l'instruction MOVED. Alors, comment gère-t-il l'emplacement en cours de migration ? C'est à cela que sert ce cluster Redis. Lorsque le nœud découvre que l'emplacement est en cours de migration, il renvoie la commande ASKING au client. Le client recevra la commande ASKING, qui contient l'adresse IP du nœud et le port du clusterNode vers lequel l'emplacement est en cours de migration. Ensuite, le client enverra d'abord une commande ASKING au clusterNode migrant. Le but de cette commande doit être d'indiquer au nœud actuel que vous devez faire une exception pour gérer cette demande, car cet emplacement a été migré vers vous et vous ne pouvez pas. rejetez-moi directement (par conséquent, si Redis ne reçoit pas la commande ASKING, il interrogera directement le clusterState du nœud, et l'emplacement en cours de migration n'a pas été mis à jour vers le clusterState, il ne peut donc renvoyer directement MOVED, qui continuera à boucler plusieurs fois...), reçu Le nœud avec la commande ASKING exécutera de force cette requête une fois (une seule fois, et vous devrez renvoyer la commande ASKING à l'avance la prochaine fois).

4. Échec du cluster

L'échec du cluster Redis est en fait similaire à celui de Sentinel lorsque le nœud maître tombe en panne ou ne répond pas dans le délai maximum spécifié et qu'un nouveau nœud maître est réélu. les nœuds esclaves. Bien sûr, le principe est que pour chaque nœud maître du cluster Redis, nous avons configuré le nœud esclave à l'avance, sinon cela ne servira à rien... Les étapes générales sont les suivantes :

  • Dans un cluster fonctionnant normalement, chaque nœud enverra régulièrement des commandes PING aux autres nœuds. Si le nœud recevant la commande ne renvoie pas de message PONG dans le délai spécifié, le nœud actuel enverra. la commande PING au nœud recevant la commande. Les indicateurs du clusterNode sont définis sur REDIS_NODE_PFAIL n'est pas hors ligne, mais suspecté d'être hors ligne.

  • Le nœud du cluster informera les autres nœuds en envoyant des messages sur les informations d'état de chaque nœud du cluster

  • Si plus de la moitié des nœuds maîtres du cluster responsables du traitement des emplacements définissent un certain nœud maître comme suspect hors ligne, alors ce nœud sera marqué hors ligne, et le nœud définira les drapeaux du clusterNode du nœud recevant la commande sur REDIS_NODE_FAIL indique qu'il est hors ligne

  • Le nœud du cluster informe les autres nœuds en envoyant des messages, le cluster Les informations d'état de chaque nœud du nœud hors ligne. À ce stade, le nœud esclave du nœud hors ligne constate que son nœud maître a été marqué comme hors ligne, il est donc temps d'avancer. élira Créer un nœud esclave comme dernier nœud maître et exécutera le nœud sélectionné pour pointer SLAVEOF personne pour devenir le nouveau nœud maître

  • Le nouveau nœud maître révoquera les affectations d'emplacement du nœud maître d'origine et modifiera ces emplacements affectations à lui-même. C'est-à-dire modifier la structure clusterNode et la structure clusterState

  • Le nouveau nœud maître diffuse une instruction PONG au cluster. Les autres nœuds sauront qu'un nouveau nœud maître a été généré et mettront à jour la structure clusterNode et la structure clusterState.

  • le nouveau nœud maître Si une nouvelle instruction SLAVEOF est envoyée aux nœuds esclaves restants du nœud maître d'origine, ce qui en fait son propre nœud esclave

  • Le dernier nouveau nœud maître sera responsable du travail de réponse du emplacement du nœud maître d'origine

  • J'ai beaucoup écrit ici Fuzzy, si vous avez besoin de fouilles détaillées, vous devez lire cet article :

REDIS cluster-spec -- Redis Chinese Information Station -- Redis China User Group (CRUG )

http://redis.cn/topics/cluster- spec.html

Ou vous pouvez lire le livre "Redis Design and Implementation" écrit par Huang Jianhong. Ce livre est très bon, et j'ai aussi fait référence à un. beaucoup de contenu.

Pour plus de connaissances sur la programmation, veuillez visiter :
Vidéos de programmation

 ! !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:csdn.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal