【Redis】记录一次K8S存储故障导致Redis集群拓扑异常的修复过程

文章目录

  • 背景
  • 处理新节点
  • 遗忘旧节点

背景

集群部署在K8S环境内,存储使用的localpv,有一台K8S主机节点磁盘故障,导致在该节点上的redis节点均出现故障,主要表现为持久化失败、集群拓扑异常,持久化失败可以临时关闭RDB和AOF持久化、等挂载好新的硬盘后,重新创建pvc进行恢复,经过观察,这些redis节点恢复后,operator并不能完成集群自愈,需要手动干预,主要表现为:集群拓扑异常:故障的节点没有被清理掉、新的节点没有以正常的角色加入到集群中。

集群是一个3主3从的规模,3个master,每个master一个slave,这个集群中故障的Pod,在创建pvc后,进行过重启操作,导致现在的拓扑,有4个正常的master,一个无效的节点,原因是恢复的节点没有以slave的角色加入到集群,且集群没有forget掉之前故障的节点

【Redis】记录一次K8S存储故障导致Redis集群拓扑异常的修复过程_第1张图片

处理新节点

从新的节点上看,没有无效的节点

【Redis】记录一次K8S存储故障导致Redis集群拓扑异常的修复过程_第2张图片

处理新节点比较简单,只需要对比下哪个master没有slave,将该节点设置为这个master的从节点即可:

【Redis】记录一次K8S存储故障导致Redis集群拓扑异常的修复过程_第3张图片

执行完命令之后,其他的节点上能看到该节点的角色变了

【Redis】记录一次K8S存储故障导致Redis集群拓扑异常的修复过程_第4张图片

监控中的拓扑也正常了,现在这种情况,集群是可以正常工作的,但是强迫症,必须要清除掉这个无效的节点。

【Redis】记录一次K8S存储故障导致Redis集群拓扑异常的修复过程_第5张图片

遗忘旧节点

如果逐台执行cluster forget来遗忘这个无效的节点,由于集群之间会进行通信,同步拓扑信息,如果不是很快同事执行该操作,最后是无法保证成功的,所以写了个脚本,来模拟同时执行:

bath-forget-nodes.sh

#!/bin/bash

set -e

# 查出所有正常的节点(排除状态为fail的),需要在这些节点上执行forget操作 
nodes_addrs=$(redis-cli -a $3 -h $1 -p $2 cluster nodes|grep -v fail| awk '{print $2}')
echo " -------------normal cluster nodes -----------------"
echo " $nodes_addrs "  
echo " --------------------------------------------"  
for addr in ${nodes_addrs[@]}; do
    host=${addr%:*}
    port=${addr#*:}
    # 查出所有需要forget的节点
    del_nodeids=$(redis-cli -a $3 -h $host -p $port cluster nodes|grep -E 'handshake|fail'| awk '{print $1}')
    for nodeid in ${del_nodeids[@]}; do
        echo " -------------delete nodes info -----------------------"  
        echo "delete from host: $host $port, delete node id: $nodeid "
        echo " ------------------------------------------------------"   
        # 执行forget            
        redis-cli -a $3 -h $host -p $port cluster forget $nodeid
    done
done

一共是需要3个参数,IP、port、密码,最好先把执行forget的一行注释掉,看看输出是否符合预期。

【Redis】记录一次K8S存储故障导致Redis集群拓扑异常的修复过程_第6张图片

执行完之后,每个节点的拓扑都恢复正常了:

【Redis】记录一次K8S存储故障导致Redis集群拓扑异常的修复过程_第7张图片

大公告成,虽然是比较简单的操作,还是记录一下,好记性不如烂笔头。

你可能感兴趣的:(Redis,redis,kubernetes,运维开发)