Redis 持久化机制

总览

redis 数据库,可以直接用来当数据库使用,也可以当系统的缓存使用。但是 redis 大部分数据是存储在内存中的,当服务掉线重启,会造成数据的丢失。当然,redis 是有持久化线程的,我们可以利用这个持久化服务来做数据的持久化,这样当 redis 重启的时候,即可从硬盘重新读取数据,然后进行数据的恢复。 redis 的持久化方式有两种:

  1. RDB 方式
  2. AOP方式

    RDB 方式

执行过程

redisRDB 持久化是通过快照完成的。当符合一定条件的时候,redis 可以将目前的数据生成一份副本存储在硬盘。 redis 执行快照的一句有下面几种:

  1. 根据配置的规则
  2. 用户执行 SAVEBGSAVE 命令
  3. 执行 FLUSHALL 命令
  4. 执行复制时

配置规则

redis 可以根据用户在配置文件中配置的规则进行定时,定量的持久化。在 redisconf 文件夹中配置如下:

1
2
3
save 900 1 # 表示900秒以内有一个或以上的简直更改时进行快照
save 300 10
save 60 10000

执行 SAVE 或 BGSAVE 命令

执行 SAVE 时,redis 会阻塞所有客户端的请求,然后进行备份。这一过程可能造成 redis 长时间无响应,所以应该尽量避免。 执行 BGSAVE 时,redis 则异步的进行快照,客户端的请求依然可以进行处理。 执行 BGSAVE 时,redis 做了以下的操作:

  1. 当执行 BGSAVE 的时候,redis 会使用 Fork 函数复制一份当前进程(父)的副本(子)
  2. 父进程继续接收客户端的请求,而子进程会将 Fork 的副本写入硬盘的临时文件
  3. 当子进程将所有数据写入临时文件时,开始替换旧的 RDB 文件

在进行 Fork 操作的时候,父子进程共享一份内存数据,当父进程需要修改某一片的数据的时候,操作系统会将这一份数据进行复制,保证子进程的读取。所以,Fork 函数执行的时候,RDB文件存储的是这一时刻的数据。 执行这一操作需要确保开启 Linux 系统允许应用程序申请超过可用内存的空间(物理空间和交换空间)。方法是在 .etc/sysctl.conf 加入 vm.overcommit_memory = 1 然后重启系统或执行 sysctl vm.overcommit_memory = 1使配置生效即可。

执行 FLUSHALL 命令

执行该命令时,数据库中的所有数据将会被清空,不论配置文件怎么配置,只要执行该命令,redis 就会执行一次快照操作。

执行复制时

只要配置主从复制时,无论有没有配置规则,都会生成 RDB 文件的快照。用于多个实例之间进行数据的同步。

AOF 方式

当使用 redis 存储非临时数据时,一般需要开启 AOF 模式来减少每次 redis 的宕机造成的数据损失。AOF 会将 redis 执行的每一条命令都写入硬盘。当然这一过程肯定对性能造成一定影响,不过可以接受。

开启AOF

默认 redis 是没有开启 AOF 模式的。可以通过配置文件来实现:

1
appendonly yes

开启 AOF 持久化后将会保存每一条命令,可以通过下面配置来指定持久化文件的名字。 appendfilename append.aof

AOF 的实现

AOF 会通过保存客户端发送的通讯协议进行保存,所以会导致 AOF 文件越来越大的问题,因为可能出现的情况是,一个键被设置了,后面又被删除了,这时候完全可以不进行记录这一个过程。那么可以通过配置文件来设置 redisAOF 文件达到一定容量的时候进行 AOF 的优化重写:

1
2
auto-aof-rewrite-percentage 100 # 当前 AOF 文件超过上一次的 AOF 文件的百分之多少时进行重写,如果无重写过则以启动时的文件大小为准
auto-aof-min-size 64mb # 当 AOF 达到这个设置容量时触发重写

除了可以让 redis 自动重写以外,还可以通过传输命令 BGREWRITEAOF 来触发 redis 的重写。

同步硬盘数据

虽然每次都会重写 AOF 文件,但是此时这个文件并没有真正的写入硬盘中,而是进入硬盘缓存,如果此时系统出现异常宕机,则会导致数据的丢失。系统默认情况下,30秒执行一次同步硬盘操作,但是一般开启 AOF 的应用都不能允许这个情况的出现,这就需要 redis 在写入 AOF 文件的时候,主动触发同步硬盘。我们可以通过以下设置来实现这个目的:

1
aapendfsync everysec # 每秒执行一次同步操作,也是默认设置

可选值:always no 前者是每次写入 AOF 都进行同步,后者则完全交由系统决定。

持久化使用

redis 允许同时开启两种模式,既保证数据安全又使得备份十分容易。重启 redisredis 会使用 AOF 方式来回复数据,因为 AOF 可能丢失的数据更少。