1、AOF缓冲区实现
添加缓冲区块
如果之前缓冲区链表中的最后一个block没有用完,那么先使用完,如果不够,在创建新的block添加到链表尾,为后续的写做准备
输出缓冲
迭代缓冲区链表,写到文件
2、AOF重写
冲洗AOF文件:void flushAppendOnlyFile(int force)
设置aof同步为AOF_FSYNC_EVENTSEC
服务器端每个事件循环都会将AOF缓冲写到文件上,并且每一秒中都会有线程执行文件到磁盘的同步操作。首先会判断当期啊是否有正在执行的后台线程
如果没有设置强制执行的话,会采取延迟执行同步操作
否则,就会执行写和同步
写失败则删除刚刚改动的那部分
如果有正在进行的aof文件同步或是rdb文件同步,那么就返回,等待下次
3、AOF文件加载
创建伪客户端
用来加载AOF中的命令
加载AOF文件
不断循环在伪客户端上执行AOF中的写命令
4、AOF文件重写
重写API
rioWriteBulkCount:命令+参数技术
格式:"*<count>\r\n"
rioWriteBulkLongLong:long long类型值
格式:$<count>\r\n<payload>\r\n
rioWriteBulkString:string类型值
格式:$<count>\r\n<payload>\r\n
rioWriteBulkDouble:double类型值
格式:$<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去管理(后台线程)