一次Redis合库以及aof踩坑记

# 概述

此文是第一次搞 redis 主从小白犯的错,大神可以忽略。记录为了让看到本博文的小白前车之鉴

# 软件资源

centOs:6.5
redis:2.8.10

# 背景

公司现有架构均是单机模式,本文仅先介绍 redis 单机踩的坑 -- 即生产应用 redis 均是单一实例,一旦实例挂掉功能就会不可用。现公司业务使用了一台实例(业务实例), 一台 session 共享实例 (session 实例)。

现需要对现有架构升级(后续会出整个架构升级的相关博客),先从最简单的 redis 开始开刀,采用主从复制,启用哨兵监听进行主从切换(后续会有相关详细博客)。

# 基本问题

  • 线上 redis 仅启用了 rdb 持久化,需要启用 AOF
  • 线上业务实例和 session 实例 keys<1W,可以把业务实例和 session 实例合并节约资源

# 踩坑记

# AOF 挖坑

已经搭建了主从模式,创建了多个 key 验证没问题,很开心 ing, 发现需要启用 AOF, 查看官方文档认为 so easy, 于是乎 改改改配置,重启服务,在主节点添加了一个 key, 主从验证通过,非常开心 ing。

【敲黑板,开始挖坑了哈】 此时模拟极端故障,把主从节点都停掉了,开始依次开启服务,发现仅有开启 AOF 后添加的一个 key,泪崩 ing。。。。

# AOF 填坑

经过多次尝试,终于找到问题

问题解析:redis 运行一段时间后 再开启 AOF,AOF 持久化文件是个空文件,它只会追加开启 AOF 后的操作记录,开启 AOF 之前的操作均不会记录,所以我挖坑过程中,开启 AOF 后没有对那些旧 key 做过任何操作,导致没有记录到旧 key 的操作,所有再次启动时,仅仅恢复了开启 AOF 后操作的 key

解决方案:运行了一段时间的 redis,才开启 AOF 一定要记得先对实例进行一次 AOF 持久化,即持久化一下开启 AOF 持久化之前的数据

# 合库挖坑

因为要把 session 实例和业务实例做一次数据合并,太懒,不想写脚本做 redis 数据迁移。。想到了 AOF 持久化文件,将两个实例的 AOF 文件做一次合并,然后重启服务不就可以做合库操作了吗?

【敲黑板,开始挖坑了哈】

业务实例的 AOF 文件内容如下

img

session 实例的 AOF 文件内容如下:

img

把 session 实例 AOF 文件内容复制到业务实例 AOF 中,内容如下:

img

此处文件本身最后还有一个 25 行的空行, 本人洁癖,很开心的删掉了。

把文件放到服务器替换 AOF 文件,重启 redis 服务

img

报出了 AOF 损坏的错误

# 合库填坑

根据提示执行了修复命令,查看修复后的文件和我合并文件,发现最后一条命令自行修复删除了,推断是最后一条命令有问题

问题解析:由于本人把最后的空行删除了,导致 AOF 检验失败,查看 AOF 文件格式,推断出那个空行是 redis 的标识行,专门用来对新命令做追加操作。

解决方案:加上最后一行换行符

实践证明:

手 -- 贱是要付出代价的!!!

手 -- 贱是要付出代价的!!!

手 -- 贱是要付出代价的!!!

# 补充: redis 迁移方案

整理一下常用的几种 redis 迁移的方案,分别对应不同的场景。

  • 备份 / 拷贝 / 重启
  • redis-dump
  • 客户端

备份和拷贝

利用 redis 的持久化功能,redis 重启的时候,会自动从硬盘的持久化文件中读取数据再恢复到内存中。利用这里原理,把 redis2 的持久化备份
替换成 redis1 的,然后重启 redis2,它就会从硬盘持久化文件恢复到内存,这样一来 redis2 就跟 redis1 一样了

要使用这个方案,就必须了解 redis 的持久化,redis 的持久化方案有 2 种,rdb 模式和 aof 模式:

  • rdb 保存整个 redis 的数据
  • aof 保存成 redis 可以执行的命令

rdb 覆盖过去之后,新的 redis 数据就没了,毕竟是覆盖操作。而 aof 因为是保存的命令,只是在新的 redis 上重新执行了一遍,所以不会覆盖新 redis 上的数据。 简单来说如果需要保留新 redis 的数据,可以使用 aof。