Redis源码阅读之aof.c

来源:互联网 发布:歼十外销知乎 编辑:程序博客网 时间:2024/05/28 20:19

1AOF缓冲区实现

添加缓冲区块

如果之前缓冲区链表中的最后一个block没有用完,那么先使用完,如果不够,在创建新的block添加到链表尾,为后续的写做准备



输出缓冲

迭代缓冲区链表,写到文件


2AOF重写

 

冲洗AOF文件:void flushAppendOnlyFile(int force)

设置aof同步为AOF_FSYNC_EVENTSEC

服务器端每个事件循环都会将AOF缓冲写到文件上,并且每一秒中都会有线程执行文件到磁盘的同步操作。首先会判断当期啊是否有正在执行的后台线程


如果没有设置强制执行的话,会采取延迟执行同步操作


否则,就会执行写和同步

写失败则删除刚刚改动的那部分

如果有正在进行的aof文件同步或是rdb文件同步,那么就返回,等待下次

 

3AOF文件加载

创建伪客户端

用来加载AOF中的命令

 

加载AOF文件

不断循环在伪客户端上执行AOF中的写命令

 

4AOF文件重写

重写API

rioWriteBulkCount:命令+参数技术

格式:"*<count>\r\n"

 

rioWriteBulkLongLonglong long类型值

格式:$<count>\r\n<payload>\r\n

 

rioWriteBulkStringstring类型值

格式:$<count>\r\n<payload>\r\n

 

rioWriteBulkDoubledouble类型值

格式:$<count>\r\n<payload>\r\n

 

重写列表对象

rewriteListObject:根据不同的底层编码类型,将列表中的元素挨个写入AOF,使用命令RPUSH格式

 

重写集合对象

rewriteSetObject:根据不同的底层编码类型,将集合中的元素挨个写入AOF,使用命令SADD格式

 

重写有序集合对象

rewriteSortedSetObject:根据不同的底层编码类型,将集合中的元素挨个写入AOF,使用命令ZADD格式

 

重写哈希对象

rewriteHashObject:根据不同的底层编码类型,选择将KEY还是VALUE写入AOF中,使用HMSET

 

重写AOF文件

遍历数据库,针对不同的对象,执行不同的对象重写(对象有过期键时间同样需要写入)


重写完成之后,文件内容同步到磁盘


重命名


 

后台执行AOF文件重写

调用命令BGREWRITEAOF

REDIS调用fork,执行rewriteAppendOnlyFileBackground

  • 子进程在临时文件中重写
  • 父进程将这段时间的写入命令添加server.aof_rewrite_buf


子进程结束之后就退出

父进程在检查子进程的状态


 

后台执行AOF文件重写工作完成

查看完成是否成功,如果完成失败,打印日志

  • 由于信号引起
  • 由于自身的一些错误

如果执行成功,父进程就会将server.aof_rewrite_buf直接添加到临时文件末尾


重命名临时文件

  • 如果AOF在配置文件中是disabled,那么重命名之后就不要去设置文件描述符了
  • 如果AOF原先是enabled,那么就要替换原来的文件描述符


为了尽量减少unlink原来AOF文件带来的阻塞影响,这里采取的措施是直接打开原来的文件描述符,然后交给后台IO去管理(后台线程)


0 0