跳转至

Redis 持久化

简介

由于 redis 是内存数据库,所以其数据断电易失,因此需要将数据保存到磁盘中。redis 有两种持久化解决方案,分别是:RDB,AOF。

快照 (Snapshot) / RDB

这种方式可以将某一时刻的所有数据都写入硬盘中 , 当然这也是 redis 的默认开启持久化方式 , 保存的文件是以 .rdb 形式结尾的文件因此这种方式也称之为 RDB 方式。

在指定时间间隔后,将内存中的数据集快照写入数据库 ;在恢复时候,直接读取快照文件,进行数据的恢复 ; 默认情况下, Redis 将数据库快照保存在名字为 dump.rdb的二进制文件中。文件名可以在配置文件中进行自定义。

file

RDB 持久化的大致过程

在进行 RDB 的时候,redis 的主线程是不会做 io 操作的,主线程会 fork 一个子线程来完成该操作;

  1. Redis 调用 forks。同时拥有父进程和子进程。
  2. 子进程将数据集写入到一个临时 RDB 文件中。
  3. 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益 ( 因为是使用子进程进行写操作,而父进程依然可以接收来自客户端的请求。)

bgsave:

客户端可以使用 BGSAVE 命令来创建一个快照 , 当接收到客户端的 BGSAVE 命令时 ,redis 会调用 fork 来创建一个子进程 , 然后子进程负责将快照写入磁盘中 , 而父进程则继续处理命令请求。 bgsave 是异步进行,进行持久化的时候,redis 还可以将继续响应客户端请求 ; file

save:

使用 save 命令,会立刻对当前内存中的数据进行持久化 , 但是会阻塞,也就是不接受其他操作了; 由于 save 命令是同步命令,会占用 Redis 的主进程。若 Redis 数据非常多时,save 命令执行速度会非常慢,阻塞所有客户端的请求。 file

shutdown:

redis 通过 shutdown 指令接收到关闭服务器的请求时 , 会执行一个 save 命令 , 阻塞所有的客户端 , 不再执行客户端执行发送的任何命令 , 并且在 save 命令执行完毕之后关闭服务器

注意 :

SAVE 命令并不常用 , 使用 SAVE 命令在快照创建完毕之前 ,redis 处于阻塞状态 , 无法对外服务

如果用户在 redis.conf 中设置了 save 配置选项 ,redis 会在 save 选项条件满足之后自动触发一次 BGSAVE 命令 , 如果设置多个 save 配置选项 , 当任意一个 save 配置选项条件满足 ,redis 也会触发一次 BGSAVE 命令

file

优点

  1. RDB 文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
  2. 生成 RDB 文件的时候,redis 主进程会 fork() 一个子进程来处理所有保存工作,主进程不需要进行任何磁盘 IO 操作。
  3. RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

缺点

  1. 需要一定的时间间隔进程操作!如果 redis 意外宕机了,这个最后一次修改数据就没有的了!
  2. fork 进程的时候,会占用一定的内容空间!!

RDB 触发机制

  1. save 的规则满足的情况下,会自动触发 rdb 规则
  2. 执行 flushall 命令,也会触发我们的 rdb 规则!
  3. 退出 redis,也会产生 rdb 文件!

配置生成快照名称和位置

  1. 修改生成快照名称 dbfilename dump.rdb
  2. 修改生成位置 dir ./

file

恢复 rdb 文件

  1. 只需要将 rdb 文件放在 redis 启动目录中,redis 启动时自动检查 dump.rdb 恢复其中的数据。
  2. 查看其存在的位置

file 如果 /var/lib/redis 这个目录存在 dump.rdb 文件,则启动时自动恢复数据。

AOF

Append Only File

将我们所有的命令都记录下来,history,恢复的时候就把这个文件全部再执行一遍

什么是 AOF

快照功能(RDB)并不是非常耐久(durable: 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、以及未保存到快照中的那些数据。 从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。

file

特点

这种方式可以将所有客户端执行的写命令记录到日志文件中 ,AOF 持久化会将被执行的写命令写到 AOF 的文件末尾 , 以此来记录数据发生的变化 , 因此只要 redis 从头到尾执行一次 AOF 文件所包含的所有写命令 , 就可以恢复 AOF 文件的记录的数据集 .

开启 AOF 持久化

redis 的默认配置中 AOF 持久化机制是没有开启的,需要在配置中开启

file

appendonly no yes 则表示启用 AOF

默认是不开启的,我们需要手动配置,然后重启 redis,就可以生效了!

如果这个 aof 文件有错位,这时候 redis 是启动不起来的,我需要修改这个 aof 文件

redis 给我们提供了一个工具 redis-check-aof --fix

日志追加频率

修改日志同步频率
- 修改appendfsync everysec|always|no 指定

file

AOF 文件的重写

AOF 带来的问题

AOF 的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用 incr test 命令 100 次,文件中必须保存全部的 100 条命令,其实有 99 条都是多余的。因为要恢复数据库的状态其实文件中保存一条 set test 100 就够了。为了压缩 aof 的持久化文件 Redis 提供了 AOF 重写 (ReWriter) 机制。

AOF 重写

用来在一定程度上减小 AOF 文件的体积

触发机制

# 1.客户端方式触发重写
- 执行BGREWRITEAOF命令  不会阻塞redis的服务
# 2.服务器配置方式自动触发
- 配置redis.conf中的auto-aof-rewrite-percentage选项 参加下图↓↓↓
- 如果设置auto-aof-rewrite-percentage值为100和auto-aof-rewrite-min-size 64mb,并且启用的AOF持久化时,那么当AOF文件体积大于64M,并且AOF文件的体积比上一次重写之后体积大了至少一倍(100%)时,会自动触发,如果重写过于频繁,用户可以考虑将auto-aof-rewrite-percentage设置为更大

file

重写原理

注意:重写 aof 文件的操作,并没有读取旧的 aof 文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的 aof 文件 , 替换原有的文件这点和快照有点类似。

# 重写流程
- 1. redis调用fork ,现在有父子两个进程 子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
- 2. 父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
- 3. 当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
- 4. 现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。

file

优点

  1. 每一次修改都会同步,文件的完整性会更加好
  2. 没秒同步一次,可能会丢失一秒的数据
  3. 从不同步,效率最高

缺点

  1. 相对于数据文件来说,aof 远远大于 rdb,修复速度比 rdb 慢!
  2. Aof 运行效率也要比 rdb 慢,所以我们 redis 默认的配置就是 rdb 持久化

如何选择哪种持久化方式

一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。

如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。

有很多用户都只使用 AOF 持久化, 但并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。


最后更新: 2023年9月17日 19:14:43
创建日期: 2023年9月17日 19:14:43
回到页面顶部