持久化

持久化(Persistence),即把内存中的数据保存到磁盘中。

持久化的实现方式

快照式

在某个时刻把所有数据进行完整备份。

例:MySQL 的 Dump 方式、Redis 的 RDB 方式。

日志式

把用户执行的所有写指令(增删改)备份到文件中,还原数据时只需要把备份的所有指令重新执行一遍即可。

例:MySQL 的 Binlog、Redis 的 AOF、Hbase 的 HLog。

RDB简介

默认情况下, Redis 将数据库快照保存在名为 dump.rdb 的二进制文件中。

当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:

  1. Redis 调用 forks 派生一个子进程。父进程和子进程同时存在。
  2. 子进程将当前内存中的数据库快照写入到一个临时 RDB 文件中。
  3. 当子进程完成对新 RDB 文件的写入后,Redis 用新 RDB 文件替换原来的 RDB 文件。

当 Redis 需要恢复数据时, Redis 程序可以通过载入 RDB 文件来还原数据库的状态。

RDB 的触发机制

save命令

save 命令是一个同步操作命令,会占用 Redis 的主进程。若 Redis 数据非常多时,save 命令执行速度会非常慢,导致阻塞所有客户端的请求。

生产环境不建议使用 save 命令,可以使用 bgsave 命令代替。

127.0.0.1:6379> save
OK

bgsave命令

bgsave 命令是一个异步操作命令,Redis 使用 Linux 系统的 fock() 生成一个子进程来将数据保存到磁盘,主进程可以继续为客户端提供服务。

如果操作成功,可以通过客户端命令LASTSAVE来检查操作结果。

127.0.0.1:6379> bgsave

自动生成RDB

通过配置 Redis 的配置文件,可以设置“ 在N 秒内数据集至少有 M 个改动”这一条件被满足时,自动进行数据集保存操作。

例如,以下设置会让 Redis 在满足“60 秒内至少有 1000 个键被改动”这一条件时,自动进行数据集保存操作:

save 60 1000

savebgsave 对比

命令savebgsave
IO类型同步异步
阻塞是(阻塞发生在fock,非常快)
复杂度O(n)O(n)
优点不消耗额外的内存不阻塞客户端命令
缺点阻塞客户端命令fock子进程需要消耗少量内存

RDB 常用持久化配置

# RDB自动持久化规则
# 当 900 秒内有至少有 1 个键被改动时,自动进行数据集保存操作
save 900 1
# 当 300 秒内有至少有 10 个键被改动时,自动进行数据集保存操作
save 300 10
# 当 60 秒内有至少有 10000 个键被改动时,自动进行数据集保存操作
save 60 10000

# RDB持久化文件名
dbfilename dump-<port>.rdb

# 数据持久化文件存储目录
dir /var/lib/redis

# bgsave发生错误时是否停止写入,通常为yes
stop-writes-on-bgsave-error yes

# rdb文件是否使用压缩格式
rdbcompression yes

# 是否对rdb文件进行校验和检验,通常为yes
rdbchecksum yes

RDB的优点

  1. RDB是一个非常紧凑的文件,它保存了某个时间点的数据集快照,适用于数据集的定时备份。
  2. RDB是一个单一文件,可以很方便传送到另一个数据节点,适用于灾难恢复。
  3. RDB在保存RDB文件时父进程只需要 fork 一个子进程,接下来的工作全部由子进程完成,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能。
  4. 通常情况下,在恢复大数据集的时候,RDB方式会比AOF更快一些。

RDB的缺点

  1. 耗时、耗性能。如果设置的备份频率较高,RDB 需要经常 fork 子进程来进行备份操作,当数据集比较大并且服务器性能较差时,fork 可能会比较耗时,从而导致 Redis 在一定时间内(毫秒级-秒级)不能响应客户端的请求。
  2. 不可控、丢失数据。通常RDB以配置方式进行定时备份,如果 redis 意外宕机(例如电源中断),可能会丢失上一次备份到宕机前这段时间的数据。

小伍
139 声望4 粉丝