Redis 持久化 - RDB 与 AOF

Redis 的数据是存储在内存当中, 因为服务器宕机、停电等情况, Redis 中的数据容易丢失。这时 Redis 持久化的作用就体现出来了。例: 可以用来完成数据恢复、故障恢复数据等。

Redis 持久化分为三种策略机制: RDB(Redis DataBase)AOF(Append Only File)、两种方式混合持久化。


本文简要的描述两种方式。 如需深层次的知识点, 恭请各位大佬进入高级区查阅。

点我查看 - Redis 基本知识,快来回顾一下


点我查看 - Redis 订阅与 Redis Stream 技术


点我查看 - PHP 使用 PHPRedis 与 Predis

一、RDB(Redis DataBase)

RDB 是指周期性的将内存中的数据集快照写入磁盘文件。


这种方式是也就是将内存中的数据以快照的方式写入二进制文件中, 默认的文件名为 dump.rdb, 在 Redis 重启时, 通过加载 dump.rdb 文件来恢复数据。


1.1 RDB 的触发方式

1.1.1 自动触发

顾名思义, 自动触发是 Redis 在某个时间内, 自动执行持久化操作, 将数据进行备份。

Redis 配置文件是 /usr/local/redis/bin/redis.conf

  • 这是我的 redis.conf 所在位置, 根据自己情况找到该文件

  • 打开后, 我的在 412 行开始是快照的配置

  • 我这里默认 RDB 持久化功能是关闭的, # save "", 我的在 424 行

  • dbfilename dump.rdb 文件名配置, 我的在 481 行

  • dir ./ 备份文件保存目录配置, 我的在 504 行

  • 默认都是注释着的, 如果要启用, 将行开头的 # 去掉

# 配置格式: save m n [m n ...]
# 解释: 在 m 秒内, 如果有 n 个键发生改变, 则自动触发持久化操作, 可配置多个条件

# 例: save 3600 1 300 100 60 10000
# 例解: 3600 秒内, 如果有 1 个键发生改变, 则自动触发持久化操作
# 例解: 300 秒内, 如果有 100 个键发生改变, 则自动触发持久化操作
# 例解: 60 秒内, 如果有 10000 个键发生改变, 则自动触发持久化操作

1.1.2 手动触发

顾名思义, 手动触发就是通过 手动执行命令 来完成持久化操作。

手动触发的命令有两个: save()bgsave(), 他们之间的主要区别在于是否会阻塞线程。

SAVE 命令:

  • save() 命令触发 Redis 同步持久化。
  • 缺点: 会使 Redis 处于阻塞状态, 不能执行其他命令, 直到 RDB 持久化完成。
  • 优点: 虽然不会消耗额外的内存,但生产环境慎用

BGSAVE 命令:


bgsave() 会执行 fork 操作创建子进程, 持久化的工作由子进程完成, 整个过程只有在 fork 子进程的时候有短暂的阻塞, 当子进程被创建后, 就可以响应其他客户端的请求了。

  • bgsave() 命令触发 Redis 异步持久化。
  • 缺点: 创建子进程, 需要消耗更多内存。
  • 优点: 创建子进程后, 其他客户端还可以交互, 大多数情况采用bgsave()

1.2 RDB 的优缺点

1.2.1 RDB 优点

  • RDB 的持久化文件为二进制数据, 占用内存更小。
  • RDB 因为备份的是数据库的快照, 所以非常适合冷备份, 比如 凌晨1点的时候, 进行持久化操作。
  • 在面对大数据的情况下, RDB 备份与恢复速度比 AOF 快。

1.2.2 RDB 缺点

  • RDB 是周期性进行备份, 如果发生意外情况, 且这段时间有数据交互, 就会丢失这段时间的数据。
  • 无法实现 实时持久化
  • 因为是全量备份, 且还经常创建子进程, 数据量大的话, 会长期消耗服务器CPU与内存。

二、AOF(Append Only File)

AOF 采用日志方式记录, 将执行完的命令、命令参数、参数个数等信息通过 write 函数追加到日志文件末尾。

2.1 同步流程

命令同步流程:

  • 将命令或参数等发送至 AOF 程序
  • AOF 程序收到后, 因为 Redis 是单线程, 通过 resp 协议, 将数据暂存到 AOF 缓冲区
  • 通过设置的同步策略, 将暂存区的命令同步追加到文件末尾

2.2 同步策略

# 同步策略由 appendfsync 参数决定, 我的在 1435 行开始
# appendfsync always

appendfsync everysec # 默认

# appendfsync no
  • always

    AOF 缓冲区收到数据时, 立即调用 fsync 命令强制往 AOF 文件写数据

  • everysec

    AOF 缓冲区收到数据时, 调用 write 命令往 io 缓冲区写数据, 同时以每秒调用一次 fsync 命令, 强制将 io 缓冲区的数据写入 AOF 文件

  • no

    AOF 缓冲区收到数据时, 调用 write 命令往 io 缓冲区写数据, io 缓冲区填满时或系统定期的将 io 缓冲区的数据写入 AOF 文件


2.3 AOF 重写

随着执行命令越来越多, AOF 文件会越来越大, 可采用 AOF 重写机制 解决这一问题。


重写会启用一个后台子进程 bgrewriteaof

2.3.1 配置

AOF 重写 是去除 AOF 文件中 无效的命令超时的数据 等或采用 命令合并 方式, 创建一个新的 AOF 文件来保存重写后的命令。

no-appendfsync-on-rewrite no # 重写机制默认是关闭的, 如需开启, 请改为 yes , 我的在 1460 行

2.3.2 触发重写

  • 手动触发

    AOF 重写可以由用户通过调用 BGREWRITEAOF 命令手动触发。

  • 自动触发

    根据 auto-aof-rewrite-percentageauto-aof-rewrite-min-size 64mb 确定触发时机。

    # 我的在 1479 行
    auto-aof-rewrite-percentage 100 # 当前 AOF 文件大小(aof_current_size) 比 之前重写后的大小(aof_base_size) 至少大了 100%
    
    auto-aof-rewrite-min-size 64mb # AOF 体积大于 64mb 会触发重写
    

2.4 开启 AOF

默认 AOF 持久化功能是关闭的。

Redis 配置文件是 /usr/local/redis/bin/redis.conf。打开后, 我的在 1359 行是配置的开始。

appendonly yes # 开启, 改为 yes , 我的在 1379 行

appendfilename "appendonly.aof" # 快照基本文件名

appenddirname "appendonlydir" # 存储专用目录

2.5 AOF 的优缺点

2.5.1 AOF 的优点

  • 可以更好的保护数据完整性, 比 RDB 更靠谱
  • 即使文件过大, 也可以采用 重写 方式, 不影响客户端

2.5.2 AOF 的缺点

  • 因为同步策略, 一般情况下 AOF 的速度慢于 RDB
  • 即使一直在重写, 但文件体积还是要比 RDB 的二进制文件大
  • AOF 在恢复时, 会重演每条命令, 速度也比 RDB
  • 因体量较大, 恢复时, 可能存在写坏, 可通过对比两文件差异, 使用 redis-check-aof --fix AOF文件名 修复, diff -u 来对比文件的差异, 进而确定后再恢复。

三、两者比较

方式 存储速度 恢复速度 数据完整性 文件大小 资源消耗
RDB 不可抗拒因素, 可能会丢失数据
AOF 依据同步策略,视情况而定, 可能会写坏

根据业务场景选择合适的持久化方式, 默认 RDB


  • 如果业务场景主要充当缓存功能, 失效重新访问数据获取, 不怎么依赖持久化, 则选择 RDB
  • 如果数据需要持久保存, 确保数据的完整性, 则建议 RDBAOF 同时启用。

点我查看 - Redis 基本知识,快来回顾一下


点我查看 - Redis 订阅与 Redis Stream 技术


点我查看 - PHP 使用 PHPRedis 与 Predis

你可能感兴趣的:(#,Redis,redis,数据库,缓存)