概述
此文是第一次搞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文件内容如下
session实例的AOF文件内容如下:
把session实例AOF文件内容复制到业务实例AOF中,内容如下:
此处文件本身最后还有一个25行的空行, 本人洁癖,很开心的删掉了。
把文件放到服务器替换AOF文件,重启redis服务
报出了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。