Redis - Redis持久化:AOF和RDB

news2025/2/21 4:11:39

1. 为什么要持久化

  • Redis是内从数据库,宕机后数据会丢失;
  • Redis重启后,为了快速恢复数据,提供了持久化机制;
  • Redis有两种持久化方式:RDB和AOF,这也是Redis无畏宕机与快速恢复数据的杀手锏。

注意:Redis持久化不保证数据的完整性。

当Redis用作DB时,DB数据要完整,所以一定要有一个完成的数据源(文件、MySQL),在系统重启时,从这个完整的数据源中将数据load到Redis中。

2. RDB 快照,让宕机快速恢复

2.1 RDB(Redis DataBase)

RDB(Redis DataBase)是Redis默认的持久化方式。Redis将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。

在做数据恢复时,直接将 RDB 文件中的数据读入内存完成恢复。

2.2 触发快照的方式

  1. 符合自定义配置的快照规则

在 redis.conf 中配置:N 秒内数据集至少有 M 个改动,这一条件被满足时,自动保存一次数据集

# save 3600 1
# save 300 100
# 60 秒内有至少有 1000 个键被改动这一条件时, 自动保存一次数据集
save 60 10000
  1. 命令显示触发,执行 save 或者 bgsave 命令

还可以手动执行命令生成RDB快照,进入 Redis 客户端执行命令 save 或 bgsave 可以生成 dump.rdb 文件, 每次命令执行都会将所有 Redis 内存快照到一个新的rdb文件里,并覆盖原有rdb快照文件。

bgsave的写时复制(COW)机制

Redis 借助操作系统提供的写时复制技术(Copy-On-Write, COW),在生成快照的同时,依然可以正常 处理写命令。简单来说,bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。 bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。此时,如果主线程对这些 数据也都是读操作,那么,主线程和 bgsave 子进程相互不影响。但是,如果主线程要修改一块数据,那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。

save与bgsave对比:

在这里插入图片描述
配置自动生成rdb文件后台使用的是bgsave方式。

  1. 执行 flushall 命令

执行 flushall 命令,也会产生 dump.rdb 文件,但里面是空的,无意义。

  1. 执行主从复制操作 (第一次)

2.3 RDB持久化流程

在这里插入图片描述

  1. Redis父进程首先判断:当前是否在执行save,或bgsave/bgrewriteaof(aof文件重写命令)的子进程,如果在执行则bgsave命令直接返回。

  2. 父进程执行fork(调用OS函数复制主进程)操作创建子进程,这个过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令。

  3. 父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令。

  4. 子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行原子替换。(RDB始终完整)

  5. 子进程发送信号给父进程表示完成,父进程更新统计信息。

  6. 父进程fork子进程后,继续工作。

2.4 RDB的优缺点

2.4.1 优点

  • 适合大规模数据恢复
  • 对数据完整性和一致性要求不高更适合使用
  • RDB 采⽤⼆进制 + 数据压缩的⽅式写磁盘,⽂件体积⼩,数据恢复速度快

2.4.2 缺点

  • Fork的时候,内存中的数据会被克隆一份,大致2倍的膨胀,需要考虑;

  • 虽然Redis在fork的时候使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能;

  • 不保证数据完整性,在备份周期在一定间隔时间做一次备份,所以如果 Redis 意外 down 的话,会丢失最后一次快照以后更改的所有数据。

3. AOF(append-only file),避免宕机数据丢失

3.1 AOF是什么

快照功能并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失 最近写入、且仍未保存到快照中的那些数据。从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方 式: AOF 持久化,将修改的每一条指令记录进文件 appendonly.aof 中(先写入 os cache,每隔一段时间 fsync 到磁盘)。

以日志的形式来记录每个写操作(增量保存),将 Redis 执行过的所有写指令记录下来(读操作不记录),只允追加文件但不可改写文件,Redis 启动之初会读取该文件重新构造数据,换言之,Redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

3.2 AOF持久化实现

配置 redis.conf

# 可以通过修改redis.conf配置文件中的appendonly参数开启 
appendonly yes 
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的。 
dir /path
# 默认的文件名是appendonly.aof,可以通过appendfilename参数修改 
appendfilename "appendonly.aof"

3.3 AOF持久化流程

  1. 命令写入(append)

客户端的请求写命令会被 append 追加到 aof_buf 缓冲区内

  1. 文件同步(sync)

AOF 缓冲区会根据 AOF 持久化策略 [always, everysec, no] 将操作 sync 同步到磁盘的 AOF 文件中

  1. 文件重写(rewrite)

AOF 文件大小超过重写策略或手动重写时,会对 AOF 文件进行重写(rewrite),压缩 AOF 文件容量

  1. 重启加载(load)

Redis 服务器重启时,会重新 load 加载 AOF 文件中的写操作达到数据恢复的目的

3.4 AOF原理

3.4.1 AOF是如何实现的

AOF文件中存储的是redis的命令,同步命令到 AOF 文件的整个过程可以分为三个阶段:

命令传播: Redis 将执行完的命令、命令的参数、命令的参数个数等信息发送到 AOF 程序中。

缓存追加: AOF 程序根据接收到的命令数据,将命令转换为网络通讯协议的格式,然后将协议内容追加到服务器的 AOF 缓存中。

文件写入和保存: AOF 缓存中的内容被写入到 AOF 文件末尾,如果设定的 AOF 保存条件被满足的话,fsync 函数或者 fdatasync 函数会被调用,将写入的内容真正地保存到磁盘中。

命令传播

当一个 Redis 客户端需要执行命令时, 它通过网络连接, 将协议文本发送给 Redis 服务器。服务器在接到客户端的请求之后, 它会根据协议文本的内容, 选择适当的命令函数, 并将各个参数从字符串文本转换为 Redis 字符串对象( StringObject )。每当命令函数成功执行之后, 命令参数都会被传播到AOF 程序。

缓存追加

当命令被传播到 AOF 程序之后, 程序会根据命令以及命令的参数, 将命令从字符串对象转换回原来的协议文本。协议文本生成之后, 它会被追加到 redis.h/redisServer 结构的 aof_buf 末尾。

redisServer 结构维持着Redis 服务器的状态, aof_buf 域则保存着所有等待写入到 AOF 文件的协议文本(RESP)。

文件写入和保存

每当服务器常规任务函数被执行、 或者事件处理器被执行时, aof.c/flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作:
WRITE:根据条件,将 aof_buf 中的缓存写入到 AOF 文件。
SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。

3.4.2 AOF日志记录的内容有哪些?

当 Redis 接受到 “set key value” 命令将数据写到内存后,Redis 会按照如下格式写⼊ AOF ⽂件。

这是一种resp协议格式数据,星号后面的数字代表命令有多少个参数,$号后面的数字代表这个参数有几个字符。

  • *3:命令有3个部分
  • $3:后面紧跟具体的指令,指令的字长

在这里插入图片描述

3.4.3 AOF保存模式 - 三种写入策略

可以在 redis.config 中配置 Redis 多久将数据 fsync 到磁盘一次:

# If unsure, use "everysec".
# 每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。
# appendfsync always
# 每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据。
appendfsync everysec
# 从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择:
# appendfsync no

推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。

always 策略在实践中非常慢,但它支持组提交,因此如果有多个并行的写入操作,Redis 将尝试执行单个 fsync 操作。

3.5 AOF重写

3.5.1 AOF重写机制介绍

随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件体积。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。

3.5.2 AOF重写机制原理

重写后的AOF文件为什么可以变小?有如下原因:

  1. 进程内已经超时的数据不再写文件。

  2. 旧的AOF文件含有无效命令,比如,我们调用INCR test命令100次,文件中就必须保存全部的100条命令,但其实99条都是多余的。因为要恢复数据库的状态其实文件中保存一条SET test 100就够了。

  3. 多条写命令可以合并为一个,如:lpush list a、lpush list b、 lpush list c 可以转化为:lpush list a b c。

为了防止合并的数据过大造成客户端缓冲区溢出,对于list、set、hash、zset等类型,以64个元素为界拆分为多条。

  • AOF 重写实现:
    在这里插入图片描述

  • Redis 7.0 中 Multi Part AOF 实现:
    在这里插入图片描述

3.5.3 触发 AOF 重写方式

  1. Redis 客户端手动触发

进入redis客户端执行命令 bgrewriteaof 重写AOF

  1. 配置 redis.config
# aof 文件自上一次重写后文件大小增长了100%,则再次触发重写机制,比如说,上次AOF文件容量为100M,这次文件已经到200M了,则自动触发重写机制
auto-aof-rewrite-percentage 100
# aof 文件至少要达到64M才会触发自动重写,文件太小,恢复速度很快,重写意义不大
auto-aof-rewrite-min-size 64mb

3.6 AOF 的优缺点

优点

具有更高的数据安全性,AOF 默认同步策略为每秒同步一次,因此即使 Redis 服务出现问题,那么最多也只会丢失最近一秒内修改的数据。AOF 文件采用追加的形式进行保存,因此即使在写入过程中出现问题,也不会破坏日志文件中已经存在的内容;如果当我们的写入过程只进行了一半就出现了问题,那么在下一次 Redis 启动之前,我们可以通过 redis-check-aof 工具来帮助我们解决数据一致性的问题当日志文件过大时,我们可以通过重写机制来对 AOF 文件进行重写AOF 文件有序地保存了对数据库执行的所有写入操作,格式十分清晰,易于理解

缺点

  • 数据的完整性和一致性更高相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB在恢复大数据集时的速度比 AOF 的恢复速度要快。

  • 同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。当我们采用同步禁用 (appendfsync no) 策略时,其效率和 RDB 相同

  • 数据的完整性和一致性更高因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。

  • 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

4. RDB 和 AOF 对比

在这里插入图片描述

  • 官方推荐2个都启用

  • 内存数据库:使用 rdb+aof - 数据不容易丢

  • 用作缓存服务器,对数据不敏感:使用rdb - 性能高

  • 不建议只使用 aof - 性能差

  • 在数据还原时:有rdb+aof,则还原aof,因为RDB会造成文件的丢失,AOF相对数据要完整。只有rdb,则还原rdb。

  • 追求高性能:都不开,redis宕机则从数据源恢复

5. Redis 4.0 混合持久化

重启 Redis 时,我们很少使⽤ rdb 来恢复内存状态,因为会丢失⼤量数据。我们通常使⽤ AOF ⽇志重放,但是重放 AOF ⽇志性能相对 rdb 来说要慢很多,这样在 Redis 实例很⼤的情况下,启动需要花费很⻓的时间。

Redis 4.0 为了解决这个问题,带来了⼀个新的持久化选项——混合持久化。将 rdb ⽂件的内容和增量的 AOF ⽇志⽂件存在⼀起。这⾥的 AOF ⽇志不再是全量的⽇志,⽽是⾃持久化开始到持久化结束的这段时间发⽣的增量 AOF ⽇志,通常这部分 AOF ⽇志很⼩。

在 redis.conf 文件可以开启混合持久化(必须先开启aof

# aof‐use‐rdb‐preamble yes

如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将 重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一 起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改 名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。

于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重启效率大幅得到提升。

混合持久化AOF文件结构如下
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/107957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全球代表供应商!腾讯安全NDR再获Gartner认可

近日,国际研究机构Gartner发布了2022年《Market Guide for Network Detection and Response》(《网络检测和响应(NDR)市场指南》)(以下简称《报告》),腾讯安全被Gartner列为全球NDR市…

非零基础自学Golang 第17章 HTTP编程(上) 17.3 爬虫框架gocolly 17.3.1 gocolly简介

非零基础自学Golang 文章目录非零基础自学Golang第17章 HTTP编程(上)17.3 爬虫框架gocolly17.3.1 gocolly简介第17章 HTTP编程(上) 17.3 爬虫框架gocolly 我们在之前学习了如何使用标准库实现HTTP爬虫【其实也不算,就实现了简单的请求,但是爬虫不就是这…

别乱用了,用新的。Go SliceHeader 和 StringHeader 将会被废弃!

大家好,我是煎鱼。Go 语言中有个很经典的 (Slice|String)Header,经常出现在大家视野中,为此我写了《Go SliceHeader 和 StringHeader,你知道吗?》给大家介绍,避免被面试官卷到。以重点来讲,Slic…

Alibaba送给开发人员的“礼物”:Java架构成长笔记,深入内核,拒绝蒙圈

提起阿里,行外人联想到的关键词无非是“交易”、“淘宝”、“支付宝”,但对于程序员来说,阿里庞大的技术体系才是最吸引人的。实际上阿里作为国内一线互联网公司的头把交椅,内部的技术体系和发展都是备受关注的,对于程…

【javaScript总结归纳】字符串常用方法总结

前言 在js中我们对字符串进行一部分截取,可以使用slice()函数截取,也可以直接用substring()函数来截取,但是截取也有可能出bug const str小𠮷和小𧨁今天吃了50块钱的KFC console.log(str.slice(0,5)); 可以在控制台看…

评估EtherCAT从站节点解决方案

本系列博客文章的第1部分介绍了用于C2000™微控制器的EtherCAT从站堆栈解决方案的市场机遇,以及从站堆栈开发快速入门的三个阶段指南。第2部分详细说明了TIC2000 MCU EtherCAT实施的特点和优势。第3部分分别介绍了使用EtherCAT从站和C2000 Delfino MCU controlCARD套…

Linux【windows使用xshell连接本地虚拟机】【Mac使用terminal连接本地虚拟机】

文章目录对于本地虚拟机的配置使用Mac的terminal的ssh连接本地虚拟机windows使用xshell连接本地虚拟机对于本地虚拟机的配置 IP地址和子网掩码。 在虚拟机中使用ping命令判断虚拟机到宿主机是否是连通的。(不通的话,关闭Windows防火墙,再试一…

python+pyhyper实现识别图片中的车牌号

背景 最近领导给布置了一个基于图片识别车牌号的工具开发任务,然后就去研究实现逻辑,自己根据opencv写了一个小demo,发现不仅速度慢而且成功率极低。然后,就找到了Hyperlpr开源项目。 环境搭建 排雷1:有教程说在git…

动态内存管理易错点+分析例题

复习一下: 常见的错误: 1.可能返回的是空指针 2.对动态开辟的内存越界访问 3.非动态开辟内存却用free释放 4.使用free释放动态开辟内存的一部分 5.free多次释放 如果加了pNULL的话 free(p)相当于啥也不干 程序起码不会崩掉 6.动…

RabbitMQ、RocketMQ、Kafka延迟队列实现

延迟队列在实际项目中有非常多的应用场景,最常见的比如订单未支付,超时取消订单,在创建订单的时候发送一条延迟消息,达到延迟时间之后消费者收到消息,如果订单没有支付的话,那么就取消订单。 那么&#xf…

Proteus8仿真:51单片机IrLink红外发送加接受模块的使用

51单片机IrLink红外的使用元器件原理图部分代码单片机1发送main.c单片机2接受main.c工程文件元器件 元器件名称51单片机AT89C51红外收发IRLINK按键BUTTON发光二极管LED-RED时钟激励源DCLOCK与门74LS08示波器 原理图部分 关于IRLINK的使用: 在Proteus上就是一个红外…

数据中台选型前必读(七):解读数据服务的四大关键技术

在前面的文章中,我们介绍了“数据服务”对于“数据中台”的重要性,并讲解了数据服务解决的问题及其核心功能,在这个系列的最终篇我们展开聊聊数据服务的四大关键技术,然后总结一下数据服务架构的三大关键点,希望对大家…

JSP ssh培训管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh 培训管理系统是一套完善的web设计系统(系统采用ssh框架进行设计开发),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Mye…

校园打架行为识别检测 yolov7

校园打架行为识别检测系统基于python基于yolov7深度学习框架边缘分析技术,自动对校园、广场等区域进行实时监测,当监测到有人打架斗殴时,系统立即抓拍存档语音提醒,并将打架行为回传给学校后台,提醒及时处理打架情况。…

Word控件Spire.Doc 【超链接】教程(7):在 C#、VB.NET 中的 Word 中创建图像超链接

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下,轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具,专注于创建、编辑、转…

你一定要会的JavaFile

File对象就表示一个路径,可以是文件的路径,也可以是文件夹的路径这个路径可以是存在的,也允许是不存在的File的构造 方法名称说明public File(String pathname)根据文件路径创建文件对象public File(String parent,String child)根据父路径名…

第4章 角色Api控件器的实现与调试

1 自定义管道中间件 1.1 WebApi.Middleware.CorsMiddleware namespace WebApi.Middleware { /// <summary> /// 【跨域访问中间件--类】 /// <remarks> /// 摘要&#xff1a; /// 该管道中间件类主要为了解决在由vue/uni-app前端项目(Cors)访问当前后端项…

你的期待薪资是多少?为什么?

很多人去面试的时候&#xff0c;就像打游戏&#xff0c;过五关斩六将&#xff0c;终于到最后一关了&#xff0c;但是谈薪资的难度堪比打游戏中搞定终级 boss 的难度&#xff0c;真的是太「南」了&#xff0c;好多人都是因为这个问题让自己五味杂陈呀。报高了怕好 offer 失之交臂…

【Call for papers】SIGIR-2023(CCF-A/内容检索/2023年1月31日截稿)

The 46th International ACM SIGIR Conference on Research and Development in Information Retrieval will be held from 23-27 July, 2023 in Taipei. 文章目录1.会议信息2.时间节点3.论文主题1.会议信息 会议介绍&#xff1a; SIGIR是展示新研究成果和展示信息检索新系统和…

Postgresql INDEX HOT 原理与更好的 “玩转” INDEX

随着问问题的同学越来越多&#xff0c;公众号内部私信回答问题已经很困难了&#xff0c;所以建立了一个群&#xff0c;关于各种数据库的问题都可以&#xff0c;目前主要是 POSTGRESQL, MYSQL ,MONGODB ,POLARDB ,REDIS&#xff0c;SQL SERVER 等&#xff0c;期待你的加入&#…