我爱编程redis学习

AOF持久化

2018-05-23  本文已影响0人  茶还是咖啡

AOF持久化功能的实现可以分为追加(append)、文件写入(write)、文件同步(sync)三个步骤。

数据持久化

当aof持久化处于打开状态时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾。

struct redisServer{
    //...

    //AOF缓冲区
    sdshdr aof_buf;

    //...
};

AOF文件的写入与同步

Redis的服务器进程是一个时间循环,每次结束一个时间循环之前调用flushAppendOnlyFile函数,考虑是否将缓冲区中的内容写入和保存到AOF文件里面。
FlushAppendOnlyFile函数的行为由服务器中的appendfsync选项的值来决定。
appendfsync选项的值 flushAppendOnlyFile函数的行为
always 将aof_buf缓冲区中的所有内容写入并同步到AOF文件中
everysec 将aof_buf缓冲区中所有内容写入到AOF文件,如果上次同步aof文件的时间距离现在超过1秒,那么再次对aof文件进行同步,并且这个同步操作是由一个线程专门负责的。
no 将aof_buf缓冲区中的所有内容写入到AOF文件,但并不对AOF文件进行同步,何时同步由操作系统决定。
为了提高文件的写入效率,用户调用write函数,将一些数据写入到文件的时候,操作系统会将写入的数据暂时保存在一个内存缓冲区里面,等到缓冲区满了,或者超过指定时间之后,才能将缓冲区中的数据写入到磁盘里面。
这种做法虽然提高了效率,但是也为数据安全带来了问题,如果数据出现停机,那么缓冲区中保存的数据会丢失。

效率和安全性:
Always是效率最低的一个,但是时最安全的,everysync效率很高,即使数据库宕机,也仅仅是最多丢失最近1秒的数据。No的文件写入由操作系统决定,所以效率最快,但是如果出现数据库宕机,那么会丢失上一次同步AOF文件之后的所有命令数据。

载入与还原

原理:AOF文件包含了重建数据库的所有写命令,所以只要执行AOF文件中的命令就可以还原数据库。服务器会创建一个伪客户端,从AOF文件中读出指令并执行。

AOF的重写

首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令。
AOF重写程序会调用aof_rewrite函数,他可以很好的创建一个新的AOF文件,所以调用这个函数的线程将会被长时间阻塞。
所以redis将AOF重写程序放到子程序中执行,这样可以在子进程进行AOF重写期间,父进程可以继续工作。
子进程带有服务器进程的数据副本,使用子进程不使用线程可以避免不使用锁的情况下保证数据的安全性。
但是子进程AOF重写期间如果父进程处理的执行对数据库原有的状态进行了修改,会导致数据不一致的问题。
为了解决这一问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在创建子进程之后开始使用,当Redis服务器完成一个写命令之后,他会同步将这个写命令发送给AOF缓冲区和AOF重写缓冲区。


image.png

当子进程完成AOF重写工作之后,会向父进程发送一个信号,父进程接收到该信号之后会调用一个信号处理函数并执行并执行一下工作:

  1. 将AOF重写缓冲区中的所有数据都写入到AOF文件中,这时新的AOF文件中所保存的数据库的状态和服务器当前的数据库状态一致。
  2. 原子性的覆盖现有的AOF文件完成新旧两个AOF文件的替换。
    整个AOF重写过程只有信号处理函数会阻塞服务器造成阻塞,所以AOF重写将服务器的性能影响降到了最低。
上一篇 下一篇

猜你喜欢

热点阅读