本文记录一下 Redis 集群中节点的 AOF 文件损坏导致启动失败,以及新增节点的处理过程。
问题描述
在启动 Redis 集群时,发现其中两个服务没有启动成功,如下:
分别是6381
和 6382
端口的服务,经过调查,两个节点启动失败的原因如下:
6381
节点没有成功加入 Redis 集群,6382
节点的 AOF 文件发生了损坏。
通过 cluster nodes
看下集群节点状态,如下:
集群中只有5个节点,其中3个 master 节点,2个 slave 节点,6382
节点是启动失败状态,而 6381
端口并没有在集群中。
下面分别看下处理方案。
AOF 文件损坏
控制台中已经给出了处理方法,运行下面的命令即可:
1 | redis-check-aof --fix <filename> |
进入 6382
节点目录下,运行该命令,在对应的文件夹中,发现很多 temp-rewriteaof-xxx.aof
文件,如下:
修复成功后,节点就能成功启动了,但是控制台出现了如下的报错:
经过调查,这个报错会导致 6382
节点文件夹下生成大量 temp-rewriteaof-xxx.aof
文件,如下:
这些文件是 Redis 在执行 AOF 重写(Append-Only File Rewrite) 操作时生成的临时文件。下面来看一下为什么会出现这些文件:(来源:chatgpt)
- AOF 重写:AOF 是 Redis 用于持久化的方式之一,它会将每一个写操作(如 SET、INCR 等)记录到 AOF 文件中,确保数据的持久性。当 AOF 文件的大小超过一定阈值时,Redis 会自动触发重写操作,以压缩和减少 AOF 文件的体积。这个过程是通过生成一个临时文件来完成的,也就是 temp-rewriteaof-xxxx.aof 文件。
- 临时文件:在重写过程中,Redis 会将所有操作写入这个临时文件,重写完成后会用这个文件替换旧的 AOF 文件。
- 异常退出:如果 Redis 在 AOF 重写时崩溃或者重写操作中途被中断,这些临时文件可能不会被自动删除。这就导致了大量 temp-rewriteaof-xxxx.aof 文件的残留。
而产生这个报错的根本原因是 在进行 AOF 重写时,AOF 文件中存在未知的命令,如下:
将这段异常的指令移除,6382
节点就能正常启动了,而那些 temp-rewriteaof-xxx.aof
文件也可以移除了。
添加新的 Slave 节点
上面的 6382
节点修复完成后,再看下 Redis 集群的情况:
可以看到,6383
、6384
、6385
三个是 master 节点,而 6380
是 6383
的 slave 节点,6382
是 6385
的 slave 节点。剩余一个未知端口的节点是 6384
节点的 slave 节点,我们将这个未知的节点移除:
1 | ruby .\redis-trib.rb del-node 127.0.0.1:6381 78e3d67bae1f4705b0215ac19238dff29156c95f |
但是移除失败了:
这个节点对整个 Reids 集群并没有影响,因此不管它也可以,当然也可以在各个 Redis 节点下执行下面的命令来忽略它:
1 | cluster forget 78e3d67bae1f4705b0215ac19238dff29156c95f |
接着将 6381
节点设置为 6384
的 slave 节点,启动 6381
节点,在 redis-trib.rb
所在目录下执行如下命令:
1 | ruby .\redis-trib.rb add-node --slave --master-id c53c2ec015170e9339d87a26b9c61d9b46b901ba 127.0.0.1:6381 127.0.0.1:6384 |
这串命令的含义为:./redis-trib.rb add-node --slave --master-id {主节点id} {添加节点的ip和端口} {集群中已存在节点ip和端口}
运行之后出现了如下报错:
因为 6381
节点已经存在数据了,将该节点的 appendonly.aof
文件清空,然后再重启节点,之后重新执行命令,成功
再来通过 cluster nodes
看下集群状态:
附:redis-trib包含的命令