文章目录加载中

Redis数据持久化:RDB

Redis 支持两种方式的持久化,一种是 RDB 方式,另一种是 AOF 方式。前者会根据指定的规则“定时”将内存中的数据存储在硬盘上,而后者在每次执行命令后将命令本身记录下来。两种持久化方式可以单独使用其中一种,但更多情况下是将二者结合使用。

# 什么是 RDB 持久化?

RDB 方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时 Redis 会自动将内存中的所有数据生成一份副本并存储在硬盘上,这个过程即为“快照”。

# 哪些情况下,redis 对数据进行快照?

1、根据配置规则进行自动快照

进行快照的条件可以由用户在配置文件中自定义,由两个参数构成:时间窗口 M 和改动的键的个数 N。含义是:每当时间 M 内被更改的键的个数大于 N 时,则生成快找

2、用户执行 SAVE 或 BGSAVE 命令

在 redis 中执行 save 命令,会阻塞客户端请求,如果数据较多,会导致 redis 不响应。

与之相反,BGSAVE 是异步的。

3、执行 FLUSHALL 命令

此命令会清空数据,如果此时有定义自动快照条件,那么会进行生成快照。

4、执行复制(replication)时

redis 集群中,在复制初始化进行时,会进行自动快照。

# redis 快照原理

Redis 默认会将快照文件存储在 Redis 当前进程的工作目录中的 dump.rdb 文件中。

过程:

  1. Redis 使用 fork 函数复制一份当前进程(父进程)的副本(子进程)
  2. 父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件
  3. 当子进程写入完所有数据后会用该临时文件替换旧的 RDB 文件,至此一次快照操作完成

这里 fork 时,用到了写时复制(copy-on-write)策略,即 fork 函数发生的一刻父子进程共享同一内存数据,所以新的 RDB 文件存储的是执行 fork 一刻的内存数据

写时复制策略也保证了在 fork 的时刻虽然看上去生成了两份内存副本,但实际上内存的占用量并不会增加一倍

# 异常情况

通过 RDB 方式实现持久化,一旦 Redis 异常退出,就会丢失最后一次快照以后更改的所有数据。

根据具体业务场景进行处理,不一定要求完美。例如,使用 Redis 存储缓存数据时,丢失最近几秒的数据或者丢失最近更新的几十个键并不会有很大的影响。如果数据相对重要,希望将损失降到最小,则可以使用 AOF 方式进行持久化。

本文来自心谭博客:xin-tan.com,经常更新web和算法的文章笔记,前往github查看目录归纳:github.com/dongyuanxin/blog