Redis是内存数据库,它将本身的数据库状态存储在内存里面,因此若是不想办法将存储在内存中的数据库状态保存到磁盘,那么服务器 进程一旦退出,服务器中的数据库状态也会消失不见。redis
为了解决这个问题,Redis提供了RDB持久化功能,这个功能能够将数据库状态保存到磁盘里面算法
一、RDB文件的建立与载入数据库
Redis可使用SAVE或BGSAVE命令建立RDB文件。数组
SAVE命令会阻塞服务器进程,直到RDB文件建立完毕,在服务器阻塞过程当中服务器不能处理任何命令,因此此时客户端发送来的命令都会被拒绝。服务器
BGSAVE命令会派生一个子线程,而后由子线程负责建立RDB文件,服务器进程(主进程)继续处理命令。app
RDB文件的载入是在服务器启动时自动执行,因此Redis并无专门载入RDB文件的命令,只要Redis服务器在启动时检测到RDB文件存在,它就会自动载入。函数
因为AOF文件的更新频率一般比RDB文件更新频率高,因此若是服务器开启了AOF,那么服务器优先从AOF文件还原数据库,只有AOF关闭时,服务器才会使用RDB文件还原数据库。学习
BGSAVE命令执行时,Redis服务器处理SAVE、BGSAVE、BGREWRITEAOF命令方式会与平时不一样。编码
一、SAVE命令会被服务器拒绝,服务器禁止SAVE、BGSAVE命令同时执行,是为了不主线程与子线程同时执行rdbSave产生竞争条件。spa
二、BGSAVE命令一样也会被拒绝,由于两个BGSAVE命令也会产生竞争条件。
三、BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕后执行,若是 BGREWRITEAOF命令正在执行,那么客户端发送的BGSAVE命令会被服务器拒绝。
RDB文件载入时,服务器会处在阻塞状态,直到载入工做完成。
Redis使用BGSAVE命令自动间隔保存。
一、RDB文件的建立与载入
Redis可使用SAVE或BGSAVE命令建立RDB文件。
SAVE命令会阻塞服务器进程,直到RDB文件建立完毕,在服务器阻塞过程当中服务器不能处理任何命令,因此此时客户端发送来的命令都会被拒绝。
BGSAVE命令会派生一个子线程,而后由子线程负责建立RDB文件,服务器进程(主进程)继续处理命令。
RDB文件的载入实在服务器启动时自动执行,因此Redis并无专门载入RDB文件的命令,只要Redis服务器在启动时检测到RDB文件存在,它就会自动载入。
因为AOF文件的跟新频率一般比RDB文件更新频率高,因此若是服务器开启了AOF,那么服务器优先从AOF文件还原数据库,只有AOF关闭时,服务器才会使用RDB文件还原数据库。
BGSAVE命令执行时,Redis服务器处理SAVE、BGSAVE、BGREWRITEAOF命令方式会与平时不一样。
一、SAVE命令会被服务器拒绝,服务器禁止SAVE、BGSAVE命令同时执行,是为了不主线程与子线程同时执行rdbSave产生竞争条件。
二、BGSAVE命令一样也会被拒绝,由于两个BGSAVE命令也会产生竞争条件。
三、BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕后执行,若是 BGREWRITEAOF命令正在执行,那么客户端发送的BGSAVE命令会被服务器拒绝。
RDB文件载入时,服务器会处在阻塞状态,直到载入工做完成。
Redis使用BGSAVE命令自动间隔保存。
struct redisServer{ //记录了保存条件的数组 struct saveparam *saveparams; //修改计数器 long long diry; //上一次执行保存的时间 time_t lastsave; } save选项的保存条件: struct saveparam{ //秒数 time_t seconds; //修改次数 int changes; }
Redis的服务器周期性操做函数serverCron默认100毫秒执行一次,用于维护正在运行的服务器,他的一项工做就是检查save选项所设置的保存条件是否已经知足,若是知足则执行BGSAVE命令。
RDB文件结构
RDB文件中的数据库结构示例
Redis 标识时Redis数据库RDB文件
db_version 文件版本
selectdb 标识后面是查询的第几个数据库。
pairt 保存着该数据库的全部键值对以及过时时间
EOF 标识内容结束
check_sum 校验和,用来检测RDB文件是否正确有无损坏。
VALUE编码:
一、字符串对象
redis支持压缩存储,若是不压缩的状况下,存储len与字符串;若是压缩则结构以下:
REDIS_RDB_ENC_LZF常量标志着字符串被LZF算法压缩,读入陈旭在碰到这个常量时会根据compressed_len(压缩后长度),orgin_len(原长度)和compressed_string (压缩后字符串)三个部分,对字符串进行解压缩。
二、列表对象
list_length记录了列表长度。tiem每一项都是一个字符串,程序读入时按字符串对象读入。
三、集合对象 存储方式与列表对象类似。
四、哈希表对象
其中key_value_pair结构中的键值对以键紧挨值的方式排列。
五、有序结合对象
天天学一点,总会有收获。
说明:尊重做者知识产权,文中内容参考《Redis设计与实现》,仅在此作学习与你们分享。