Redis 持久化策略

Redis 提供了多种持久化机制,用于将数据保存到磁盘中,以防止因服务器重启或故障而导致的数据丢失。主要的持久化策略有两种:RDB (Redis Database) 和 AOF (Append Only File),即当 Redis 服务器重新启动时,会读取相应的文件,来还原上次退出时的数据;

一、RDB

RDB 是 Redis 默认的持久化方式 ,它会定期的将 Redis 内存中的所有数据都写入硬盘中,生成一个 "快照"------.rdb 二进制文件

"定期" 又有两种方式:

1)手动触发

程序员通过 Redis 客户端,执行特定的命令(save,bgsave)来触发快照的生成;

  1. save 命令:执行 save 命令的时候,redis 就会全力以赴的进行 "快照生成" 操作,此时就会阻塞 redis 的其他客户端的命令,直到 RDB 过程完成为止,对于内存比较大的实例造成长时间阻塞,基本不采用;
  2. bgsave 命令:background,该命令不会影响 Redis 服务器处理其他客户端的请求和命令,该命令通过多进程的方式实现,Redis 进程执行 fork 操作创建子进程,RDB 持久化由子进程负责,完成后自动结束,阻塞只发生在 fork 创建进程阶段,这个时间很短;
    1. 执行 bgsave 命令,Redis 父进程判断当前进是否存在其他正在执行的子进程,如 RDB / AOF 子进程,如果存在,bgsave 命令会直接返回;
    2. 父进程执行 fork 创建子进程,fork 过程中父进程会阻塞,通过 info stats 命令查看 latest_fork_usec 选项,可以获取最近⼀次 fork 操作的耗时,单位为微秒;
    3. 父进程 fork 操作执行完成后,bgsave 命令返回 "Background saving started" 信息并不再阻塞父进程,此时父进程可以继续响应其他命令;
    4. 子进程创建 rdb 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换;执行 lastsave 命令可以获取最后一次生成 rdb 的时间,对应 info 统计的rdb_last_save_time 选项;
    5. 进程发送信号给父进程表示完成,父进程更新统计信息;

通过 save 命令 手动触发 RDB

通过 bgsave 命令手动触发 RDB

rdb 文件保存在 dir 配置指定的目录(默认 /var/lib/redis/)下,文件名通过 dbfilename 配置(默认 dump.rdb)指定,/user/bin/ 目录下有检测 rdb 文件的工具 redis-check-rdb,通过 redis-check-rdb rdb 文件名的方式检查 rdb 文件;

如果 Redis 启动时加载到损坏的 rdb 文件会拒绝启动,此时可以使用 Redis 提供的 redischeck-dump 工具检测 rdb 文件并获取对应的错误报告; 也可以通过查看 Redis 的日志查看错误问题,日志文件默认在 /var/log/redis/ 目录下;

**通过 bgsave 生成 rdb 文件时,**会把要生成的快照数据保存在一个临时文件中,当这个快照生成完毕之后,再删除之前的 rdb 文件,把新生成的临时文件名修改为删除的 rdb 文件名(可通过 stat 命令查看文件的 Inode 编号);

2)自动触发

在 Redis 的配置文件中可以看到这样的信息;

"save m n" 表示 m 秒内数据集发生了 n 次修改时,自动 RDB 持久化,既要满足经过 m 秒,还要满足达到 n 次修改;

以下情况也会自动触发 rdb

  1. 在 Redis 服务器关闭时也会自动触发
  2. Redis 进行主从复制的时候,主节点也会自动生成 rdb 快照,然后把 rdb 文件内容传输给从节点

3)RDB 的优缺点

优点

  1. 高效的磁盘IO:由于是定期生成快照,RDB 文件的磁盘 IO 操作相对集中,通常比 AOF 的每次写操作同步更加高效。
  2. 快速恢复:RDB 文件是一个紧凑的二进制文件,加载速度较快,适合用于快速数据恢复。
  3. 简单文件结构:RDB 文件结构相对简单,文件较小,便于传输和备份。

缺点

  1. 数据持久化的时间间隔:RDB 是基于时间间隔生成快照的,在两次快照之间的数据可能会丢失。如果 Redis 崩溃(通过 kill -9 杀掉 redis 进程),则最后一次快照之后的所有数据都将丢失,即不能实时的持久化保存数据。
  2. 生成快照时的性能开销:生成快照时,尤其是对大数据集生成快照,可能会对 Redis 的性能产生影响。
  3. 存在兼容性问题:Redis 版本演进过程中有多个 RDB 版本,兼容性可能有风险。

二、AOF

AOF 默认是关闭状态,需要修改配置文件(改为 yes)来开启 AOF 功能,当开启 AOF 的时候,RDB 就不生效了,即 Redis 启动时就不会读取 RDB 文件的内容了;同时 AOF 写入的是文本文件;

AOF 通过记录每个写操作的日志,以追加的方式写入日志文件,来实现数据持久化;

AOF 的主要作用是解决了数据持久化的实时性,目前已经是 Redis 持久化的主流方式;

1)AOF 工作流程

  1. 所有的写入命令会追加到 aof_buf(缓冲区)中;

  2. AOF 缓冲区根据对应的策略(缓冲区刷新策略)向硬盘做同步操作;

  3. 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的;

  4. 当 Redis 服务器启动时,可以加载 AOF 文件进行数据恢复;

可以看出 AOF 机制并非是直接让工作进程把数据写入硬盘,而是先写入一个内存的缓冲区,积累一波后,再统一写入硬盘,若在缓冲区还没来得及写入硬盘的时候,此时进程异常结束,主机掉电,则缓冲区的数据会丢失;

因此 Redis 给出了缓冲区的刷新策略(类似于 MySQL 的事务隔离级别),通过 **appendfsync**选项进行配置,默认为 everysec,分别为:

  • always:每次有写操作时,立即将数据写入 AOF 文件并同步到磁盘;
  • everysec:每秒将缓冲区中的数据写入 AOF 文件并同步到磁盘,Redis 使用后台线程每秒执行一次 fsync
  • no:让操作系统决定何时将缓冲区中的数据写入 AOF 文件并同步到磁盘。Redis 只负责将数据写入缓冲区,不主动执行 fsync

2)AOF 的重写机制

随着命令不断写入 AOF,文件会越来越大,为了解决这个问题,Redis 引入 AOF 重写机制压缩文件体积;AOF 文件重写是把 Redis 进程内的数据转化为写命令同步到新的 AOF 文件;

重写后的 AOF 文件为什么可以变小?有如下原因:

  • 进程内已超时的数据不再写入文件;
  • 旧的 AOF 中的无效命令,例如 del、hdel、srem 等重写后将会删除,只需保留数据的最终版本;
  • 多条写操作合并为⼀条,例如 lpush list a、lpush list b、lpush list c 从可以合并为 lpush list a b c;

较小的 AOF 文件不仅降低了硬盘空间占用,还可以提升启动 Redis 时数据恢复的速度;

AOF 重写过程可以分为手动触发和自动触发

  • 手动触发 :通过执行 bgrewriteaof 命令;

  • 自动触发 :根据配置项 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时机;

    • auto-aof-rewrite-min-size:表示触发重写时 AOF 的最小文件大小,默认为 64MB;

    • auto-aof-rewrite-percentage:代表当前 AOF 占用大小相比较上次重写时增加的比例;

AOF 重写流程

  1. 执行 AOF 重写请求,如果当前进程正在执行 AOF 重写,则请求不执行;如果当前进程正在执行 bgsave 操作,则会等待 bgsave 操作完成之后再执行;

  2. 父进程执行 fork 创建子进程;

  3. 重写

  4. 父进程 fork 之后,可以继续响应其他命令,所有修改操作写入缓冲区并根据缓冲区策略同步到硬盘,保证旧的 AOF 文件机制正确;

  5. 父进程生成一个 aof_rewrite_buf 重写缓冲区,用于存放 fork 之后的写数据(这部分数据也会在 aof_buf 中存在);

  6. 子进程根据内存快照,将命令合并到新的 AOF 文件中(精简旧的 AOF 文件);

  7. 子进程完成重写

  8. 新文件写入后,子进程发送信号给父进程;

  9. 父进程把 AOF 重写缓冲区内临时保存的命令追加到新的 AOF 文件中;

  10. 用新的 AOF 文件替换旧的 AOF 文件;

3)AOF 的优缺点

优点

  1. 更高的数据安全性:AOF 可以配置为每次写操作后立即同步到磁盘或者每秒同步一次,从而提供不同程度的数据安全性,即使 Redis 崩溃,通过 AOF 文件可以恢复到最后一次写操作的状态(根据同步策略,数据丢失可以控制在最小范围内);
  2. 可读性:AOF 文件是一个纯文本文件,包含了所有写操作的记录,这使得它更容易阅读和理解;

缺点

  1. 性能开销:相比 RDB 快照,AOF 在每次写操作时都会进行磁盘写入,这可能会导致较高的 I/O 开销,尤其是在写操作频繁的场景中;
  2. 恢复速度:在 Redis 重启时,需要从 AOF 文件中重放所有的写操作来恢复数据,对于大型 AOF 文件,这个过程可能比较耗时,导致恢复速度较慢;

三、混合持久化

混合持久化结合了 RDB 和 AOF 两种持久化方式的优点,通过将 RDB 快照和 AOF 日志结合在一起,实现数据的高效持久性和快速恢复;

在 redis 配置文件中存在以下内容,表示是否开启了混合持久化(默认为 yes,表示开启);

优点:

  • 快速恢复:相比纯 AOF 持久化,混合持久化大大加快了恢复速度,因为大部分数据直接从 RDB 快照加载。
  • 高数据安全性:相比纯 RDB 持久化,混合持久化能确保更高的数据持久性,因为 AOF 日志记录了快照后的所有写操作。
  • 文件体积:通过合并 RDB 和 AOF,减少了持久化文件的体积增长。
相关推荐
IvorySQL15 分钟前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·24 分钟前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德27 分钟前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫1 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i1 小时前
完全卸载MariaDB
数据库·mariadb
期待のcode1 小时前
Redis的主从复制与集群
运维·服务器·redis
纤纡.1 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql
jiunian_cn1 小时前
【Redis】渐进式遍历
数据库·redis·缓存
橙露2 小时前
Spring Boot 核心原理:自动配置机制与自定义 Starter 开发
java·数据库·spring boot
冰暮流星2 小时前
sql语言之分组语句group by
java·数据库·sql