AOF持久化的实现



AOF 持久化分为 : 命令追加(append)->文件写入->文件同步(sync) 三个步骤


【Redis】Redis AOF持久化_数据

写入AOF文件不就是同步了吗?这里的写入和 同步的区别是什么?


这里的写入AOF文件, 在现代操作系统中,用户调用了write()函数来将数据写入到文件中,但是操作系统通常会将写入的数据暂时保存在一个 ** 内存缓冲区** 里面,等这个缓冲区的空间被填满、或者超过了指定的时限之后,才真正的将缓冲区中的数据写入到磁盘里面;所以 这里的写入AOF文件,实际上可能并没有真正的落到磁盘里面;
这种做法虽然提高了效率,但是也为写入数据带来了安全问题,因为如果这时候计算机掉电,这一部分数据就会丢失
为此系统提供 了 fsync和fdatasync两个同步函数,他们可以强制操作系统立马将缓冲区中的数据写入到磁盘立马!
所有这里说的 同步 就是让缓冲区的数据写入到磁盘从而实现真正的持久化!


AOF文件的载入与数据还原



Redis服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原了服务器关闭之前的数据库状态了


【Redis】Redis AOF持久化_Redis_02

AOF文件重写



AOF文件经过一段时间之后会越来越大, 所以就需要重写AOF文件来减小文件大小;
实际上,AOF文件重写并不需要对现有的AOF文件进行任何读取、分析或者写入操作;这个功能是通过读取 当前数据库状态来实现的;


redis提供了aof_rewrite函数来重写

如果用redis的服务器进程来进行重写,就会影响redis整体的性能;

那么redis实现的方式是 AOF后台重写

AOF后台重写

【Redis】Redis AOF持久化_redis_03

redis 创建一个子进程出来专门做AOF重写操作;

怎么解决AOF在重写的时候,又有新的写命令在执行?


为了解决这种数据不一致的问题,redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当redis服务器执行完了一个写命令之后,它会同事将这个命令发送给 AOF缓冲区和AOF重写缓冲区;


AOF重写缓冲区是怎么被使用的?


当子进程完成AOF重写工作之后,它会向父进程发送一个信号量,父进程在接收到改信号之后,会调用一个信号处理函数,并执行以下操作:
1.将AOF重写缓冲去中的所有内容写入到新的AOF文件中;这是新的AOF文件所保存的数据库状态将和服务器当前的数据库状态一致;
2.对新的AOF文件进行改名,原子的覆盖现有的AOF文件,完成新旧两个AOF文件的替换


这个信号处理函数执行完毕之后,父进程就可以继续像往常一样接受命令了,整个AOF后台重写过程中,只有这个信号处理函数是阻塞主进程的