MENU

Redis Cluster 断电重启后恢复

April 26, 2021 • Read: 804 • 默认分类

情况描述:

redis cluster集群由三个节点服务器组成,一共6个redis实例,每个节点开启2个端口,三主三从。
断电后启动reids服务,发现redis集群不正常。

服务器重启后,集群报错:

# redis-cli -c -h ip -p 7000
ip:7000> set cc dd
(error) CLUSTERDOWN Hash slot not served

检查集群节点情况

> cluster nodes
c0767666bee76e5e0dc67f24031a3e1b574235cc :7000@17000 myself,master - 0 0 0 connected

发现集群的节点只剩一个,其余节点都不见了。

将集群节点加入:

# redis-cli --cluster add-node ip:7005 ip:7000
>>> Adding node ip:7005 to cluster ip:7000
>>> Performing Cluster Check (using node ip:7000)
M: c0767666bee76e5e0dc67f24031a3e1b574235cc ip:7000
   slots: (0 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.

这个往往是由于主node移除了,但是并没有移除node上面的slot,从而导致了slot总数没有达到16384,其实也就是slots分布不正确。所以在删除节点的时候一定要注意删除的是否是Master主节点。现在这样情况,我们先修复集群:

# redis-cli --cluster fix IP:7000

将节点加入集群:

# redis-cli --cluster add-node ip:7001 ip:7000
>>> Adding node ip:7001 to cluster ip:7000
>>> Performing Cluster Check (using node ip:7000)
M: c0767666bee76e5e0dc67f24031a3e1b574235cc ip:7000
   slots:[0-16383] (16384 slots) master
M: a98432e520af41117f5d8a81e2c0e2a430940c7e ip:7003
   slots: (0 slots) master
M: 2ff0c7ee051e26f484b6826d6aa8a5a3fbc93d17 ip:7002
   slots: (0 slots) master
M: 26bf8ce786d7c9d0bbb9d9d78978497f86fbbe0a ip:7005
   slots: (0 slots) master
M: 0a7718d2c53a16debdbfb391a7acd23a50a05faa ip:7004
   slots: (0 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node ip:7001 to make it join the cluster.
[OK] New node added correctly.

另一种情况(重新初始化集群)

重新初始化集群报错:

[ERR] Node IP:Port is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0

解决办法

  1. 先将redis 进程干掉   ps -ef | grep redis    kill pid
  2. 将每个节点下aof、rdb、nodes.conf本地备份文件删除,redis.conf   appendfilename ;
  3. 127.0.0.1:7001> flushdb #清空当前数据库(这一步可以省略) 
  4. 重新创建集群;
  5. 这种情况可能发生在每次非正常关闭redis集群的时候

为什么要删除aof、rdb、nodes.conf本地备份文件?

1、dump.rdb

dump.rdb是由Redis服务器自动生成的 默认情况下 每隔一段时间redis服务器程序会自动对数据库做一次遍历,把内存快照写在一个叫做“dump.rdb”的文件里,这个持久化机制叫做SNAPSHOT。有了SNAPSHOT后,如果服务器宕机,重新启动redis服务器程序时redis会自动加载dump.rdb,将数据库状态恢复到上一次做SNAPSHOT时的状态。

2、appendonly.aof(数据持久化)

默认情况下Redis会异步的将数据导出到磁盘上。这种模式对许多应用程序已经足够了,但是如果断电或者redis进程出问题就会导致一段时间内的更新数据丢失(取决与配置项);

这种只增文件是可选的能够提供更好的体验的数据持久化策略。

举个例子,如果使用默认的配置数据fsync策略,在服务器意外断电的情况下redis只会丢失一秒中内的更新数据,或者当redis进程出问题但操作系统运转正常时,redis只会丢失一个数据更新操作。

AOF 和 RDB 持久化方式可以同时启动并且无冲突。

如果AOF开启,启动redis时会加载aof文件,这些文件能够提供更好的保证。

3、nodes.conf

每个集群节点都有一个集群配置文件。它是由Redis节点自动创建和更新的。每个Redis集群节点都需要一个不同的集群配置文件。

注:确保在同一系统中运行的实例没有重叠的集群配置文件名。集群的配置,配置文件首次启动自动生成。

总结几点(redis重启后,master实例变为slave实例,master之前对应的slave则变为master。):

  • 1)master主节点实例最好分布在不同的服务器上,slave从节点实例也最好分布在不同的服务器上
  • 2)master主节点实例和它自己所包括的从节点实例也最好分布在不同的服务器上,不要在同一个服务器上。部署redis cluster的机器如果是虚拟机,则虚拟机最好也别部署在同一台物理宿主机上。这样做是为了避免因服务器挂掉或主从节点机器全部挂掉,导致数据丢失,集群启用失败。
  • 3)如果redis机器挂掉的数量不超过集群机器总数量的1/2,那么redis集群服务将不受影响,可以继续使用。但是节点机器重启后,则它上面的redis节点实例加入到集群中后,它上面之前的master实例变为slave实例(这个master之前对应的slave将随之变为master),也就是说重启后这个节点的两个redis实例全部变为slave了(原来是一主一从,重启后两从)。
  • 4)如果redis机器挂掉的数量超过了集群机器总数量的1/2,则不仅要重启机器的redis服务,还要重新加入到redis cluster集群,重新创建集群时,注意master和slave关系要和之前一样。
  • 5)千万注意redis cluster中的节点重启事会先从集中中踢出来,即它上面的master和slave实例会消失,master之前对应的slave变为新的master,待该节点重启,成功后会自动重新加入到集群中,并全部成为slave实例。由于节点重启期间,在从集群中踢出来到自动重新加入到集群中存在一定的时间间隔,所以集群中的节点,不能同时重启,也不能短时间内一起重启,否则会造成集群崩溃,集群数据丢失。一般而言,重启一台节点,待该节点重启后并检查成功重新加入到集群中够,再另外重启别的节点。

redis作为纯缓存服务时,数据丢失,一般对业务是无感的,不影响业务,丢失后会再次写入。但如果作为存储服务(即作为存储数据库),数据丢失则对业务影响很大。

不过一般业务场景,存储数据库会用mysql、oracle或mongodb。

- - - The END - - -
  • 文章作者:谭先生
  • 版权所有:文章转载时,注明出处即可!
  • 本站部分资源收集于网络,纯个人收藏,无商业用途,如有侵权请及时告知!
  • Last Modified: August 4, 2021
    Archives QR Code Tip
    QR Code for this page
    Tipping QR Code
    Leave a Comment

    已有 1 条评论
    1. 黎臻 黎臻     Windows 10 /    FireFox

      学习了,今天刚好遇到服务器断电重启@(真棒)

    阅读:804