持久化
持久化(Persistence),即把内存中的数据保存到磁盘中。
持久化的实现方式
快照式
在某个时刻把所有数据进行完整备份。
例:MySQL 的 Dump 方式、Redis 的 RDB 方式。
日志式
把用户执行的所有写指令(增删改)备份到文件中,还原数据时只需要把备份的所有指令重新执行一遍即可。
例:MySQL 的 Binlog、Redis 的 AOF、Hbase 的 HLog。
RDB简介
默认情况下, Redis 将数据库快照保存在名为 dump.rdb
的二进制文件中。
当 Redis 需要保存 dump.rdb
文件时, 服务器执行以下操作:
- Redis 调用 forks 派生一个子进程。父进程和子进程同时存在。
- 子进程将当前内存中的数据库快照写入到一个临时 RDB 文件中。
- 当子进程完成对新 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
save
与 bgsave
对比
命令 | save | bgsave |
---|---|---|
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的优点
- RDB是一个非常紧凑的文件,它保存了某个时间点的数据集快照,适用于数据集的定时备份。
- RDB是一个单一文件,可以很方便传送到另一个数据节点,适用于灾难恢复。
- RDB在保存RDB文件时父进程只需要 fork 一个子进程,接下来的工作全部由子进程完成,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能。
- 通常情况下,在恢复大数据集的时候,RDB方式会比AOF更快一些。
RDB的缺点
- 耗时、耗性能。如果设置的备份频率较高,RDB 需要经常 fork 子进程来进行备份操作,当数据集比较大并且服务器性能较差时,fork 可能会比较耗时,从而导致 Redis 在一定时间内(毫秒级-秒级)不能响应客户端的请求。
- 不可控、丢失数据。通常RDB以配置方式进行定时备份,如果 redis 意外宕机(例如电源中断),可能会丢失上一次备份到宕机前这段时间的数据。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。