Maison >base de données >Redis >Qu'est-ce qu'un cluster ? Pourquoi Cluster est-il nécessaire dans Redis ?

Qu'est-ce qu'un cluster ? Pourquoi Cluster est-il nécessaire dans Redis ?

青灯夜游
青灯夜游avant
2021-09-24 19:55:423232parcourir

Qu'est-ce que le cluster ? Pourquoi Cluster est-il nécessaire dans Redis ? Cet article vous amènera à en savoir plus sur le cluster Cluster et à parler de la quantité de données que le cluster Cluster peut prendre en charge. J'espère qu'il vous sera utile !

Qu'est-ce qu'un cluster ? Pourquoi Cluster est-il nécessaire dans Redis ?

Cet article fournira un démantèlement en profondeur de divers aspects du cluster tels que les nœuds, l'attribution des emplacements, l'exécution des commandes, le re-sharding, le pilotage, le basculement et les messages. [Recommandations associées : Tutoriel vidéo Redis]

Redis 集群原理总览

Le but est de maîtriser qu'est-ce que Cluster ? Principe de partitionnement du cluster, principe des données de positionnement client, basculement, sélection du maître, quels scénarios utiliser le cluster, comment déployer le cluster... [toc]

Pourquoi avons-nous besoin de Cluster

65 Frère : Frère Ma, depuis que j'ai utilisé le Sentinel Cluster pour réaliser un basculement automatique comme vous l'avez mentionné, je peux enfin être heureux avec ma petite amie et je n'ai pas peur des temps d'arrêt de Redis .Il s'est couché tard dans la nuit.

Mais j'ai récemment rencontré un terrible problème. Redis doit sauvegarder 8 millions de paires clé-valeur, occupant 20 Go de mémoire.

J'ai utilisé un hôte de mémoire de 32 Go pour le déploiement, mais la réponse Redis était parfois très lente. J'ai utilisé la commande INFO pour vérifier l'indicateur last_fork_usec (le dernier fork prenait du temps) et j'ai constaté qu'il était particulièrement élevé.

Principalement causé par le mécanisme de persistance Redis RDB. Redis lancera le processus enfant pour terminer l'opération de persistance RDB. Le temps nécessaire à l'exécution du fork est positivement lié à la quantité de données Redis.

Et lorsque Fork est exécuté, il bloquera le thread principal. En raison de la grande quantité de données, le thread principal sera bloqué trop longtemps, la réponse de Redis semble donc lente.

65 Brother : Avec l'expansion de l'échelle de l'entreprise, la quantité de données devient de plus en plus grande. Il est difficile d'étendre le matériel d'une seule instance lors de la mise à niveau de l'architecture maître-esclave, et la sauvegarde de grandes quantités de données entraînera une réponse lente. Existe-t-il un moyen de résoudre ce problème ?

Pour enregistrer de grandes quantités de données, en plus d'utiliser des hôtes à grande mémoire, nous pouvons également utiliser des clusters de découpage. Comme le dit le proverbe : « Ce que chacun ajoute rend les flammes plus brillantes. » Si une machine ne peut pas sauvegarder toutes les données, plusieurs machines doivent les partager.

L'utilisation du cluster Redis Cluster résout principalement divers problèmes de lenteur causés par un stockage de données volumineux et facilite également l'expansion horizontale.

Deux solutions correspondent aux deux solutions d'expansion pour l'augmentation des données Redis : Expansion verticale (scale up) et expansion horizontale (scale out).

  1. Extension verticale : mettez à niveau la configuration matérielle d'un seul Redis, par exemple en augmentant la capacité de mémoire, la capacité du disque et en utilisant un processeur plus puissant.
  2. Extension horizontale : augmentez le nombre d'instances Redis horizontalement, et chaque nœud est responsable d'une partie des données.

Par exemple, si vous avez besoin d'une ressource serveur avec 24 Go de mémoire et 150 Go de disque, deux options s'offrent à vous :

Quest-ce quun cluster ? Pourquoi Cluster est-il nécessaire dans Redis ?

Face à l'échelle de millions ou de dizaines de millions d'utilisateurs, une solution évolutive horizontalement Le cluster de découpage Redis sera un très bon choix.

65 Frère : Quels sont les avantages et les inconvénients de ces deux options ?

  • Le déploiement d'expansion verticale est simple, mais lorsque la quantité de données est importante et que RDB est utilisé pour assurer la persistance, cela entraînera un blocage et une réponse lente. De plus, en raison des limitations matérielles et financières, le coût de l'extension de la mémoire, telle que l'extension à la mémoire 1T, est trop élevé.
  • L'expansion horizontale facilite l'expansion sans se soucier des limites matérielles et des coûts d'une seule instance. Cependant, le découpage des clusters impliquera des problèmes de gestion distribuée de plusieurs instances. Il est nécessaire de déterminer comment distribuer raisonnablement les données entre les différentes instances, tout en permettant aux clients d'accéder correctement aux données des instances.
  • Qu'est-ce que le cluster

Le cluster Redis est une solution de base de données distribuée. Le cluster gère les données via le partitionnement (une pratique de « penser diviser pour mieux régner ») et fournit des fonctions de réplication et de basculement.

Divisez les données en 16384 emplacements, et chaque nœud est responsable d'une partie des emplacements. Les informations sur les emplacements sont stockées dans chaque nœud.

Il est décentralisé. Comme le montre la figure, le cluster se compose de trois nœuds Redis. Chaque nœud est responsable d'une partie des données de l'ensemble du cluster. La quantité de données dont chaque nœud est responsable peut être différente.

Trois nœuds sont connectés les uns aux autres pour former un cluster peer-to-peer. Ils échangent des informations de cluster entre eux via le protocole Gossip. Enfin, chaque nœud enregistre l'allocation d'emplacement des autres nœuds. Gossip协议相互交互集群信息,最后每个节点都保存着其他节点的 slots 分配情况。

开篇寄语

技术不是万能的,程序员也不是最厉害的,一定要搞清楚,不要觉得「老子天下第一」。一旦有了这个意识,可能会耽误我们的成长。

技术是为了解决问题的,如果说一个技术不能解决问题,那这个技术就一文不值。

不要去炫技,没有意义。

集群安装

点击 -> 《Redis 6.X Cluster 集群搭建》查看

一个 Redis 集群通常由多个节点(node)组成,在刚开始的时候,每个节点都是相互独立的,它们都处于一个只包含自己的集群当中,要组建一个真正可工作的集群,我们必须将各个独立的节点连接起来,构成一个包含多个节点的集群。

连接各个节点的工作可以通过 CLUSTER MEET 命令完成:CLUSTER MEET <ip> <port></port></ip>

向一个节点 node 发送 CLUSTER MEET

Message d'ouverture

CLUSTER MEETLa technologie n'est pas omnipotente et les programmeurs ne sont pas les plus puissants. Vous devez le comprendre clairement et ne pas penser "Je suis le meilleur au monde". . Une fois que nous en avons pris conscience, cela peut retarder notre croissance.

La technologie sert à résoudre les problèmes. Si une technologie ne peut pas résoudre les problèmes, alors cette technologie ne vaut rien.

Ne montrez pas vos compétences, cela n’a aucun sens.

Installation du clusterCliquez sur -> "Construction du cluster Redis 6.X" Vue

Un cluster Redis est généralement composé de plusieurs nœuds, au niveau Au début, chaque nœud est indépendant les uns des autres et ils sont dans un cluster qui ne contient qu'eux-mêmes. Pour former un cluster véritablement fonctionnel, nous devons connecter les nœuds indépendants pour former un cluster contenant plusieurs A cluster de nœuds.

Le travail de connexion des différents nœuds peut être effectué via la commande CLUSTER MEET : CLUSTER MEET <ip> <port></port></ip> .

L'envoi de la commande CLUSTER MEET à un nœud permet au nœud d'établir une liaison avec le nœud spécifié par l'adresse IP et le port. Lorsque la prise de contact réussit, le nœud transférera l'adresse IP et le port spécifiés. est ajouté au cluster où réside actuellement le nœud.

C'est comme si le nœud node disait : "Hé, frère avec ip = xx, port = xx, veux-tu rejoindre le groupe technologique "Code Byte" ? Rejoignez le cluster et vous trouverez un moyen de grandir au fur et à mesure un grand maître. Suivez " Le compte public "Ma Ge Byte" a répondu "Rejoignez le groupe", si vous êtes un frère, venez avec moi ! "

Pour les étapes détaillées de la construction du

Redis Cluster

, veuillez cliquer sur "

Lire le texte original

" dans le coin inférieur gauche de l'article ou cliquez sur -> "
    Redis 6.X Cluster Cluster Building
  • " pour afficher .Pour plus de détails officiels sur Redis Cluster, veuillez consulter:

    redis.io/topics/clus…

  • Principe de mise en œuvre du cluster

  • 65 Brother : Après le découpage des données, les données doivent être distribuées sur différentes instances. Comment correspondre entre. des données et des instances ?

À partir de Redis 3.0, la solution officielle Redis Cluster a été fournie pour implémenter des clusters de découpage, qui implémentent les règles de données et d'instances. La solution Redis Cluster utilise Hash Slot (je l'appellerai simplement Slot ensuite) pour gérer la relation de mappage entre les données et les instances.

Suivez "Code Byte" pour entrer dans le parcours d'exploration des principes de mise en œuvre du cluster...

Divisez les données en plusieurs parties et stockez-les sur différentes instances

🎜L'ensemble de la base de données du cluster est divisé en 16384 emplacements (slots), dans la base de données Chaque clé appartient à l'un de ces 16 384 emplacements, et chaque nœud du cluster peut gérer 0 ou jusqu'à 16 384 emplacements. 🎜🎜Le processus de mappage des clés et des emplacements de hachage peut être divisé en deux étapes principales : 🎜🎜🎜🎜Selon la clé de la paire clé-valeur, utilisez l'algorithme CRC16 pour calculer une valeur de 16 bits ; 🎜🎜🎜🎜Associez les 16 bits ; -valeur du bit à 16384 Effectuez modulo et obtenez un nombre de 0 à 16383 représentant l'emplacement de hachage correspondant à la clé. 🎜🎜🎜🎜Cluster permet également aux utilisateurs de forcer une clé à s'accrocher dans un emplacement spécifique en intégrant la marque de l'étiquette dans la chaîne de clé, cela peut forcer la clé à s'accrocher dans l'emplacement égal à l'emplacement où se trouve l'étiquette. 🎜🎜Mappage de l'emplacement de hachage et de l'instance Redis🎜🎜🎜65 Frère : Comment l'emplacement de hachage est-il mappé à l'instance Redis ? 🎜

Créé via cluster create dans Exemple de déploiement de cluster, Redis distribuera automatiquement 16 384 emplacements de hachage de manière égale sur l'instance de cluster, comme N nœuds, et les emplacements de hachage sur chaque nœud Nombre d'emplacements = 16 384 /N. cluster create 创建,Redis 会自动将 16384 个 哈希槽平均分布在集群实例上,比如 N 个节点,每个节点上的哈希槽数 = 16384 / N 个。

除此之外,可以通过 CLUSTER MEET 命令将 7000、7001、7002 三个节点连在一个集群,但是集群目前依然处于下线状态,因为三个实例都没有处理任何哈希槽。

可以使用 cluster addslots 命令,指定每个实例上的哈希槽个数。

65 哥:为啥要手动制定呢?

能者多劳嘛,加入集群中的 Redis 实例配置不一样,如果承担一样的压力,对于垃圾机器来说就太难了,让牛逼的机器多支持一点。

三个实例的集群,通过下面的指令为每个实例分配哈希槽:实例 1负责 0 ~ 5460 哈希槽,实例 2 负责 5461~10922 哈希槽,实例 3 负责 10923 ~ 16383 哈希槽。

redis-cli -h 172.16.19.1 –p 6379 cluster addslots 0,5460
redis-cli -h 172.16.19.2 –p 6379 cluster addslots 5461,10922
redis-cli -h 172.16.19.3 –p 6379 cluster addslots 10923,16383

键值对数据、哈希槽、Redis 实例之间的映射关系如下:

Quest-ce quun cluster ? Pourquoi Cluster est-il nécessaire dans Redis ?

Redis 键值对的 key 「码哥字节」「牛逼」经过 CRC16 计算后再对哈希槽总个数 16394 取模,模数结果分别映射到实例 1 与实例 2 上。

切记,当 16384 个槽都分配完全,Redis 集群才能正常工作

复制与故障转移

65 哥:Redis 集群如何实现高可用呢?Master 与 Slave 还是读写分离么?

Master 用于处理槽,Slave 节点则通过《Redis 主从架构数据同步》方式同步主节点数据。

当 Master 下线,Slave 代替主节点继续处理请求。主从节点之间并没有读写分离, Slave 只用作 Master 宕机的高可用备份。

Redis Cluster 可以为每个主节点设置若干个从节点,单主节点故障时,集群会自动将其中某个从节点提升为主节点。

如果某个主节点没有从节点,那么当它发生故障时,集群将完全处于不可用状态

不过 Redis 也提供了一个参数cluster-require-full-coverage可以允许部分节点故障,其它节点还可以继续提供对外访问。

比如 7000 主节点宕机,作为 slave 的 7003 成为 Master 节点继续提供服务。当下线的节点 7000 重新上线,它将成为当前 70003 的从节点。

故障检测

65 哥:在《Redis 高可用篇:Sentinel 哨兵集群原理》我知道哨兵通过监控、自动切换主库、通知客户端实现故障自动切换,Cluster 又如何实现故障自动转移呢?

一个节点认为某个节点失联了并不代表所有的节点都认为它失联了。只有当大多数负责处理 slot 节点都认定了某个节点下线了,集群才认为该节点需要进行主从切换。

Redis 集群节点采用 Gossip 协议来广播自己的状态以及自己对整个集群认知的改变。比如一个节点发现某个节点失联了 (PFail),它会将这条信息向整个集群广播,其它节点也就可以收到这点失联信息。

关于 GossipDe plus, vous pouvez utiliser la commande CLUSTER MEET pour connecter les trois nœuds 7000, 7001 et 7002 à un cluster, mais le cluster est toujours hors ligne car aucune des trois instances ne traite de hachage. fente.

Vous pouvez utiliser la commande cluster addlots pour spécifier le nombre d'emplacements de hachage sur chaque instance.

65 Frère : Pourquoi avez-vous besoin de le formuler manuellement ? 🎜🎜🎜Ceux qui en sont capables devraient travailler plus dur. Les configurations des instances Redis ajoutées au cluster sont différentes si elles supportent la même pression, ce sera trop difficile pour les machines poubelles. 🎜🎜Pour un cluster de trois instances, allouez des emplacements de hachage à chaque instance via les instructions suivantes : Instance 1 est responsable de 0 à 5 460 emplacements de hachage, Instance 2 est responsable de 5461 ~ 10922 emplacements de hachage, l'Instance 3 est responsable des emplacements de hachage 10923 ~ 16383. 🎜
GET 公众号:码哥字节
(error) MOVED 16330 172.17.18.2:6379
🎜La relation de mappage entre les données de paire clé-valeur, les emplacements de hachage et les instances Redis est la suivante : 🎜🎜Mappage des données, Slot et instances🎜🎜 Clé de paire clé-valeur Redis "codebytes" Après le Dans le calcul CRC16, le nombre total d'emplacements de hachage 16 394 est pris modulo et les résultats du module sont mappés respectivement sur l'instance 1 et l'instance 2. 🎜🎜N'oubliez pas quele cluster Redis ne peut fonctionner normalement que lorsque les 16 384 emplacements sont entièrement alloués. 🎜

Réplication et basculement

🎜65 Brother : Comment le cluster Redis atteint-il la haute disponibilité ? Le Maître et l’Esclave sont-ils encore séparés de la lecture et de l’écriture ? 🎜🎜🎜Master est utilisé pour traiter le slot, et le nœud Slave transmet le "Synchronisation des données de l'architecture maître-esclave Redis🎜 》méthode pour synchroniser les données du nœud maître. 🎜🎜Lorsque le maître se déconnecte, l'esclave continue de traiter les requêtes à la place du nœud maître. Il n'y a pas de séparation en lecture-écriture entre les nœuds maître et esclave, et l'esclave n'est utilisé que comme sauvegarde haute disponibilité en cas de panne du maître. 🎜🎜Redis Cluster peut configurer plusieurs nœuds esclaves pour chaque nœud maître. Lorsqu'un seul nœud maître échoue, le cluster promouvra automatiquement l'un des nœuds esclaves au nœud maître. 🎜🎜Si un nœud maître n'a pas de nœuds esclaves, alors en cas de panne, le cluster sera complètement indisponible. 🎜🎜Cependant, Redis fournit également un paramètre cluster-require-full-coverage qui permet à certains nœuds d'échouer et à d'autres nœuds de continuer à fournir un accès externe. 🎜🎜Par exemple, si le nœud maître 7000 tombe en panne, l'esclave 7003 devient le nœud maître et continue de fournir des services. Lorsque le nœud hors ligne 7000 reviendra en ligne, il deviendra le nœud esclave du nœud 70003 actuel. 🎜

Détection de défauts

🎜65 Brother : Dans "Redis Haute disponibilité : principe du cluster Sentinel 🎜" Je sais que Sentinel réalise un basculement automatique via la surveillance, la commutation automatique de la base de données principale et la notification des clients. Comment le Cluster réalise-t-il le basculement automatique ? 🎜🎜🎜Ce n'est pas parce qu'un nœud pense qu'un certain nœud est hors de contact que tous les nœuds pensent qu'il est hors de contact. Ce n'est que lorsque la plupart des nœuds responsables du traitement des slots déterminent qu'un nœud est hors ligne que le cluster considérera que le nœud doit effectuer une commutation maître-esclave. 🎜🎜Les nœuds du cluster Redis utilisent le protocole Gossip pour diffuser leur propre statut et les changements dans leurs connaissances de l'ensemble du cluster. Par exemple, si un nœud découvre qu'un certain nœud est perdu (PFail), il diffusera ces informations à l'ensemble du cluster et d'autres nœuds pourront également recevoir ces informations de connexion perdue. 🎜🎜À propos du protocole Gossip, vous pouvez lire un article de frère Wukong : "🎜L'invasion de virus dépend entièrement de la distribution🎜"🎜🎜Si un nœud reçoit le nombre de déconnexions d'un nœud (PFail Count) Après avoir atteint la majorité du cluster, vous pouvez marquer le nœud comme confirmé comme étant hors ligne (Échec), puis le diffuser à l'ensemble du cluster, forçant les autres nœuds à accepter également le fait que le nœud était hors ligne et à en prendre immédiatement le contrôle. du nœud perdu. 🎜

Failover

Lorsqu'un esclave constate que son nœud maître est entré dans l'état hors ligne, le nœud esclave commencera à basculer sur le nœud maître hors ligne.

  • Sélectionnez un nœud dans la liste des nœuds maître et esclave hors ligne pour devenir le nouveau nœud maître.

  • Le nouveau nœud maître révoquera toutes les attributions d'emplacements au nœud maître hors ligne et s'attribuera ces emplacements.

  • Le nouveau nœud maître diffuse un message PONG au cluster. Ce message PONG peut faire savoir immédiatement aux autres nœuds du cluster que ce nœud est passé d'un nœud esclave à un nœud maître et que ce nœud maître a pris le relais. tâche initialement effectuée par le nœud maître. Emplacement que le nœud hors ligne est responsable du traitement.

  • Le nouveau nœud maître commence à recevoir des demandes de commandes liées à l'emplacement de traitement et le basculement est terminé.

Processus d'élection du maître

65 Frère : Comment le nouveau nœud maître est-il élu ?

  • L'époque de configuration +1 du cluster est un compteur de temps automatique avec une valeur initiale de 0 et sera +1 à chaque fois qu'un basculement est effectué.

  • Le nœud esclave qui détecte que le nœud maître est hors ligne diffuse un message CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST au cluster, exigeant que tous les nœuds maîtres qui reçoivent ce message et disposent du droit de vote votent pour ce nœud esclave. CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST消息,要求所有收到这条消息、并且具有投票权的主节点向这个从节点投票。

  • 这个主节点尚未投票给其他从节点,那么主节点将向要求投票的从节点返回一条CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示这个主节点支持从节点成为新的主节点。

  • 参与选举的从节点都会接收CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK

  • Ce nœud maître n'a pas encore voté pour d'autres nœuds esclaves, alors le nœud maître renverra un message CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK au nœud esclave demandant le vote, indiquant que ce nœud maître prend en charge le nœud esclave pour devenir le nouveau nœud maître.

Tous les nœuds esclaves participant à l'élection recevront le message CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK Si les votes collectés >= (N/2) + 1 supportent, alors le nœud esclave sera élu comme nouveau maître. nœud.

Quest-ce quun cluster ? Pourquoi Cluster est-il nécessaire dans Redis ?Si aucun nœud esclave ne peut collecter suffisamment de votes de soutien dans une époque de configuration, le cluster entrera dans une nouvelle époque de configuration et l'élection aura lieu à nouveau jusqu'à ce qu'un nouveau nœud maître soit élu.

Semblables à Sentinel, les deux sont implémentés sur la base de l'algorithme Raft. Le processus est le suivant :

Est-il possible d'utiliser une table pour enregistrer la relation entre les paires clé-valeur et les instances ?

65 Frère, laissez-moi vous tester : "La solution Redis Cluster alloue des paires clé-valeur à différentes instances via des emplacements de hachage. Ce processus nécessite le calcul CRC de la clé de la paire clé-valeur et modulo le nombre total de hachage emplacements à mapper à l'instance. Si vous utilisez une table pour enregistrer directement la correspondance entre les paires clé-valeur et les instances (par exemple, la paire clé-valeur 1 est sur l'instance 2 et la paire clé-valeur 2 est sur l'instance 1). , il n'est pas nécessaire de calculer la correspondance entre la clé et l'emplacement de hachage. Recherchez simplement le tableau. Pourquoi Redis ne le fait-il pas ? "

Si vous utilisez un enregistrement de table global, si la relation entre les paires clé-valeur et les instances changent (repartagement, augmentation ou diminution de l'instance), sa surface doit être modifiée. S'il s'agit d'une opération monothread, toutes les opérations doivent être sérialisées et les performances seront trop lentes.

Le multithreading implique le verrouillage. De plus, si la quantité de données de paires clé-valeur est très importante, l'espace de stockage requis pour enregistrer les données de table de la relation entre les paires clé-valeur et les instances sera également très important.

En ce qui concerne le calcul des emplacements de hachage, bien que la relation entre les emplacements de hachage et le temps d'instance doive être enregistrée, le nombre d'emplacements de hachage est beaucoup plus petit, seulement 16 384, et la surcharge est très faible.

Comment le client localise-t-il l'instance où se trouvent les données ?

65 Brother : Comment le client détermine-t-il sur quelle instance les données accédées sont distribuées ?

L'instance Redis enverra ses informations d'emplacement de hachage à d'autres instances du cluster via le protocole Gossip, réalisant ainsi la diffusion des informations d'allocation d'emplacement de hachage.

De cette façon, chaque instance du cluster dispose d'informations sur les relations de mappage entre tous les emplacements de hachage et les instances.

Lors du découpage des données, la clé est calculée sous forme de valeur via CRC16 puis modulo 16384 pour obtenir le Slot correspondant. Cette tâche de calcul peut être exécutée lors de l'envoi d'une requête sur le client.

Redis 客户端定位数据所在节点Cependant, après avoir localisé l'emplacement, vous devez localiser davantage l'instance Redis où se trouve l'emplacement.

Lorsque le client se connecte à une instance, l'instance répond au client avec la relation de mappage entre l'emplacement de hachage et l'instance, et le client met en cache les informations de mappage entre l'emplacement de hachage et l'instance localement.

Lorsque le client fait une demande, il calculera l'emplacement de hachage correspondant à la clé, localisera l'instance où se trouvent les données via les informations de mappage d'instance d'emplacement de hachage mises en cache localement, puis enverra la demande à l'instance correspondante.

🎜🎜🎜Redistribuer les emplacements de hachage🎜🎜🎜65 Frère : Que dois-je faire si la relation de mappage entre les emplacements de hachage et les instances change en raison de nouvelles instances ou d'une redistribution de l'équilibrage de charge ? 🎜

集群中的实例通过 Gossip 协议互相传递消息获取最新的哈希槽分配信息,但是,客户端无法感知。

Redis Cluster 提供了重定向机制:客户端将请求发送到实例上,这个实例没有相应的数据,该 Redis 实例会告诉客户端将请求发送到其他的实例上

65 哥:Redis 如何告知客户端重定向访问新实例呢?

分为两种情况:MOVED 错误、ASK 错误

MOVED 错误

MOVED 错误(负载均衡,数据已经迁移到其他实例上):当客户端将一个键值对操作请求发送给某个实例,而这个键所在的槽并非由自己负责的时候,该实例会返回一个 MOVED 错误指引转向正在负责该槽的节点。

GET 公众号:码哥字节
(error) MOVED 16330 172.17.18.2:6379

该响应表示客户端请求的键值对所在的哈希槽 16330 迁移到了 172.17.18.2 这个实例上,端口是 6379。这样客户端就与 172.17.18.2:6379 建立连接,并发送 GET 请求。

同时,客户端还会更新本地缓存,将该 slot 与 Redis 实例对应关系更新正确

MOVED 指令

ASK 错误

65 哥:如果某个 slot 的数据比较多,部分迁移到新实例,还有一部分没有迁移咋办?

如果请求的 key 在当前节点找到就直接执行命令,否则时候就需要 ASK 错误响应了,槽部分迁移未完成的情况下,如果需要访问的 key 所在 Slot 正在从从 实例 1 迁移到 实例 2,实例 1 会返回客户端一条 ASK 报错信息:客户端请求的 key 所在的哈希槽正在迁移到实例 2 上,你先给实例 2 发送一个 ASKING 命令,接着发发送操作命令

GET 公众号:码哥字节
(error) ASK 16330 172.17.18.2:6379

比如客户端请求定位到 key = 「公众号:码哥字节」的槽 16330 在实例 172.17.18.1 上,节点 1 如果找得到就直接执行命令,否则响应 ASK 错误信息,并指引客户端转向正在迁移的目标节点 172.17.18.2。

ASK 错误

注意:ASK 错误指令并不会更新客户端缓存的哈希槽分配信息

所以客户端再次请求 Slot 16330 的数据,还是会先给 172.17.18.1 实例发送请求,只不过节点会响应 ASK 命令让客户端给新实例发送一次请求。

MOVED指令则更新客户端本地缓存,让后续指令都发往新实例。

集群可以设置多大?

65 哥:有了 Redis Cluster,再也不怕大数据量了,我可以无限水平拓展么?

答案是否定的,Redis 官方给的 Redis Cluster 的规模上线是 1000 个实例

65 哥:到底是什么限制了集群规模呢?

关键在于实例间的通信开销,Cluster 集群中的每个实例都保存所有哈希槽与实例对应关系信息(Slot 映射到节点的表),以及自身的状态信息。

在集群之间每个实例通过 Gossip协议传播节点的数据,Gossip 协议工作原理大概如下:

  1. 从集群中随机选择一些实例按照一定的频率发送 PING 消息发送给挑选出来的实例,用于检测实例状态以及交换彼此的信息。 PING 消息中封装了发送者自身的状态信息、部分其他实例的状态信息、Slot 与实例映射表信息。
  2. 实例接收到 PING 消息后,响应 PONG 消息,消息包含的信息跟 PING 消息一样。

集群之间通过 Gossip协议可以在一段时间之后每个实例都能获取其他所有实例的状态信息。

所以在有新节点加入,节点故障,Slot 映射变更都可以通过 PINGPONG 的消息传播完成集群状态在每个实例的传播同步。

Gossip 消息

发送的消息结构是 clusterMsgDataGossip结构体组成:

typedef struct {
    char nodename[CLUSTER_NAMELEN];  //40字节
    uint32_t ping_sent; //4字节
    uint32_t pong_received; //4字节
    char ip[NET_IP_STR_LEN]; //46字节
    uint16_t port;  //2字节
    uint16_t cport;  //2字节
    uint16_t flags;  //2字节
    uint32_t notused1; //4字节
} clusterMsgDataGossip;

所以每个实例发送一个 Gossip消息,就需要发送 104 字节。如果集群是 1000 个实例,那么每个实例发送一个 PING 消息则会占用 大约 10KB。

除此之外,实例间在传播 Slot 映射表的时候,每个消息还包含了 一个长度为 16384 bit 的 Bitmap

Chaque bit correspond à un Slot. Si la valeur = 1, cela signifie que ce Slot appartient à l'instance actuelle. Ce Bitmap occupe 2 Ko, donc un message PING fait environ 12 Ko. PING 消息大约 12KB。

PONGPING 消息一样,一发一回两个消息加起来就是 24 KB。集群规模的增加,心跳消息越来越多就会占据集群的网络通信带宽,降低了集群吞吐量。

实例的通信频率

65 哥:码哥,发送 PING 消息的频率也会影响集群带宽吧?

Redis Cluster 的实例启动后,默认会每秒从本地的实例列表中随机选出 5 个实例,再从这 5 个实例中找出一个最久没有收到 PING 消息的实例,把 PING 消息发送给该实例。

65 哥:随机选择 5 个,但是无法保证选中的是整个集群最久没有收到 PING 通信的实例,有的实例可能一直没有收到消息,导致他们维护的集群信息早就过期了,咋办呢?

这个问题问的好,Redis Cluster 的实例每 100 ms 就会扫描本地实例列表,当发现有实例最近一次收到 PONG 消息的时间 > cluster-node-timeout / 2。那么就立刻给这个实例发送 PING 消息,更新这个节点的集群状态信息。

当集群规模变大,就会进一步导致实例间网络通信延迟怎加。可能会引起更多的 PING 消息频繁发送。

降低实例间的通信开销

  • 每个实例每秒发送一条 PING消息,降低这个频率可能会导致集群每个实例的状态信息无法及时传播。
  • 每 100 ms 检测实例 PONG消息接收是否超过 cluster-node-timeout / 2,这个是 Redis 实例默认的周期性检测任务频率,我们不会轻易修改。

所以,只能修改 cluster-node-timeout的值:集群中判断实例是否故障的心跳时间,默认 15 S。

所以,为了避免过多的心跳消息占用集群宽带,将 cluster-node-timeout调成 20 秒或者 30 秒,这样 PONG 消息接收超时的情况就会缓解。

但是,也不能设置的太大。都则就会导致实例发生故障了,却要等待 cluster-node-timeout时长才能检测出这个故障,影响集群正常服务、

总结

  • 哨兵集群实现故障自动转移,但是当数据量过大导致生成 RDB 时间过长。而 Fork 执行的时候会阻塞主线程,由于数据量过大导致阻塞主线程过长,所以出现了 Redis 响应慢的表象。
  • 使用 Redis Cluster 集群,主要解决了大数据量存储导致的各种慢问题,同时也便于横向拓展。在面向百万、千万级别的用户规模时,横向扩展的 Redis 切片集群会是一个非常好的选择。
  • 集群的整个数据库被分为 16384 个槽(slot),数据库中的每个键都属于这 16384 个槽的其中一个,集群中的每个节点可以处理 0 个或最多 16384 个槽。
  • Redis 集群节点采用 Gossip 协议来广播自己的状态以及自己对整个集群认知的改变。
  • 客户端连接到集群候任何一个实例后,实例会将哈希槽与实例映射信息发送给客户端,客户端将信息保存,用于将 key 定位到对应的节点。
  • 集群并不能无限增加,由于集群通过 Gossip协议传播集群实例信息,所以通信频率是限制集群大小的主要原因,主要可以通过修改 cluster-node-timeout
  • PONG est identique au message PING La somme des deux messages envoyés et renvoyés est de 24 Ko. À mesure que la taille du cluster augmente, de plus en plus de messages de pulsation occuperont la bande passante de communication réseau du cluster et réduiront le débit du cluster.

Fréquence de communication de l'instance

65 Frère : Frère Ma, la fréquence d'envoi des messages PING affectera également la bande passante du cluster, n'est-ce pas ?

Après le démarrage de l'instance de Redis Cluster, 5 instances seront sélectionnées au hasard dans la liste des instances locales chaque seconde par défaut, puis l'instance qui n'a pas reçu le message PING depuis le plus longtemps sera trouvée dans ces 5 instances. Envoyez un message PING à cette instance.
🎜65 Brother : Sélectionnez-en 5 au hasard, mais il n'y a aucune garantie que l'instance sélectionnée sera celle qui n'a pas reçu de communication PING depuis le plus longtemps dans l'ensemble du cluster, ce qui entraîne le fait que certaines instances n'ont pas reçu le message. les informations de cluster qu'ils conservent expirent depuis longtemps. D'accord, que faire ? 🎜
🎜C'est une bonne question. Les instances du cluster Redis analyseront la liste des instances locales toutes les 100 ms. Lorsqu'une instance est trouvée, l'heure à laquelle elle a reçu pour la dernière fois un message PONG cluster-node-timeout/2. Envoyez ensuite immédiatement un message <code>PING à cette instance pour mettre à jour les informations sur l'état du cluster de ce nœud. 🎜🎜Lorsque la taille du cluster augmente, cela augmente encore le délai de communication réseau entre les instances. Peut entraîner l'envoi fréquent de davantage de messages PING. 🎜

Réduire la surcharge de communication entre les instances

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer