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 创建进程阶段,这个时间很短;7c5b0e3242224ac196f50fa7025d20a6.png
    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 

136e842eb03d4d4f8b5db794ead26823.png

通过 bgsave 命令手动触发 RDB

74492c5dda97465b8731188e4ee13b6c.png

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/ 目录下;

47687ecafd344c289c971963ba3f7592.png3c5a0eb6fce44f43a0793e33d497034d.png0b5d4851dfec421d8b7ece89291dad16.png

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

2)自动触发

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

42b482f4de504f24bf523d9650159030.png

 "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 写入的是文本文件;

196fd5013093419e85c32687c1cf60fc.png

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

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

1)AOF 工作流程

9aec73cb72c1427a9498b0560b0d2e9f.png

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 命令;062777c4849e4b53992e5b47e248ef57.png

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

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

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

AOF 重写流程

06701da6448b4f2692ba5f0161b34606.png

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

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

3. 重写

  1. 父进程 fork 之后,可以继续响应其他命令,所有修改操作写入缓冲区并根据缓冲区策略同步到硬盘,保证旧的 AOF 文件机制正确;
  2. 父进程生成一个 aof_rewrite_buf 重写缓冲区,用于存放 fork 之后的写数据(这部分数据也会在 aof_buf 中存在);

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

5. 子进程完成重写

  1. 新文件写入后,子进程发送信号给父进程;
  2. 父进程把 AOF 重写缓冲区内临时保存的命令追加到新的 AOF 文件中;
  3. 用新的 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,表示开启);

1d6964c998584cc08c50b7b4a5348f91.png

优点:

  • 快速恢复:相比纯 AOF 持久化,混合持久化大大加快了恢复速度,因为大部分数据直接从 RDB 快照加载。
  • 高数据安全性:相比纯 RDB 持久化,混合持久化能确保更高的数据持久性,因为 AOF 日志记录了快照后的所有写操作。
  • 文件体积:通过合并 RDB 和 AOF,减少了持久化文件的体积增长。

 

 

  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rcnhtin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值