Dans MySQL, le split-brain signifie que dans un système à haute disponibilité (HA), lorsque deux nœuds connectés sont déconnectés, le système qui était à l'origine un tout est divisé en deux nœuds indépendants qui commencent à rivaliser pour les ressources partagées, ce qui entraîne. chaos du système et corruption des données. Pour le système HA de services sans état, peu importe qu'il s'agisse d'un système à cerveau divisé ou non ; mais pour le système HA de services avec état (tels que MySQL), le système à cerveau divisé doit être strictement évité.
L'environnement d'exploitation de ce tutoriel : système windows7, version mysql8, ordinateur Dell G3.
Split-brain
signifie que dans un système à haute disponibilité (HA), lorsque les deux nœuds connectés sont déconnectés, le système qui était à l'origine un tout est divisé en deux nœuds indépendants, à ce moment les deux nœuds commencent à rivaliser pour les ressources partagées, ce qui entraîne le chaos du système et la corruption des données.
Dans un environnement de cluster à haute disponibilité, il existe un nœud actif et un ou plusieurs nœuds de secours qui prendront en charge le service lorsque le nœud actif tombe en panne ou cesse de répondre.
Cela semble être une hypothèse raisonnable jusqu'à ce que vous considériez les couches de réseau entre les nœuds. Que se passe-t-il si le chemin réseau entre les nœuds échoue ?
Aucun des nœuds ne peut désormais communiquer avec l'autre nœud, auquel cas le serveur de secours peut se promouvoir au rang de serveur actif sur la base du fait qu'il pense que le nœud actif est en panne. Cela fait que les deux nœuds deviennent « vivants » car chaque nœud pensera que l’autre nœud est mort. En conséquence, l’intégrité et la cohérence des données sont compromises à mesure que les données changent sur les deux nœuds. C'est ce qu'on appelle le « split-brain ».
Pour la HA des services sans état, peu importe qu'il s'agisse d'un split-brain ou non ; mais pour la HA des services avec état (tels que MySQL), le split-brain doit être strictement évité ; . (Mais certains systèmes dans les environnements de production configurent les services avec état en fonction de l'ensemble HA du service sans état, et les résultats peuvent être imaginés...)
Comment éviter la division du cerveau du cluster HA
Utilisez généralement 2 méthodes 1) Arbitrage Lorsque deux nœuds ne sont pas d’accord, l’arbitre du tiers décide quelle décision écouter. Cet arbitre peut être un service de verrouillage, un disque partagé ou autre chose.
2)clôture Lorsque l'état d'un nœud ne peut pas être déterminé, tuez l'autre nœud via la clôture pour garantir que les ressources partagées sont complètement libérées. Le principe est qu'il doit y avoir un équipement de clôture fiable.
Idéalement, aucun des éléments ci-dessus ne devrait manquer. Cependant, si le nœud n'utilise pas de ressources partagées, telles que la base de données HA basée sur la réplication maître-esclave, le périphérique fence peut être omis en toute sécurité et seul l'arbitrage est conservé. Et bien souvent, aucun dispositif de clôture n'est disponible dans notre environnement, comme dans les hôtes cloud.
Alors peut-on omettre l'arbitrage et ne conserver que le dispositif de clôture ? Ne peut pas. Parce que lorsque deux nœuds perdent le contact l’un avec l’autre, ils se protègent en même temps. Si la méthode de clôture est le redémarrage, les deux machines redémarreront en continu. Si la méthode de clôture est hors tension, le résultat peut être que deux nœuds meurent ensemble, ou qu'un seul puisse survivre. Mais si la raison pour laquelle deux nœuds perdent le contact l’un avec l’autre est que l’un des nœuds a une panne de carte réseau et que celui qui survit se trouve être le nœud défectueux, alors la fin sera tragique. Par conséquent, un simple double nœud ne peut en aucun cas empêcher la division du cerveau.
Comment mettre en œuvre la stratégie ci-dessus
Vous pouvez implémenter un ensemble de scripts conformes à la logique ci-dessus à partir de zéro. Il est recommandé d'utiliser un logiciel de cluster mature pour créer, tel que Pacemaker+Corosync+agent de ressources approprié. Keepalived ne convient pas à la haute disponibilité des services avec état. Même si l'arbitrage et les clôtures sont ajoutés à la solution, cela semble toujours gênant.
Il y a aussi quelques précautions lors de l'utilisation de la solution Pacemaker+Corosync 1) Comprendre les fonctions et les principes des agents ressources Ce n'est qu'en comprenant les fonctions et les principes de Resource Agent que vous pourrez connaître les scénarios dans lesquels il est applicable. Par exemple, l'agent de ressources de pgsql est relativement complet, prend en charge la réplication de flux synchrone et asynchrone, peut basculer automatiquement entre les deux et peut garantir que les données ne seront pas perdues lors de la réplication synchrone. Mais l'agent de ressources actuel de MySQL est très faible. Sans utiliser GTID et sans compensation de journal, il est facile de perdre des données. Il est préférable de ne pas l'utiliser et de continuer à utiliser MHA (mais veillez à vous prémunir contre le split-brain lors du déploiement. MHA).
2) S'assurer du nombre légal de voix (quorum) Le quorum peut être considéré comme le mécanisme d'arbitrage propre à Pacemkaer. La majorité de tous les nœuds du cluster sélectionnent un coordinateur, et toutes les instructions du cluster sont émises par ce coordinateur, ce qui peut parfaitement éliminer le problème de la division du cerveau. Pour que ce mécanisme fonctionne efficacement, il doit y avoir au moins 3 nœuds dans le cluster et no-quorum-policy est défini sur stop, ce qui est également la valeur par défaut. (De nombreux tutoriels définissent une politique de non-quorum à ignorer pour faciliter la démonstration. Si la même chose est faite dans l'environnement de production sans autres mécanismes d'arbitrage, c'est très dangereux !)
Mais que se passe-t-il s'il n'y a que 2 nœuds ?
但是如果你有很多双节点集群,找不到那么多用于凑数的节点,又不想把这些双节点集群拉到一起凑成一个大的集群(比如觉得不方便管理)。那么可以考虑第三种方法。 第三种方法是配置一个抢占资源,以及服务和这个抢占资源的colocation约束,谁抢到抢占资源谁提供服务。这个抢占资源可以是某个锁服务,比如基于zookeeper包装一个,或者干脆自己从头做一个,就像下面这个例子。这个例子是基于http协议的短连接,更细致的做法是使用长连接心跳检测,这样服务端可以及时检出连接断开而释放锁)但是,一定要同时确保这个抢占资源的高可用,可以把提供抢占资源的服务做成lingyig高可用的,也可以简单点,部署3个服务,双节点上个部署一个,第三个部署在另外一个专门的仲裁节点上,至少获取3个锁中的2个才视为取得了锁。这个仲裁节点可以为很多集群提供仲裁服务(因为一个机器只能部署一个Pacemaker实例,否则可以用部署了N个Pacemaker实例的仲裁节点做同样的事情。但是,如非迫不得已,尽量还是采用前面的方法,即满足Pacemaker法定票数,这种方法更简单,可靠。
--------------------------------------------------------------keepalived的脑裂问题----------------------------------------------
1)解决keepalived脑裂问题
检测思路:正常情况下keepalived的VIP地址是在主节点上的,如果在从节点发现了VIP,就设置报警信息。脚本(在从节点上)如下:
[root@slave-ha ~]# vim split-brainc_check.sh #!/bin/bash # 检查脑裂的脚本,在备节点上进行部署 LB01_VIP=192.168.1.229 LB01_IP=192.168.1.129 LB02_IP=192.168.1.130 while true do ping -c 2 -W 3 $LB01_VIP &>/dev/null if [ $? -eq 0 -a `ip add|grep "$LB01_VIP"|wc -l` -eq 1 ];then echo "ha is brain." else echo "ha is ok" fi sleep 5 done 执行结果如下: [root@slave-ha ~]# bash check_split_brain.sh ha is ok ha is ok ha is ok ha is ok 当发现异常时候的执行结果: [root@slave-ha ~]# bash check_split_brain.sh ha is ok ha is ok ha is ok ha is ok ha is brain. ha is brain.
2)曾经碰到的一个keepalived脑裂的问题(如果启用了iptables,不设置"系统接收VRRP协议"的规则,就会出现脑裂)
曾经在做keepalived+Nginx主备架构的环境时,当重启了备用机器后,发现两台机器都拿到了VIP。这也就是意味着出现了keepalived的脑裂现象,检查了两台主机的网络连通状态,发现网络是好的。然后在备机上抓包:
[root@localhost ~]# tcpdump -i eth0|grep VRRP tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 22:10:17.146322 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:17.146577 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:17.146972 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:18.147136 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:18.147576 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:25.151399 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:25.151942 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:26.151703 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:26.152623 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:27.152456 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:27.153261 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:28.152955 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:28.153461 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:29.153766 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:29.155652 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:30.154275 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:30.154587 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:31.155042 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:31.155428 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:32.155539 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:32.155986 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:33.156357 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:33.156979 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 22:10:34.156801 IP 192.168.1.96 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 50, authtype simple, intvl 1s, length 20 22:10:34.156989 IP 192.168.1.54 > vrrp.mcast.net: VRRPv2, Advertisement, vrid 51, prio 160, authtype simple, intvl 1s, length 20 备机能接收到master发过来的VRRP广播,那为什么还会有脑裂现象? 接着发现重启后iptables开启着,检查了防火墙配置。发现系统不接收VRRP协议。 于是修改iptables,添加允许系统接收VRRP协议的配置: -A INPUT -i lo -j ACCEPT ----------------------------------------------------------------------------------------- 我自己添加了下面的iptables规则: -A INPUT -s 192.168.1.0/24 -d 224.0.0.18 -j ACCEPT #允许组播地址通信 -A INPUT -s 192.168.1.0/24 -p vrrp -j ACCEPT #允许VRRP(虚拟路由器冗余协)通信 ----------------------------------------------------------------------------------------- 最后重启iptables,发现备机上的VIP没了。 虽然问题解决了,但备机明明能抓到master发来的VRRP广播包,却无法改变自身状态。只能说明网卡接收到数据包是在iptables处理数据包之前发生的事情。
3)预防keepalived脑裂问题
1)可以采用第三方仲裁的方法。由于keepalived体系中主备两台机器所处的状态与对方有关。如果主备机器之间的通信出了网题,就会发生脑裂,此时keepalived体系中会出现双主的情况,产生资源竞争。 2)一般可以引入仲裁来解决这个问题,即每个节点必须判断自身的状态。最简单的一种操作方法是,在主备的keepalived的配置文件中增加check配置,服务器周期性地ping一下网关,如果ping不通则认为自身有问题 。 3)最容易的是借助keepalived提供的vrrp_script及track_script实现。如下所示:
# vim /etc/keepalived/keepalived.conf ...... vrrp_script check_local { script "/root/check_gateway.sh" interval 5 } ...... track_script { check_local } 脚本内容: # cat /root/check_gateway.sh #!/bin/sh VIP=$1 GATEWAY=192.168.1.1 /sbin/arping -I em1 -c 5 -s $VIP $GATEWAY &>/dev/null check_gateway.sh 就是我们的仲裁逻辑,发现ping不通网关,则关闭keepalived service keepalived stop。
4)推荐自己写脚本
写一个while循环,每轮ping网关,累计连续失败的次数,当连续失败达到一定次数则运行service keepalived stop关闭keepalived服务。如果发现又能够ping通网关,再重启keepalived服务。最后在脚本开头再加上脚本是否已经运行的判断逻辑,将该脚本加到crontab里面。
【相关推荐:mysql视频教程】
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!