redis持久化之AOF

AOF持久化

将redis服务器所执行的写命令来记录数据库状态,并保存到AOF文件中。

1. 持久化的实现

  1. 命令追加
    服务器在执行完一个写命令之后,该命令会被追加到服务器状态的aof_buf缓冲区的末尾

     	struct redisServer {
     		// AOF缓冲区
     		sds aof_buf;
     	}
    
  2. 写入与同步
    服务器在结束一个事件循环之前,会调用flushAppendOnlyFile来判断是否要将aof_buf缓冲区的内容写入AOF文件中,根据不同的appendfsync实现不同的追加逻辑:

    1. always 将缓冲区的所有内容写入并同步到AOF文件;
    2. everysec 每一秒同步一次缓冲区的数据到AOF文件中;(默认选项)
    3. no 何时同步有操作系统决定。

特别注意的是:appendfsync的选项直接决定AOF持久化的效率和安全性

always会很大程度上影响redis服务器的性能,效率是最低的,但是由于每一次的写操作都会触发一次同步AOF文件的操作,也是最安全的,宕机情况下只会丢失一个事件中所产生的命令。(redis以事件为单位的)
everysec 是在企业中普遍使用的模式,效率上也够快,发生宕机的话最多也就丢失一秒的命令。
no 因为不需要执行同步操作,所以AOF写入速度是最快的,但是会在系统缓存中积累一段时间的写入数据,所以单次同步间隔的时长是最长的,效率和everysec相当,但是一旦出现故障,上次同步之后的写命令都会丢失。

2. 文件载入和数据还原

redis读取AOF文件并还原数据库状态:

  1. 创建一个不带网络的fake client;
  2. 从AOF文件中解析出一条命令;
  3. 执行该命令;
  4. 直到所有命令都处理完。
    然后就完成了。

3. AOF重写

为了解决AOF文件体积膨胀的问题。

3.1 重写实现

不是对原来的AOF文件进行读取、分析或写入操作,新的AOF文件是直接读取当前数据库的状态来实现的。
本质是为了减少AOF文件文件中命令的数目,操作如下:首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令,这就是实现AOF重写的原理。

3.2 后台重写

为解决aof_rewrite阻塞主进程,服务器的主进程会fork一个子进程来进行重写操作;
同时还面临一个问题,主进程在AOF重写的时候也会处理新的写命令请求,那么当重写结束之后,数据库的状态和重写后的状态不一致。
在原先AOF缓冲区的基础上又会新增一个AOF重写缓冲区,当主进程处理一个新的写命令的时,先执行该命令,后将其正常放入AOF缓冲区中,新增一步就是将其放入AOF重写缓冲区。
保证:

  1. AOF缓冲区内容会定期写入和同步到AOF文件
  2. 从创建子进程开始,服务器执行的写命令都会记录到AOF重写缓冲区中。
    当子进程完成AOF重写之后,会向父进程发送一个信号,之后父进程会将AOF重写缓冲区中的所有内容写入新的AOF文件中,此时AOF文件中保存的数据库状态和服务器当前的状态一致。
    随后对新的AOF问文件进行改名,atomic原子性地覆盖原有的AOF文件,完成新旧文件的替换。
    整个后台重写过程中只有信号处理函数执行时会对服务器进程进行阻塞,因此AOF后台重写对服务器性能的影响降到了最低。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hewesH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值