redis 代码解析(2)–持久化 ლ(~•̀︿•́~)つ︻̷┻̿═━一

1.RDB持久化

redis是内存数据库它将自己的数据库状态存储在内存里,如果系统断电怎么办,进程退出怎么办,数据就需要保存,进行持久化操作,可以设置手动执行或者定期执行,保存到RDB文件中.

RDB文件是一个经过压缩的二进制文件,序列化生成后可以保存状态,

RDB文件创建和载入:

SAVE 创建:直接阻塞服务器进程,创建文件

BGSAVE:先派生出一个子进程,由子进程创建RDB

redis的文件载入工作是在服务器启动时自动执行的,所以rdis并没有专门的载入指令,当RDB文件存在时就自动载入

如果开启了AOF 优先载入AOF还原数据库状态,当AOF关闭时才可以使用RDB(RDB要完,凸( •̀_•́ )凸).

当BGSAVE创建子进程执行save时不是阻塞进程的,还可以接受操作,当遇到SAVE,BGSAVE时直接拒绝,遇到BGREWAITEAOF时,bgsave在前时,bgrewaiteaof会延迟到bg执行完,反之bg会被拒绝.

接下来就是redis的自动保存了

通过设置save条件当满足时 就会调用bgsave执行

例如: save 900 1 在900秒内执行至少一次修改就会调用BGSAVE;

redis的默认设置项

save 900 1

save 300 10

save 60 10000 三个条件满足一个即可

这些在saveparam *saveparams;{time_t seconds; int changes;}

数据库还保存了一个dirty计数器(距离上次成功执行RDB 数据库进行了多少次修改)以及一个lastsave属性(unix时间戳,记录上次成功RDB的时间):

检查save条件是否满足 使用serverCron函数 默认每隔100毫秒执行一次,

RDB文件结构:

image.png

开头是REDIS为五个字节,检查是否是RDB文件

db_version为4个字节,是字符串表示的整数,记录RDB文件的版本号

databases包含多个数据库及数据库包含的键值对数据

EOF常量长度为11字节表示正文结束;

check_sum 8字节整数 校验和

databases部分解析:

image.png

对于0 3数据库非空来说,每个数据库都保存着以下结构

image.png

SELECTDB:常量 长1字节.当程序遇到这个值得时候,知道这接下来就是数据库号码db_number 调用select

key_value_pairs部分保存了数据库中的所有键值对数据,如果带有过期时间也会和键值对保存在一起,

结构: type key value

image.png


key总是一个字符串对象,值根据type使用不同value的结构


分析RDB文件:

使用od -c 文件名.rdb 打印rdb文件

使用set MSG "HELLO"

image.png

image.png


2.AOF持久化

aof是通过保存redis数据服务器所执行的写命令来记录数据库状态的

rdb是保存键值信息,而aof保存则是将服务器执行的set 等命令保存到aof中

被写入的aof文件的所有的命令是以redis的命令请求协议保存的纯文本的,

image.png

AOF的实现:

在redisServer结构中有 sds aof_buf;//aof缓冲区;

当执行写时就同时向aof_buf中追加到其末尾

如何做到这种写入与同步呢?(将操作写入到aof文件中)

上文提到过自动判断save条件的 serverCron函数(就是一个定时运行的),所以在每次结束一个事件循环之前,都会调用flushAppendOnlyFile函数 考虑是否将aof_buf写入aof文件

image.png

aof文件载入和还原:就执行aof中的命令创建一个伪客户端,模拟执行写命令


aof重写:(有些键的值被写了多次,只需要保存最后一次的状态就行)减少文件体积和执行次数;

通过该功能redis可以创建一个新的AOF文件来代替现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,

这个新的AOF是通过对读取数据库当前的数据库状态来实现的,并不是去读取原来旧的AOF文件,对于执行了多次的list 加入文件与其保存多次list写操作,还不如直接从数据库直接读当前的list

可以使用后台执行fork一个子线程进行执行写操作写入aof重写缓存区,当redis执行完一个写命令时,将这个命令发送给aof缓存区和aof重写缓存区,

就是说在子进程aof执行重写时,服务器会继续执行客户端命令,并将命令追加到两个区.

完成重写后就向父进程发送信号,并将aof重写缓冲去的数据写入到新的aof文件,对新aof改名,原子性覆盖旧的aof文件




.


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注