Les instances Redis sont toutes des nœuds maîtres par défaut, nous devons donc modifier certaines configurations pour construire une architecture maître-esclave. L'architecture maître-esclave de Redis est relativement simple à construire. Construire une architecture maître-esclave, que nous présenterons plus tard. Avant de l'introduire, il faut d'abord comprendre les caractéristiques de l'architecture maître-esclave : Dans l'architecture maître-esclave, il y a un nœud maître (maître) et au moins un esclave. (esclave) et que la réplication des données est unidirectionnelle, elle ne peut être copiée que du nœud maître vers le nœud esclave, et non du nœud esclave vers le nœud maître.
Il existe trois façons d'établir l'architecture maître-esclave :
Ajoutez la commande slaveof {masterHost} {masterPort} au fichier de configuration Redis.conf, et elle prendra effet au démarrage de l'instance Redis.
Ajoutez le paramètre --slaveof {masterHost} {masterPort} après la commande de démarrage redis-server
Utilisez la commande directement dans la fenêtre interactive redis-cli : slaveof. {masterHost} {masterPort}
Les trois architectures maître-esclave Redis ci-dessus peuvent être construites de l'une de ces manières. Nous allons démontrer la première méthode et essayer les deux autres par vous-même. Puisqu'il s'agit d'une démonstration, nous le ferons. démarrez deux instances Redis localement au lieu de démarrer des instances Redis sur plusieurs machines. Maintenant, nous préparons une instance de nœud maître avec le port 6379 et une instance de nœud esclave avec le port 6480. Le fichier de configuration de l'instance Redis du port 6480 est nommé 6480.conf et ajoute le fichier de configuration de l'instance Redis. instruction slaveof dedans. Ajoutez l’instruction suivante à la fin du fichier de configuration.
slaveof 127.0.0.1 6379
Démarrez respectivement deux instances Redis. Après le démarrage, elles établiront automatiquement une relation maître-esclave. Concernant le principe derrière cela, nous en parlerons en détail plus tard, vérifions si notre architecture maître-esclave est construite avec succès. Ajoutez d'abord une nouvelle donnée sur le nœud maître 6379 :
Le nœud maître ajoute des données
Ensuite, récupérez les données sur le nœud esclave 6480 :
Le nœud esclave récupère les données
Vous pouvez voir que nous sommes sur le nœud esclave La nouvelle valeur ajoutée sur le nœud maître a été obtenue avec succès, indiquant que l'architecture maître-esclave a été établie avec succès. Nous utilisons la commande info replication pour visualiser les informations des deux nœuds. aux informations du nœud maître.
Réplication des informations principales
Vous pouvez voir que le rôle d'instance du port 6379 est maître, qu'une instance est connectée et d'autres informations en cours d'exécution. Jetons un coup d'œil aux informations d'instance Redis du port 6480.
réplication des informations esclaves
Vous pouvez observer que les deux nœuds enregistrent les informations sur les objets l'un avec l'autre, et ces informations seront utilisées lors de la réplication des données. Une chose doit être expliquée ici : par défaut, le nœud esclave est en lecture seule et ne prend pas en charge l'écriture. Il n'est pas recommandé d'activer l'écriture. Nous pouvons le vérifier et écrire une donnée sur l'instance 6480.
127.0.0.1:6480> set x 3 (error) READONLY You can't write against a read only replica. 127.0.0.1:6480>
L'invite est en lecture seule et ne prend pas en charge les opérations d'écriture. Bien sûr, nous pouvons également modifier la configuration. L'élément de configuration réplique-lecture seule oui dans le fichier de configuration est utilisé pour contrôler la lecture seule à partir du serveur. Pourquoi ne peut-il être qu'en lecture seule ? Parce que nous savons que la réplication est unidirectionnelle, les données ne peuvent être envoyées du maître au nœud esclave que si l'écriture est activée sur le nœud esclave, alors les données du nœud esclave sont modifiées. Le nœud maître ne peut pas le détecter et les données du nœud esclave ne peuvent pas être copiées sur le nœud maître, cela entraînerait une incohérence des données, il est donc recommandé que le nœud esclave soit en lecture seule.
La déconnexion de l'architecture maître-esclave est également la commande slaveof. L'exécution de la commande slaveof no one sur le nœud esclave peut déconnecter la relation suivante du nœud maître. Nous exécutons slaveof no. sur le nœud 6480, une commande.
127.0.0.1:6480> slaveof no one OK 127.0.0.1:6480> info replication # Replication role:master connected_slaves:0 master_replid:a54f3ba841c67762d6c1e33456c97b94c62f6ac0 master_replid2:e5c1ab2a68064690aebef4bd2bd4f3ddfba9cc27 master_repl_offset:4367 second_repl_offset:4368 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:4367 127.0.0.1:6480>
Après l'exécution de la commande slaveof no one, le rôle du nœud 6480 a été immédiatement restauré en maître. Jetons un coup d'œil et il est toujours connecté à l'instance 6379. Nous avons ajouté une nouvelle clé-valeur sur le nœud 6379.
127.0.0.1:6379> set y 3 OK
obtenir y sur le nœud 6480
127.0.0.1:6480> get y (nil) 127.0.0.1:6480>
ne peut pas obtenir y sur le nœud 6480, car le nœud 6480 a été déconnecté du nœud 6379 et il n'y a pas de relation maître-esclave. La commande slaveof peut non seulement se déconnecter, mais aussi. également pour changer de serveur maître, utilisez la commande slaveof {newMasterIp} {newMasterPort}. Laissez 6379 devenir le nœud esclave de 6480. Exécutez la commande slaveof 127.0.0.1 6480 sur le nœud 6379. Jetons un coup d'œil à la réplication des informations de 6379. .
127.0.0.1:6379> info replication # Replication role:slave master_host:127.0.0.1 master_port:6480 master_link_status:up master_last_io_seconds_ago:2 master_sync_in_progress:0 slave_repl_offset:4367 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:99624d4b402b5091552b9cb3dd9a793a3005e2ea master_replid2:0000000000000000000000000000000000000000 master_repl_offset:4367 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:4368 repl_backlog_histlen:0 127.0.0.1:6379>
Le rôle du nœud 6379 est déjà esclave, et le nœud maître est 6480. Nous pouvons regarder la réplication des informations du nœud 6480.
127.0.0.1:6480> info replication # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6379,state=online,offset=4479,lag=1 master_replid:99624d4b402b5091552b9cb3dd9a793a3005e2ea master_replid2:a54f3ba841c67762d6c1e33456c97b94c62f6ac0 master_repl_offset:4479 second_repl_offset:4368 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:4479 127.0.0.1:6480>
Il y a 6379 informations sur le nœud esclave sur le nœud 6480. On peut voir que la commande slaveof nous a aidé à terminer le changement de serveur maître.
redis 的主从架构好像很简单一样,我们就执行了一条命令就成功搭建了主从架构,并且数据复制也没有问题,使用起来确实简单,但是这背后 redis 还是帮我们做了很多的事情,比如主从服务器之间的数据同步、主从服务器的状态检测等,这背后 redis 是如何实现的呢?接下来我们就一起看看。
我们执行完 slaveof 命令之后,我们的主从关系就建立好了,在这个过程中, master 服务器与 slave 服务器之间需要经历多个步骤,如下图所示:
redis 复制原理
slaveof 命令背后,主从服务器大致经历了七步,其中权限验证这一步不是必须的,为了能够更好的理解这些步骤,就以我们上面搭建的 redis 实例为例来详细聊一聊各步骤。
在 6480 的客户端向 6480 节点服务器发送 slaveof 127.0.0.1 6379 命令时,我们会立马得到一个 OK。
127.0.0.1:6480> slaveof 127.0.0.1 6379 OK 127.0.0.1:6480>
这时候数据复制工作并没有开始,数据复制工作是在返回 OK 之后才开始执行的,这时候 6480 从节点做的事情是将给定的主服务器 IP 地址 127.0.0.1 以及端口 6379 保存到服务器状态的 masterhost 属性和 masterport 属性里面。
在 slaveof 命令执行完之后,从服务器会根据命令设置的 IP 地址和端口,跟主服务器创建套接字连接, 如果从服务器能够跟主服务器成功的建立 socket 连接,那么从服务器将会为这个 socket 关联一个专门用于处理复制工作的文件事件处理器,这个处理器将负责后续的复制工作,比如接受全量复制的 RDB 文件以及服务器传来的写命令。同样主服务器在接受从服务器的 socket 连接之后,将为该 socket 创建一个客户端状态,这时候的从服务器同时具有服务器和客户端两个身份,从服务器可以向主服务器发送命令请求而主服务器则会向从服务器返回命令回复。
从服务器与主服务器连接成功后,做的第一件事情就是向主服务器发送一个 ping 命令,发送 ping 命令主要有以下目的:
检测主从之间网络套接字是否可用
检测主节点当前是否可接受处理命令
在发送 ping 命令之后,正常情况下主服务器会返回 pong 命令,接受到主服务器返回的 pong 回复之后就会进行下一步工作,如果没有收到主节点的 pong 回复或者超时,比如网络超时或者主节点正在阻塞无法响应命令,从服务器会断开复制连接,等待下一次定时任务的调度。
从服务器在接收到主服务器返回的 pong 回复之后,下一步要做的事情就是根据配置信息决定是否需要身份验证:
如果从服务器设置了 masterauth 参数,则进行身份验证
如果从服务器没有设置 masterauth 参数,则不进行身份验证
在需要身份验证的情况下,从服务器将就向主服务器发送一条 auth 命令,命令参数为从服务器 masterauth 选项的值,举个例子,如果从服务器的配置里将 masterauth 参数设置为:123456,那么从服务器将向主服务器发送 auth 123456 命令,身份验证的过程也不是一帆风顺的,可能会遇到以下几种情况:
从服务器通过 auth 命令发送的密码与主服务器的 requirepass 参数值一致,那么将继续进行后续操作,如果密码不一致,主服务将返回一个 invalid password 错误
如果主服务器没有设置 requirepass 参数,那么主服务器将返回一个 no password is set 错误
所有的错误情况都会令从服务器中止当前的复制工作,并且要从建立 socket 开始重新发起复制流程,直到身份验证通过或者从服务器放弃执行复制为止。
Une fois l'authentification passée, le serveur esclave exécutera la commande d'écoute REPLCONF et enverra le numéro de port d'écoute du serveur esclave au serveur maître. Par exemple, dans notre exemple, le port que le serveur esclave écoute est 6480, puis le serveur esclave enverra la commande REPLCONF d'écoute 6480 au serveur maître. Une fois que le serveur maître aura reçu cette commande, il enregistrera le numéro de port. dans le statut client correspondant au serveur esclave. L'attribut slave_listening_port est la valeur du port que nous voyons dans la réplication des informations du serveur maître.
La réplication des données est la partie la plus compliquée. Elle est complétée par la commande psync. vers le serveur maître Une commande psync est utilisée pour la synchronisation des données. Avant la version redis 2.8, la commande sync était utilisée. En plus des différentes commandes, il existe également de grandes différences dans les méthodes de réplication. Avant la version redis 2.8, la réplication complète. a été utilisé.C'est bon pour Le nœud maître et le réseau entraîneront beaucoup de surcharge. Après la version 2.8 de Redis, la synchronisation des données sera divisée en synchronisation complète et synchronisation partielle.
Copie complète : Généralement utilisée dans le scénario de copie initiale, qu'il s'agisse d'une ancienne ou d'une nouvelle version de redis, une copie complète sera effectuée lors de la première connexion du serveur esclave au service principal.Il enverra toutes les données du nœud maître au nœud esclave en même temps. Lorsque les données sont volumineuses, cela entraînera une surcharge importante sur le nœud maître et le réseau. Les premières versions de Redis ne sont prises en charge que. réplication complète, qui n'est pas une réplication de données efficace. Méthode
Réplication partielle : utilisée pour gérer les scénarios de perte de données causées par des interruptions du réseau et d'autres raisons dans la réplication maître-esclave. Lorsque le nœud esclave est à nouveau connecté au nœud maître, si les conditions le permettent, le nœud maître renverra les données perdues au nœud esclave. Étant donné que les données rééditées sont beaucoup plus petites que la quantité totale de données, elles peuvent effectivement éviter la surcharge excessive d'une copie complète. La copie partielle est une optimisation majeure de l'ancienne version de la copie, évitant efficacement une copie complète inutile
#🎜🎜. ## 🎜🎜##🎜🎜 #
offset : Le décalage des données actuellement copiées à partir du nœudLes nœuds maître et esclave participant à la réplication conserveront leur propres décalages de réplication respectivement : le serveur maître envoie des données au serveur esclave à chaque fois. Lorsque N octets de données sont transmis, N est ajouté à la valeur de son propre décalage. Chaque fois que le serveur esclave reçoit N octets de données transmis par le serveur maître. , N est ajouté à sa propre valeur de décalage. En comparant les décalages de réplication des serveurs maître et esclave, vous pouvez savoir si les données des serveurs maître et esclave sont cohérentes. Si les décalages des serveurs maître et esclave sont toujours les mêmes, alors les données maître et esclave sont cohérentes. Au contraire, si les décalages des serveurs maître et esclave sont cohérents, si le montant du transfert n'est pas le même, cela signifie que les serveurs maître et esclave ne sont pas dans un état de données cohérent. Par exemple, lorsqu'il existe plusieurs serveurs esclaves. , un certain serveur se déconnecte pendant le processus de transmission, comme le montre la figure suivante : #🎜 🎜#
offset incohérence
Depuis esclave le serveur A a été déconnecté pour des raisons de réseau lors de la transmission des données, le décalage était incohérent avec le serveur maître, puis lorsque le serveur esclave A redémarre et se connecte avec succès au serveur maître, il renvoie la commande psync au serveur maître à ce moment. , la réplication des données doit-elle être effectuée en totalité ou en partie ? Si une réplication partielle est effectuée, comment le maître compense-t-il la déconnexion de l'esclave A ? Qu'en est-il des données perdues pendant cette période ? Les réponses à ces questions se trouvent dans la copie ? tampon de retard.
2. Tampon du backlog de réplication
Le tampon du backlog de réplication est une file d'attente de longueur fixe enregistrée sur le nœud maître. La taille par défaut est de 1 Mo. . Il est créé lorsque le nœud maître a un nœud esclave connecté. Lorsque le nœud maître répond à une commande d'écriture, il enverra non seulement la commande au nœud esclave, mais l'écrira également dans le tampon du backlog de réplication, comme indiqué dans le. figure ci-dessous. :
Replication Backlog Buffer
Par conséquent, le tampon de réplication du serveur principal stockera une partie des données récemment enregistrées. commande d'écriture propagée, et le tampon du backlog de copie enregistre le décalage de copie correspondant pour chaque octet de la file d'attente. Ainsi, lorsque le serveur esclave se reconnecte au serveur maître, le serveur esclave envoie son décalage de réplication au serveur maître via la commande psync. Le serveur maître utilisera ce décalage de réplication pour décider quelle opération de synchronisation des données effectuer sur le serveur esclave : # 🎜🎜#
Si les données après le décalage de réplication du serveur esclave existent toujours dans le tampon du backlog de réplication, le serveur maître effectuera des opérations de réplication partielle sur le serveur esclave#🎜🎜 #
如果从服务器的复制偏移量之后的数据不存在于复制积压缓冲区里面,那么主服务器将对从服务器执行全量复制操作
3、服务器运行ID
每个 Redis 节点启动后都会动态分配一个 40 位的十六进制字符串作为运行 ID,运行 ID 的主要作用是用来唯一识别 Redis 节点,我们可以使用 info server 命令来查看
127.0.0.1:6379> info server # Server redis_version:5.0.5 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:2ef1d58592147923 redis_mode:standalone os:Linux 3.10.0-957.27.2.el7.x86_64 x86_64 arch_bits:64 multiplexing_api:epoll atomicvar_api:atomic-builtin gcc_version:4.8.5 process_id:25214 run_id:7b987673dfb4dfc10dd8d65b9a198e239d20d2b1 tcp_port:6379 uptime_in_seconds:14382 uptime_in_days:0 hz:10 configured_hz:10 lru_clock:14554933 executable:/usr/local/redis-5.0.5/src/./redis-server config_file:/usr/local/redis-5.0.5/redis.conf 127.0.0.1:6379>
这里面有一个run_id 字段就是服务器运行的ID
在熟悉这几个概念之后,我们可以一起探讨 psync 命令的运行流程,具体如下图所示:
psync 运行流程
psync 命令的逻辑比较简单,整个流程分为两步:
1、从节点发送 psync 命令给主节点,参数 runId 是当前从节点保存的主节点运行ID,参数offset是当前从节点保存的复制偏移量,如果是第一次参与复制则默认值为 -1。
2、主节点接收到 psync 命令之后,会向从服务器返回以下三种回复中的一种:
回复 +FULLRESYNC {runId} {offset}:表示主服务器将与从服务器执行一次全量复制操作,其中 runid 是这个主服务器的运行 id,从服务器会保存这个id,在下一次发送 psync 命令时使用,而 offset 则是主服务器当前的复制偏移量,从服务器会将这个值作为自己的初始化偏移量
回复 +CONTINUE:那么表示主服务器与从服务器将执行部分复制操作,从服务器只要等着主服务器将自己缺少的那部分数据发送过来就可以了
回复 +ERR:那么表示主服务器的版本低于 redis 2.8,它识别不了 psync 命令,从服务器将向主服务器发送 sync 命令,并与主服务器执行全量复制
当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。主从服务器之间的连接不会中断,因为主节点会持续发送写命令到从节点,以确保主从数据的一致性。
经过上面 7 步就完成了主从服务器之间的数据同步,由于这篇文章的篇幅比较长,关于全量复制和部分复制的细节就不介绍了,全量复制就是将主节点的当前的数据生产 RDB 文件,发送给从服务器,从服务器再从本地磁盘加载,这样当文件过大时就需要特别大的网络开销,不然由于数据传输比较慢会导致主从数据延时较大,部分复制就是主服务器将复制积压缓冲区的写命令直接发送给从服务器。
心跳检测是发生在主从节点在建立复制后,它们之间维护着长连接并彼此发送心跳命令,便以后续持续发送写命令,主从心跳检测如下图所示:
主从心跳检测
主从节点彼此都有心跳检测机制,各自模拟成对方的客户端进行通信,主从心跳检测的规则如下:
默认情况下,主节点会每隔 10 秒向从节点发送 ping 命令,以检测从节点的连接状态和是否存活。可通过修改 redis.conf 配置文件里面的 repl-ping-replica-period 参数来控制发送频率
从节点在主线程中每隔 1 秒发送 replconf ack {offset} 命令,给主节点 上报自身当前的复制偏移量,这条命令除了检测主从节点网络之外,还通过发送复制偏移量来保证主从的数据一致
主节点根据 replconf 命令判断从节点超时时间,体现在 info replication 统 计中的 lag 信息中,我们在主服务器上执行 info replication 命令:
127.0.0.1:6379> info replication # Replication role:master connected_slaves:1 slave0:ip=127.0.0.1,port=6480,state=online,offset=25774,lag=0 master_replid:c62b6621e3acac55d122556a94f92d8679d93ea0 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:25774 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:25774 127.0.0.1:6379>
可以看出 slave0 字段的值最后面有一个 lag,lag 表示与从节点最后一次通信延迟的秒数,正常延迟应该在 0 和 1 之间。如果超过 repl-timeout 配置的值(默认60秒),则判定从节点下线并断开复制客户端连接,如果从节点重新恢复,心跳检测会继续进行。
Redis 的主从拓扑结构可以支持单层或多层复制关系,根据拓扑复杂性可以分为以下三种:一主一从、一主多从、树状主从架构。
一主一从结构是最简单的复制拓扑结构,我们前面搭建的就是一主一从的架构,架构如图所示:
一主一从架构
est utilisée pour fournir une prise en charge du basculement à partir du nœud esclave lorsque le nœud maître tombe en panne lorsque la concurrence de la commande d'écriture de l'application est activée. élevé et besoins Lors de la persistance, vous pouvez activer AOF uniquement sur le nœud esclave, ce qui garantit non seulement la sécurité des données, mais évite également les interférences de performances liées à la persistance sur le nœud maître. Mais il y a ici un problème qui requiert votre attention, c'est-à-dire que lorsque le nœud maître désactive la fonction de persistance, évitez le redémarrage automatique si le nœud maître se déconnecte. Étant donné que le nœud maître n'a pas activé la fonction de persistance auparavant, l'ensemble de données sera vide après le redémarrage automatique. À ce moment, si le nœud esclave continue de copier le nœud maître, les données du nœud esclave seront également effacées et la signification. de persévérance sera perdu. L'approche sûre consiste à exécuter slaveof no one sur le nœud esclave pour déconnecter la relation de réplication avec le nœud maître, puis à redémarrer le nœud maître pour éviter ce problème.
Architecture à un maître et plusieurs esclaves L'architecture à un maître et plusieurs esclaves est également appelée topologie en étoile. L'architecture à un maître et plusieurs esclaves est illustrée dans la figure ci-dessous :
#🎜🎜. ##🎜 🎜#Architecture à un maître et à plusieurs esclaves
L'architecture à un maître et à plusieurs esclaves peut réaliser la séparation de la lecture et de l'écriture pour réduire la pression sur le serveur principal. le taux de lecture est relativement important, la commande de lecture peut être envoyée aux nœuds esclaves partageant la pression du nœud maître. Dans le même temps, si vous devez exécuter certaines commandes de lecture fastidieuses au cours du développement quotidien, telles que les clés, le tri, etc., vous pouvez les exécuter sur l'un des nœuds esclaves pour empêcher les requêtes lentes de bloquer le nœud maître et d'affecter la stabilité des services en ligne. Pour les scénarios avec une concurrence d'écriture élevée, plusieurs nœuds esclaves amèneront le nœud maître à envoyer plusieurs fois des commandes d'écriture, consommant excessivement la bande passante du réseau, augmentant également la charge sur le nœud maître et affectant la stabilité du service.
Architecture maître-esclave en arbreArchitecture maître-esclave arborescente
L'architecture maître-esclave arborescente permet le nœud esclave non seulement copie les données de la section maître, mais il peut en même temps continuer à copier vers la couche inférieure en tant que nœud maître d'autres nœuds esclaves. Il résout les défauts de l'architecture un maître-multi-esclave et introduit la couche intermédiaire de réplication, qui peut réduire efficacement la charge du nœud maître et la quantité de données qui doivent être transmises aux nœuds esclaves. Comme le montre le diagramme d'architecture, une fois les données écrites sur le nœud A, elles seront synchronisées sur les nœuds B et C. Le nœud B synchronise ensuite les données sur les nœuds D et E. Les données sont répliquées couche par couche. Afin d'éviter toute interférence avec les performances du nœud maître, le nœud maître peut adopter une structure arborescente maître-esclave lorsqu'il doit monter plusieurs nœuds esclaves pour réduire sa pression de charge.
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!