Redis持久化之RDB
Redis提供了2个不同形式的持久化策略:RDB (redis database)AOF (append of file)这篇文章则记录一下我学习RDB过程中的一些笔记,分享给大家。RDB 模式rdb是redis默认的持久化策略,在RDB模式下,可以将redis在内存中的数据库状态保存到磁盘里面(以内存快照的形式),避免数据意外丢失。RDB持久化功能既可以手动执行,也可以通过配置文件定期执行。RD
Redis提供了2个不同形式的持久化策略:
- RDB (redis database)
- AOF (append of file)
这篇文章则记录一下我学习RDB过程中的一些笔记,分享给大家。
目录
RDB 模式
rdb是redis默认的持久化策略,在RDB模式下,可以将redis在内存中的数据库状态保存到磁盘里面(以内存快照的形式),避免数据意外丢失。
RDB持久化功能既可以手动执行,也可以通过配置文件定期执行。
RDB通过生成一个经过压缩的二进制文件,保存数据库状态,可以通过该文件进行还原。
1 Redis何时创建rdb文件以及何时载入
redis创建rdb文件有两种方式:
①手动执行SAVE或BGSAVE时;
②满足配置条件进行rdb持久化时;
1.1 SAVE和BGSAVE命令
SAVE命令和BGSAVE命令都可以生成RDB文件,这两种命令以不用的方式调用 rdbSave 函数完成RDB文件的生成。
SAVE命令是阻塞式的创建RDB文件,阻塞Redis服务器进程,直到RDB文件创建完毕;
BGSAVE则会fork一个子进程,由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令;
通过以下伪代码可以看出两个命令的差别:
def SAVE():
rdbSave()
def BGSAVE():
# 创建子进程
pid = fork()
if pid == 0:
# 子进程负责创建RDB文件
rdbSave()
# 完成后向父进程发送信号
signal_parent()
elif pid > 0:
# 父进程继续处理请求,饼通过轮询等待子进程信号
handle_request_and_wait_signal()
else:
# 处理出错情况
handle_fork_error()
SAVE命令执行时:服务器处于阻塞状态,所有客户端请求都会被拒绝。
BGSAVE执行时:由于保存工作是由子进程执行,在BGSAVE过程中redis服务器仍然可以处理客户端请求,但是处理SAVE、BGSAVE、BGREWRITEAOF会有所不同:
- BGSAVE执行过程中,服务器拒绝SAVE请求,避免产生2个rdbSave()调用,防止产生竞争条件
- BGSAVE执行过程中,服务器拒绝BGSAVE请求,避免产生2个rdbSave()调用,防止产生竞争条件
- BGSAVE和BGREWRITEAOF(AOF重写命令,后面详细说明)命令不能同时执行,如果BGSAVE执行中,BGREWRITEAOF命令会延后到BGSAVE命令执行完毕后执行。如果BGREWRITEAOF执行中,BGSAVE则会被服务器拒绝。因为这两个指令都是由子进程完成,并发出2个子进程并同时执行大量磁盘写入操作,影响性能。
1.2 通过配置文件配置RDB策略
Redis允许用户通过配置文件(一般情况下在/etc/redis/redis.conf)修改save选项,定期自动执行一次BGSAVE命令。且可以同时设置多个保存条件,只要满足任意一个条件,就会执行BGSAVE。
意思是服务器在 seconds 秒以内完成 changes 次修改,则会自动执行一次RDB持久化。下面是REDIS在执行RDB持久化时的打印日志:
我添加了一项 SAVE 30 5 的策略,30秒内服务器发生5次数据修改,则进行一次RDB。如上图。
1.3 Redis何时载入rdb文件
RDB文件载入是在服务器启动的时候自动进行的,当服务器启动时检测到RDB文件(默认当前目录下的rdb文件)就会自动载入。以下是redis-server启动时打印日志,其中DB loaded from disk:...就是成功载入RDB文件后打印的。RDB文件载入时,服务器一直会处于阻塞状态,直到完成。
RDB文件名默认为dump.rdb,可以通过配置文件 rdbfile修改:
RDB文件默认保存目录为服务器启动目录(建议修改为绝对路径),可以通过配置dir修改:
2 原理实现
redisServer结构保存了一个saveparams属性:
saveparms是一个数组,每个元素都是saveparam结构,每个saveparam结构保存了一个save选项保存条件
比如默认条件下,服务器状态的saveparms数组样子如下:
除了saveparams数组外,redisServer结构还保存了一个dirty计数器和一个lastsave属性。dirty计数器记录距离上次执行SAVE或BGSAVE后,服务器修改了多少次;lastsave属性是一个unix时间戳,记录了上次成功SAVE/BGSAVE的时间。
当服务器成功执行一个数据库修改命令以后,会对dirty计数器进行更新。如
dirty计数器的值会+1
dirty计数器的值会+3
redis服务器周期性操作函数severCron默认每隔100毫秒执行一次,该函数用户对正在运行的服务器进行维护,其中一项工作就是检查save选项设置保存的条件是否满足,如果满足就执行BGSAVE命令。
举个例子,redis-server的当前状态如下:
当时间到1378270800+301=1378271101之后,服务器将自动执行BGSAVE命令,因为saveparams数组的第二个保存条件(300秒之内有10次修改)已经被满足。
3 RDB的优缺点
优点:
①由于rdb文件是二进制存储的,节省磁盘空间。
②由于rdb保存的是数据库状态快照,恢复速度快。
缺点:
①虽然redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能
②由于rdb的save策略,如果redis服务器意外宕机,会导致最后一次保存快照后的修改数据丢失。
更多推荐
所有评论(0)