当前位置:首页 > 问答 > 正文

Redis重启后数据没了,咋整啊,重启恢复不起来问题分析

这个问题确实非常让人头疼,你绝对不是第一个遇到的,Redis重启后数据全没了,感觉就像停电后电脑没保存文档一样憋屈,别急,咱们一步步来分析为啥会这样,以及以后该怎么避免。

最核心的问题通常出在Redis的持久化配置上,Redis虽然把所有数据都放在内存里,跑得飞快,但它也提供了两种主要的“记笔记”方式,用来把内存里的数据写到硬盘上,这样重启的时候就能重新“读笔记”把数据加载回来,如果你的Redis重启后数据丢了,十有八九是这两种“记笔记”的方式都没起作用,或者没配置对。

Redis重启后数据没了,咋整啊,重启恢复不起来问题分析

第一种“记笔记”的方式叫RDB,你可以把它想象成“拍快照”。(来源:Redis官方文档对RDB的说明)Redis会根据你的设置,在特定的条件下(比如在5分钟内至少有10000个键被改动)给当前的内存数据拍一张完整的快照,保存成一个叫dump.rdb的文件,这个文件是压缩过的二进制文件,比较小,重启Redis的时候,它就会自动去找这个文件来恢复数据,那为什么重启后数据没了呢?常见原因有这几个:

  1. 根本就没开启RDB持久化,有时候为了追求极致性能,或者是在测试环境,有人会直接把RDB持久化关掉,怎么关的呢?就是在Redis的配置文件redis.conf里,把save开头的配置行都注释掉,或者最后留一行save "",这样一来,Redis就永远不会自动拍快照了,你检查一下你的配置文件是不是这样设置的。
  2. 配置的拍快照条件太“苛刻”,默认配置可能是save 900 1,意思是15分钟内有至少1个键变化就拍快照,如果你的Redis在重启前,刚好在很长一段时间内(比如半小时)都没有新的数据写入或更新,那么它可能压根就没触发拍快照的操作,dump.rdb文件还是老早以前的,甚至根本就没生成,而你最新操作的数据全在内存里,一重启自然就没了。
  3. dump.rdb文件保存的目录权限不对,Redis进程可能没有权限向指定的目录(默认是Redis的启动目录)写入dump.rdb文件,你可以检查一下Redis的日志,里面很可能会看到它抱怨说写文件失败了,没有写成功,重启的时候当然找不到有效的快照文件。
  4. 最后一次手动关机时没有触发保存,虽然Redis在正常关闭(比如用shutdown命令)时会强制拍一次快照,但如果是直接用kill -9这种暴力命令把Redis进程杀掉,那它就没机会拍这最后的快照了,内存里的最新数据就会丢失。

第二种“记笔记”的方式叫AOF,这个更像“写日记”。(来源:Redis官方文档对AOF的说明)它会把每一个写操作命令(比如set, hmset)都实时地记录到一个日志文件(默认是appendonly.aof)里,重启的时候,Redis就重新把“日记”里的命令执行一遍,来还原数据,AOF的持久性通常比RDB更好,因为丢数据的窗口期更短,那为啥用了AOF也可能丢数据呢?

Redis重启后数据没了,咋整啊,重启恢复不起来问题分析

  1. 首要原因:根本没开启AOF,AOF功能默认是关闭的,你需要在redis.conf文件里找到appendonly这个配置项,把它改成yes,如果这里是no,那AOF功能就没开。
  2. AOF的写回策略配置不当,AOF有三种主要的策略(来源:Redis官方文档对appendfsync选项的说明):
    • appendfsync always:每个写命令都立刻同步到硬盘,最安全,但最慢。
    • appendfsync everysec:每秒同步一次,折中方案,也是默认值,最多丢一秒的数据。
    • appendfsync no:让操作系统来决定什么时候同步,性能最好,但丢数据的风险最大。 如果你的配置是everysecno,在重启前刚好有数据在操作系统的缓存里,没来得及写到硬盘上,那这部分数据就丢了。
  3. AOF文件损坏,如果AOF文件在写入过程中因为某种原因(比如磁盘满了、机器突然断电)损坏了,Redis在启动时因为无法正确读取这个“日记本”,可能会拒绝启动,或者直接创建一个空的AOF文件从头开始,这就导致数据看起来全没了。

遇到这个问题,现在该怎么“整”呢?

第一步:立刻检查Redis的配置文件redis.conf 这是最关键的一步,主要看以下几个地方:

Redis重启后数据没了,咋整啊,重启恢复不起来问题分析

  • 找找有没有save配置,或者是不是被注释了、设成了save "",这决定了RDB是否开启。
  • 找到appendonly配置,看它是yes还是no,这决定了AOF是否开启。
  • 如果AOF开启了,再看一下appendfsync是什么策略。

第二步:检查数据目录。 查看Redis配置的dir目录下,有没有dump.rdbappendonly.aof文件,看看它们的最后修改时间是不是你重启之前的时间,如果这两个文件根本不存在,或者修改时间是很久以前,那数据丢失就是必然的了。

第三步:查看Redis日志。 Redis的日志文件(通常配置在logfile项中)会详细记录它启动和关闭的过程,重启时,日志里会明确写着是“从RDB文件加载数据”还是“从AOF文件加载数据”,如果看到类似“DB loaded from disk: 0.000 seconds”这样的信息,意思是加载了0条数据,那就证实了它是从一个空的数据集启动的,日志里可能还会有一些错误信息,比如权限错误、文件损坏等,这都是重要的线索。

如果数据已经丢了,而且确认没有可用的备份文件,那很遗憾,丢失的数据是找不回来了。

为了避免以后再出现这种糟心事,你一定要:

  • 根据业务需求,正确配置持久化。 如果数据比较重要,建议同时开启RDB和AOF,RDB用于做定期的完整备份和快速恢复,AOF保证数据的实时安全性。
  • 定期备份持久化文件。 把生成的dump.rdbappendonly.aof文件拷贝到别的安全的地方(比如云存储、另一台服务器)。
  • 使用shutdown命令来关闭Redis,让它有机会做最后的持久化操作,避免暴力杀进程。
  • 监控磁盘空间,别让磁盘写满了导致持久化失败。

Redis重启数据丢失,根本原因几乎总是持久化配置问题,你现在要做的就是像个侦探一样,去检查配置文件、数据文件和日志文件,找到“案发”的真正原因,然后针对性地调整配置,这样才能避免重蹈覆辙。