文章目录
- 背景
- 处理新节点
- 遗忘旧节点
背景
集群部署在K8S环境内,存储使用的localpv,有一台K8S主机节点磁盘故障,导致在该节点上的redis节点均出现故障,主要表现为持久化失败、集群拓扑异常,持久化失败可以临时关闭RDB和AOF持久化、等挂载好新的硬盘后,重新创建pvc进行恢复,经过观察,这些redis节点恢复后,operator并不能完成集群自愈,需要手动干预,主要表现为:集群拓扑异常:故障的节点没有被清理掉、新的节点没有以正常的角色加入到集群中。
集群是一个3主3从的规模,3个master,每个master一个slave,这个集群中故障的Pod,在创建pvc后,进行过重启操作,导致现在的拓扑,有4个正常的master,一个无效的节点,原因是恢复的节点没有以slave的角色加入到集群,且集群没有forget掉之前故障的节点
处理新节点
从新的节点上看,没有无效的节点
处理新节点比较简单,只需要对比下哪个master没有slave,将该节点设置为这个master的从节点即可:
执行完命令之后,其他的节点上能看到该节点的角色变了
监控中的拓扑也正常了,现在这种情况,集群是可以正常工作的,但是强迫症,必须要清除掉这个无效的节点。
遗忘旧节点
如果逐台执行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的一行注释掉,看看输出是否符合预期。
执行完之后,每个节点的拓扑都恢复正常了:
大公告成,虽然是比较简单的操作,还是记录一下,好记性不如烂笔头。