redis-08 持久化

持久化

redis是内存数据库,如果不将内存数据保存到磁盘,一旦服务器进程退出,服务器中的数据库也会消失,所以redis提供了持久化功能

RDB(Redis DataBase)

在指定的时间间隔内,将内存中的数据集快照写入磁盘,也就是所谓的snapshot快照,它恢复时是将快照文件直接读到内存里。

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件,整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效。RDB的缺点是最后一次持久化后的数据可能丢失
生产环境一般会将dump.rdb文件进行备份
rdb保存的文件是dump.rdb
1、save的规则满足配置文件的设置的时候会触发rdb规则 进行持久化
2、执行flushall命令 也会触发rdb规则 持久化
3、退出redis 也会志兴rdb持久化

如何恢复rdb文件

只要将rdb文件放在redis启动目录就行了,redis启动的时候会自动检查dump.rdb文件,恢复其中的数据
获取文件目录

127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin"  # 如果在这个目录下存在dump.rdb文件,启动就会自动恢复其中的数据

优点

  • 文件紧凑,恢复速度快;bgsave 通过子进程完成,对 Redis 主进程性能影响小
  • 适合大规模的数据恢复
  • 对数据的完整性要求不高

缺点

  • 数据安全性低,可能会丢失最后一次快照后的所有数据。fork 子进程在数据量大时可能耗时较长

  • 需要一定的时间间隔进行操作,如果redis意外宕机了,最后一次修改数据就没有了

  • fork进程的时候,需要一定的内容空间

RDB的save和bgsave命令有什么区别
  • save同步阻塞主进程进行持久化,期间不处理任何请求,不推荐在生产环境使用。
  • bgsave异步非阻塞。主进程 fork 出一个子进程,由子进程负责生成 RDB 文件,主进程继续处理请求。阻塞只发生在 fork 阶段,时间很短。

AOF(Append Only File)

将所有命令都记录下来,恢复的时候就把这个文件中的命令全部再执行一遍
以日志的形式来记录每个操作,将redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据。换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次,以完成数据的恢复工作。
配置文件中 aof默认是不开启的 需要手动开启 将appendonly 设置为 yes

如果aof文件有错误,这时候redis是启动不起来的,需要修复这个aof文件,
redis 在bin目录里 提供了一个工具 redis-check-aof
执行:redis-check-aof --fix appendonly.aof
注意:修复一般是保证修复aof文件的正确性,那错误的数据会被丢弃,比如vim编辑aof文件造成文件错误无法启动redis,修复后 你修改的那个操作的命令可能就被删掉了。

优点

  • 数据安全性高,通过 appendfsync 策略可配置,最多丢失一秒数据。
  • AOF 文件可读性强,方便误操作恢复。

缺点

  • 相对于数据文件来说,aof远远大于rdb文件,修复的速度也比rdb慢
  • 持续写入对性能有影响aof运行效率也比rdb慢,所以redis默认配置就是rdb持久化
no-appendfsync-on-rewrite no // 重写时的同步策略
// 当 AOF 重写正在进行时,主进程是否依然按照 appendfsync 策略(如 everysec)将新命令同步刷入磁盘 
//默认为 no表示不妥协。在重写过程中,主进程依然会正常执行 fsync 操作
// 改为 yes表示妥协。在重写期间,主进程会暂时跳过 fsync,仅把数据写到操作系统的页缓存(Page Cache)中。
auto-aof-rewrite-percentage 100  // 重写增长率阈值 必须和 auto-aof-rewrite-min-size 配合使用
// 100:表示当 AOF 文件的当前体积,比“上次重写后的体积”增长了 100%(即翻了一倍)时,触发重写条件。
auto-aof-rewrite-min-size 64mb // 重写最小体积门槛
// 表示无论增长率多少(哪怕是 1000%),只要 AOF 文件总大小还没超过 64MB,就坚决不触发重写

如果aof文件超过64MB,就会fork一个新的进程将文件重写
为什么要重写?重写究竟发生了什么?
举个例子:假设要统计一个商品的点击量,执行了以下操作:

第 1 秒:INCR views (0->1)
第 2 秒:INCR views (1->2)
...
第 1000 万秒:INCR views (999万->1000万)

如果只追加:AOF 文件里会有 1000 万条 INCR views 命令。这个文件会变得巨大无比(可能几十个 GB)。
如果重写:Redis 子进程读到内存中 views 的最终值是 10000000,它会抛弃那 1000 万条累加命令,只在重写后的新文件里写一条命令:SET views 10000000。我们知道Redis 重启时,需要逐条执行 AOF 里的命令来恢复数据,如果一直保持1000万条自增命令,重启的时候可能需要 几十分钟甚至几个小时,这在生产环境是不可接受的。而重写后改为SET views 10000000 一条命令即可极速加载。
结论:重写是为了删除冗余的操作历史,只保留最终结果。如果不重写,AOF 文件大小会正比于我们的操作次数(而非内存数据量),最终导致磁盘爆满和重启极度缓慢。

AOF 和 RDB 可以同时开启

日常运行AOF 会持续、实时地记录每个写入命令,充当“实时操作日志”。同时,RDB 也会按照你设定的策略(如 save 60 10000)在后台定时生成全量数据的“快照”
重启恢复AOF拥有最高优先级。当 Redis 重启时,会优先使用 AOF 文件来恢复数据。因为 AOF 日志通常比 RDB 快照更完整,数据丢失更少
只有在 AOF 功能被关闭或 AOF 文件不存在时,Redis 才会退而使用 RDB 文件来恢复

混合持久化

从 Redis 4.0 开始,还引入了“混合持久化”模式,可以通过配置开启

aof-use-rdb-preamble yes

开启后,AOF 文件在重写时,会先写入一个 RDB 格式的全量数据快照作为“文件头”,之后再追加新的增量命令日志。这带来了两大好处:
重启更快:加载时直接加载 RDB 格式的头部,比逐条重放所有命令快得多。
文件更小:结合了 RDB 的紧凑性和 AOF 的完整性。
同时开启两种机制,本质上是用一点额外的磁盘空间和性能开销,换取极高的数据安全性

持久化方式 主要作用 优点 缺点
RDB 定时全量备份 文件紧凑,适合备份;恢复速度快 数据丢失风险高(可能丢失上次快照后的数据)
AOF 实时记录操作 数据更安全,丢失数据极少 文件体积大;恢复速度慢
同时开启 优势互补 数据最安全,兼顾快速恢复与高完整性 消耗更多磁盘I/O和存储空间

因此,对于大多数生产环境,强烈推荐同时开启 RDB 和 AOF,并启用“混合持久化”模式,以实现数据安全与恢复效率的最佳平衡

持久化对 Redis 性能有影响吗?如何优化?
有影响。主要体现在磁盘 I/O 和 fork 子进程时的内存占用。
优化建议:

  • 将 RDB 文件和 AOF 文件存储在独立的、高性能的磁盘(如 SSD)上。
  • 根据业务容忍度,合理设置 save 策略和 appendfsync 策略。
  • 控制单个 Redis 实例的内存大小,避免 fork 时间过长。
  • 利用混合持久化减少 AOF 文件大小和恢复时间。

如果 Redis 突然宕机了,如何从持久化文件中恢复数据?
1、停止 Redis 服务。
2、将备份的 dump.rdb 或 appendonly.aof 文件放置到 Redis 配置的 dir 目录下。
3、重启 Redis 服务,它会自动加载持久化文件并恢复数据。

如果AOF 文件损坏了,怎么办?
redis-check-aof --fix <filename>来尝试修复。修复前务必先备份

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容