AOF重写

223 阅读2分钟

这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

AOF重写

上篇文章中我们说到AOF重写时候执行aof_rewrite,如果这个函数进行大量写入可能导致当前服务器线程阻塞,redis是怎么做的呢?

但是这个函数会进行大量的写入操作,调用这个函数的线程将被长时间阻塞,因为redis服务器使用单线程来处理命令请求。所以redis将AOF重写程序放到子进程里执行,这样:子进程进行AOF重写,服务器进程可以继续处理命令,同时因为子进程带有服务器进程的数据副本,不用锁就能数据的安全性。

子进程进行AOF重写期间,服务器进程继续处理命令请求后新命令对现有的数据库状态进行修改,导致当前数据库与重写后的AOF文件不一致。

redis服务器设置一个AOF重写缓存区来解决数据不一致问题,这个缓冲区在服务器创建子进程之后开始使用,当reids服务器执行完写命令后,同时将写命令发送到AOF缓冲区和AOF重写缓冲区

子进程执行AOF重写期间,服务器需要:

  1. 执行客户端发来的命令
  2. 将执行后的写命令追加到AOF缓冲区中
  3. 将执行后的写命令追加到AOF重写缓冲区中

这样AOF缓存区的内容会定期被写入和同步到AOF文件,子进程完成AOF重写工作后,向父进程发送一个信号,父进程在接到该信号后,调用一个信号处理函数,并将AOF重写缓冲区中的所有内容写入到新AOF文件中,这样就保证了数据一致,对新的AOF文件改名,原子操作覆盖现有AOF文件,完成文件的替换,完成父进程可以继续接受命令

AOF重写过程中,只有信号处理函数执行时对服务器进程造成阻塞,其他时候不阻塞

这就是AOF重写原理,即BGREWRITEAOF命令实现原理。