技术开发 频道

Redis 2.4:后台线程如何解决aof缺陷?

  解决缺陷2

  backgroundRewriteDoneHandler里同样的把close old-aof-file的工作交给backgroud thread来执行.

aof.c
=========
856 /* Asynchronously close the overwritten AOF. */
857 if (oldfd != -1) bioCreateBackgroundJob(REDIS_BIO_CLOSE_FILE,(void*)(long)oldfd,NULL

   这样关闭old-aof-file的工作被移交到后台任务执行,不再阻塞主线程了,不过没那么简单,如下的特殊场景需要额外处理.

aof enabled
bgrewriteaof start
aof disbled
bgrewriteaof stop
bgrewriteaof handler

   在bgrewriteaof触发之后,关闭了aof功能,这样由于server.appendfd对应old-aof-file文件未被打开, 一旦rename new-aof old-aof, 则会触发一个unlink old-aof-file的行为, 而不是上面说的close才触发unlink行为.为了跳过这种状况,如果发现aof被关闭,通过打开old-aof-file文件增加引用计数的方法解决这个问题.

aof.c
==========
810         if (server.appendfd == -1) {
811             /* AOF disabled */
812
813              /* Don't care if this fails: oldfd will be -1 and we handle that.
814               * One notable case of -1 return is if the old file does
815               * not exist.
*/
816              oldfd = open(server.appendfilename,O_RDONLY|O_NONBLOCK);
817         } else {
818             /* AOF enabled */
819             oldfd = -1; /* We'll set this to the current AOF filedes later. */
820         }

   816行:如果处于aof关闭状态,则打开old-aof-file.

  819行:aof已经是激活状态,不做任何操作.

  这样rename就不再引发unlink old-aof-file, 不会再阻塞主线程.

824         if (rename(tmpfile,server.appendfilename) == -1) {

   处理完rename之后就要来处理old-aof-file了.如果aof是非激活状态,对于new-aof-file文件,我们关闭他即可不需要其它操作,这个close不会引发阻塞,因为这个文件的已经在生成new-aof-file文件的时候做过fsync了.

  如果aof是激活状态, fsync行为递给后台去执行,这块的行为和缺陷1一样.

aof.c
===========
840             if (server.appendfsync == APPENDFSYNC_ALWAYS)
841                 aof_fsync(newfd);
842             else if (server.appendfsync == APPENDFSYNC_EVERYSEC)
843                 aof_background_fsync(newfd);

   解决缺陷3

  引入了延迟bgrewriteaof来避免与bgsave同时写文件,而server.no_appendfsync_on_rewrite参数的设置又避免了bgrewriteaof时主线程出现fsync.

  测试2.4.1的性能确实较之前版有较大的提升,以后会给出测试数据.

0
相关文章