redis aof

aof是append only file,它的好处是增量的,每个操作可以马上写到文件中,不好的地方是里面的记录都是命令,所以不太紧凑。

基本上aof.c和rdb.c接口差不多,都有load,还有Rewrite, RewriteBackground。

load过程(loadAppendOnlyFile): loading的主要思路是fake出一个新的client(这个client的replstate是REDIS_REPL_WAIT_BGSAVE_START,因此server不会给它reply),通过这个client端调用命令达到replay的功能。

aof的缓存有两个,server.aof_rewrite_buf_blocks是一个缓存区链表(每个节点10M),之所以用链表,是因为realloc可能会有很多memory copy效率不高。这个缓冲区链表存在主要是background rewrite在写aof文件的过程中redis数据又被client端做了修改,这样等background rewrite进程一结束,调用backgroundRewriteDoneHandler,就把这些缓存区追加写入aof文件,然后清空这个缓存。

另外一个缓存是server.aof_buf,这个缓存也就是每次有新的操作时都会被写,但它在每次进入event loop时都会被flush然后清空。

文件中有两个startAppendOnly和stopAppendOnly的接口,用于config命令改变appendonlyfile的配置时调用。

rewriteAppendOnlyFileBackground fork出一个子进程调用rewriteAppendOnlyFile,其中有个细节是fork返回主进程时调用下updateDictResizePolicy,就是在有子进程的时候禁止resize(除非元素个数/bucket array size >= 5了),以避免大量的copy-on-write,影响效率也多占内存。

在写aof文件时需要将PEXIRE/EXPIRE都转写成PEXIREAT以使用绝对时间。

关于是否同步调用fsync:

rewrite时调用同步fsync的,事件循环中在beforeSleep调用的flushAppendOnlyFile还有backgroundRewriteDoneHandler中,如果设定aof_fsync为每秒调用,为了省时间就会用bio(ALWAYS也是同步)。

你可能感兴趣的:(redis,源码,AOF)