当前位置: 首页 > news >正文

Redis持久化——AOF

介绍

Redis是运行在内存中的数据库,当我们关闭了Redis服务器后,内存中的数据会丢失吗?
答案是不会的,因为Redis有持久化功能,能够将内存中的数据保存到磁盘中的文件,以此来实现数据的永久保存。
在Redis中,有两种持久化功能:

  • RDB持久化功能,简称RDB快照
  • AOF持久化功能,简称AOF日志

关于RDB快照,建议先去看看我的这篇文章Redis持久化——RDB快照_秋天code的博客-CSDN博客

AOF日志

AOF的全称是,Append Only File,日志文件追加写。
AOF日志记录的是每次对数据进行修改的命令,通过这些命令就可以恢复数据库状态
注意:读命令是不会被记录到AOF日志中的,因为不涉及数据的变化。
Redis每执行一条写命令,就会把该命令以追加的方式写入到AOF日志文件中,然后在Redis服务器启动时,就会通过此日志文件中的命令,来恢复数据库状态,大致的工作流程:

在Redis中,默认开启的是RDB持久化功能,并没有开启AOF持久化功能,因此我们修改配置项来开启AOF持久化功能:

appendonly yes // 表示开启AOF持久化(no关闭)
appendfilename "appendonly.aof" // AOF日志文件的名称

AOF日志写回时机

对AOF日志文件追加写的操作是IO操作,肯定是比内存操作要慢的,又因为Redis是单线程的,所以IO操作会阻塞后面的请求,因此为了提高Redis的性能,会在内存中有一块缓冲区,专门用来存放每次写命令产生的AOF日志,将缓冲区中的命令批量写回到AOF文件中。

先来看AOF日志写入的详细流程图:

Redis中提供了3种写回策略,控制以上的第三步,即调用操作系统的IO操作的时机。

在Redis的配置文件中,appendsync配置项就是用来配置AOF的回写策略,有三个值AlwaysEverysecNo

  • Always,每次执行写操作命令完成后,同步将AOF日志写回磁盘
  • Everysec每秒,每次执行写操作命令,会先记录此命令到内存中的AOF缓冲区,隔1秒后,将缓冲区中的AOF日志写回到AOF文件中。
  • No,不由Redis控制写回硬盘的时机,转交给操作系统控制。也就是说,每次写操作命令执行完后,先将命令写入到内存中的AOF缓冲区,再由操作系统来决定何时将此缓冲区中的内存写回到磁盘文件中。

总结这三种策略:

AOF重写机制

AOF日志文件,随着执行写操作的命令次数越来越多,文件的大小会越来越大。
当一个AOF日志文件过大时,就会严重影响性能:当Redis服务器启动时,需要从AOF日志文件中恢复数据,Redis是单线程的,会逐条执行其中的命令,当AOF文件过大时,命令也会很多,整个数据恢复过程就会很慢。

Redis为了避免AOF日志文件过大的问题,提供了AOF重写机制,当AOF文件的大小超过设定的阈值时,Redis就会启动AOF重写机制,来压缩AOF文件
具体的原理是:
AOF重写机制是在重写时,读取当前数据库中的所有键值对,然后将每一个键值对用一条命令记录到新的AOF文件中,等到全部记录完成后,就会将新的AOF文件替换掉旧的AOF文件,AOF文件的体积会大大缩小。(因为一条记录、键值对,可能会对应多次写操作,我们只需要记录最终此键值对的状态即可,因此就会把原来旧的AOF文件中的对同一键值对写的命令,最终替换成一条写命令,所以AOF文件体积会缩小)

AOF和RDB对比

  • AOF日志文件是文本文件,记录的是所有的写命令;而RDB文件是二进制文件,记录的就是数据本身。
  • AOF日志恢复数据的速度较慢,即在服务器启动时占用的时间较长。RDB文件的载入会较快。(因为AOF持久化功能会把AOF日志中的每条命令再执行一遍,当AOF日志非常大时,需要执行的命令就非常多,而且Redis是单线程的,需要一条一条的执行,所以恢复数据的效率较低)

参考文章

  • 《Redis设计与实现》
  • AOF 持久化是怎么实现的? | 小林coding
http://www.lryc.cn/news/128748.html

相关文章:

  • Qt 嵌入Vue项目 flapMap 浏览器兼容性问题
  • 1.SpringMVC接收请求参数及数据回显:前端url地址栏传递参数通过转发显示在网页
  • C++ Primer Plus: 第10章(2)
  • c++中的extern关键字
  • javaScript:快乐学习计时器
  • onnxruntime 支持的所有后端
  • k8s 自身原理 5
  • 机器视觉应用开发什么最重要?
  • React+Typescript使用接口泛型处理props
  • 自定义python文件import导入ModuleNotFoundError: No module named ‘***‘ 问题
  • Codeforces Round 893 (Div. 2)B题题解
  • HTTP响应状态码大全:从100到511,全面解析HTTP请求的各种情况
  • Vue-10.集成.env
  • 强训第33天
  • 【CTF-web】buuctf-[极客大挑战 2019]EasySQL 1(sql注入)
  • 脚本语言与编译语言的区别
  • 大型企业或者组织,组建专属的虚拟局域网,深入理解相关的配置和搭建使用、网络加速和网络优化,可夸地区夸国际使用,深入搞懂每项配置的作用和含义
  • 数据结构:二叉树的递归实现(C实现)
  • MinGW编译运行报错RTTI symbol not found for class ‘XXX‘
  • table表头颜色 element plus
  • 网络安全(自学)
  • FPGA芯片IO口上下拉电阻的使用
  • 掌握指针进阶:一篇带你玩转函数指针、函数指针数组及指向函数指针数组的指针!!
  • 在Docker上部署2台节点,利用Keeplived实现双节点VIP 高可用,不需要关闭Keeplived,实现vip来回切换。
  • leetcode 279. 完全平方数
  • 【从零学习python 】48.Python中的继承与多继承详解
  • 二、编写第一个 Spring MVC 程序(总结项目报 404 问题以及 Spring MVC 的执行流程)
  • okhttp源码简单流程分析
  • SpringBoot整合Shiro实现登录认证,鉴权授权
  • Airbnb开源数据可视化工具Visx