首页 > 数据库 >(七)Redis 持久化 AOF、RDB

(七)Redis 持久化 AOF、RDB

时间:2024-08-12 09:27:04浏览次数:14  
标签:AOF 快照 Redis RDB 日志 数据

Redis 一旦服务器宕机,内存中的数据将全部丢失,从后端数据库恢复这些数据,对数据库压力很大,且性能肯定比不上从 Redis 中读取,会拖慢应用程序。所以,对 Redis 来说,实现数据的 持久化 ,避免从后端数据库中进行恢复,是至关重要的。

1、AOF 日志

AOF 日志是先执行命令,把数据写入内存,然后才记录日志以文本形式保存,如下图:"*3" 表示命令有三个部分组成,每部分由"$+数字"开头,"$3 set"表示这部分有三个字节,指"set"命令,"$7 testkey"表示该部分有七个字节,即"testkey"命令,以此类推。
AOF 写后日志只有命令能执行成功,才会被记录到日志中,避免额外的检查开销,也避免了出现记录错误命令的情况,而且不会阻塞当前的写操作。说完 优点 风险 ,如果刚执行完命令还没有来得及记日志就宕机了,就有丢失的风险。其次,AOF 日志在主线程中执行,如果在把日志文件写入磁盘压力过大,可能会带来阻塞风险。

AOF 风险与写回磁盘有关,针对这个问题提供了三种 写回策略 ,即配置项 appendfsync 的三个可选值:
(1)Always 同步写回:每个写命令执行完,立马同步地将日志写回磁盘
(2)Everysec 每秒写回:每个写命令执行完,先把日志写到 AOF 文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘
(3)No 操作系统控制的写回:每个写命令执行完,先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘

三种策略各有优劣,汇总如下:

选定写回策略,并非万事大吉,随着接收的写命令越来越多,AOF 文件会越来越大,带来性能问题。主要是以下三个方面:
(1)文件系统本身对文件大小有限制,无法保存过大的文件
(2)如果文件太大,之后再往里面追加命令记录的话,效率也会变低
(3)如果发生宕机,AOF 中记录的命令要一个个被重新执行,文件太大导致整个恢复过程就会非常缓慢,影响 Redis 正常使用

日志文件太大了怎么办呢?这个时候,AOF 重写机制 就登场了。当一个键值对被多条写命令反复修改时,AOF 文件会记录相应的多条命令,而重写时,只会根据这个键值对当前的最新状态,为它生成对应的写入命令,这样一来,一个键值对在重写日志中只用一条命令就行了,并且在日志恢复时,只用执行这条命令,就可以直接完成这个键值对的写入了。举个栗子:
AOF 重写并不会阻塞主线程,重写过程是由后台线程 bgrewriteaof 来完成的,通过内存拷贝和两处日志保证数据的完整性。

2、RDB 内存快照

内存快照 RDB 就是 Redis DataBase 的缩写,和 AOF 相比,RDB 记录的是某一时刻的数据,并不是操作,所以在做数据恢复时,我们可以直接把 RDB 文件读入内存,很快地完成恢复。但同时也面临两个问题:
(1)对哪些数据做快照?这关系到快照的执行效率问题。
(2)做快照时,数据还能被增删改吗?这关系到 Redis 是否被阻塞,能否同时正常处理请求。

为了提供所有数据的可靠性保证,全量快照会把内存中的所有数据都记录到磁盘中,一个都不少。这样会花费很多时间,全量数据越多,RDB 文件就越大,往磁盘上写数据的时间开销就越大。对于 Redis 而言,它的单线程模型就决定了,我们要尽量避免所有会阻塞主线程的操作。Redis 提供了两个命令来生成 RDB 文件,分别是 save 和 bgsave:
(1)save:在主线程中执行,会导致阻塞。
(2)bgsave:创建一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是 Redis RDB 文件生成的默认配置。

bgsave 避免主线程阻塞,可以正常接收请求,但是,为了保证快照完整性,它只能处理读操作,不能修改正在执行快照的数据。Redis 就会借助操作系统提供的写时复制技术(Copy-On-Write, COW),在执行快照的同时,正常处理写操作。示意如图:简单来说,主线程 fork 生成 bgsave 子进程,可共享主线程的所有内存数据。bgsave 子进程运行读取主线程的内存数据,并把它们写入 RDB 文件。此时,如果主线程对这些数据也都是读操作(例如图中的键值对 A),则主线程和子进程互不影响。如果主线程要修改数据(例如图中的键值对 C),则会生成该数据的副本,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。

至此上面提的两个问题“哪些数据做快照”、“做快照时数据能否修改”就都解决了。新的问题又产生了,快照间隔多久做一次合适?如果在第二次快照前宕机,就可能出现数据丢失的问题,如果太频繁又会出现第一个还没结束,第二个又开始的情况。虽然 bgsave 执行时不阻塞主线程,但是,如果频繁地执行全量快照,也会给磁盘带来额外的开销,并且 bgsave 子进程需要通过 fork 操作从主线程创建出来,频繁操作依然会阻塞主线程。

此时,增量快照就登场了,做了一次全量快照后,后续的快照只对修改的数据进行快照记录,这样可以避免每次全量快照的开销。比如 T1 和 T2 时刻如果再做快照,我们只需要将被修改的数据写入快照文件就行。虽然我们记住哪些数据被修改了,但“记住”这个操作,需要我们使用额外的元数据信息去记录,这会带来额外的空间开销问题。有时改动较小时,又要引入的额外空间区记录,有些得不偿失。此时我们就可以混合使用 AOF 日志和内存快照的方法,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。如图,T1 和 T2 时刻的修改,用 AOF 日志记录,在第二次做全量快照时,就可以清空 AOF 日志,因为修改都已经记录到快照中了。这个方法既能享受到 RDB 文件快速恢复的好处,又能享受到 AOF 只记录操作命令的简单优势,可谓鱼和熊掌兼得。

标签:AOF,快照,Redis,RDB,日志,数据
From: https://www.cnblogs.com/WinterSir/p/18085397

相关文章

  • Redis实际项目中涉及缓存一致性的处理
    在实际项目中,Redis缓存一致性是一个关键问题,尤其是在分布式系统中。缓存一致性指的是确保缓存中的数据与实际数据库中的数据保持同步。以下是一些在实际项目中处理Redis缓存一致性的方法和最佳实践:1.缓存失效策略a.TTL(TimetoLive):设置缓存的过期时间。当数据过期后,缓存会自......
  • 五.redis
    目录五.redis5.1什么是CDN5.2CDN的原理5.3首先,介绍一下Redis过期删除策略Redis对于过期的key,有两种删除策略:定期删除惰性删除5.4为啥需要两种删除策略呢?5.5然后,再介绍Redis淘汰策略.5.6那么,如何设置淘汰策略呢?5.7如何配置Redis能使用的最大的内存大小第一种方式:第二种方式:5......
  • Redis 数据类型详解
    Redis是一个开源的内存数据结构存储系统,广泛应用于缓存、消息队列、实时数据分析等场景。Redis提供了多种数据类型,本文将详细介绍Redis的五种主要数据类型及其应用场景,并从概述、基本操作、应用场景和数据结构等方面进行深入探讨。1.字符串(String)概述字符串是Redis......
  • Redis 数据类型详解
    Redis是一个开源的内存数据结构存储系统,广泛应用于缓存、消息队列、实时数据分析等场景。Redis提供了多种数据类型,本文将详细介绍Redis的五种主要数据类型及其应用场景,并从概述、基本操作、应用场景和数据结构等方面进行深入探讨。1.字符串(String)概述字符串是Redis......
  • 【Redis进阶】Redis单线程模型和多线程模型
    目录单线程为什么Redis是单线程处文件事件理器的结构文件处理器的工作流程总结文件事件处理器连接应答处理器命令请求处理器命令回复处理器多线程为什么引入多线程多线程架构多线程执行流程关于Redis的问题Redis为什么采用单线程模型Redis为什么要引入多线程呢......
  • 【Redis进阶】缓存设计模式
    目录CacheAside(旁路缓存)模式概念读操作流程如上图所示写操作流程如上图所示代码示例总结Read-Through模式概念操作流程:优点:Write-Through模式概念操作流程:优点:Write-Behind(Write-Back)模式概念操作流程:优点:缺点:总结缓存设计模式是指将缓存作为系统架......
  • springboot整合redis
    第一部分:redis的下载安装百度网盘下载:通过百度网盘分享的文件:Redis-x64-5.0.14.zip链接:https://pan.baidu.com/s/1GEQj4p0l4fy1DzwCIknpRg?pwd=qokq 提取码:qokq --来自百度网盘超级会员V5的分享第二部分:安装(1)双击打开软件(2)点击next(3)点击next(4)更改路径,点击next......
  • 节假日配置初始化 redis缓存方案及@PostConstruct注解,Cache方案GuavaUtils.java工具类
    节假日配置初始化redis缓存方案及@PostConstruct注解,Cache方案GuavaUtils.java工具类启动报错:本机,在jenkins上面没有报错?包括嵌套的注入Beanjava静态代码块和spring@value等注解注入顺序https://www.cnblogs.com/oktokeep/p/15530697.html/***节假日配置初始化redis缓存......
  • 01 NoSQL之Redis配置与优化
    目录1.1Redis介绍1.1.1关系数据库与非关系型数据库1.关系型数据库2.非关系型数据库3.非关系型数据库产生背景(1) Highperformance--对数据库高并发读写需求(2) HugeStorage--对海量数据高效存储与访问需求(3) HighScalability&&HighAvailability--对数......
  • Redis8-秒杀优化
    秒杀思路之前: Redis优化: 基于Redis完成秒杀资格判断需求:新增秒杀优惠券的同时,将优惠券信息保存到Redis中基于Lua脚本,判断秒杀库存、一人一单,决定用户是否抢购成功如果抢购成功,将优惠券id和用户id封装后存入阻塞队列开启线程任务,不断从阻塞队列中获取信息,实现异......