搜索
首页数据库Redis详细解析Redis中的持久化机制

详细解析Redis中的持久化机制

Dec 29, 2021 am 10:11 AM
redis持久化机制

本篇文章带大家了解一下Redis中的持久化机制:RDB和AOF,并对比一下RDB和AOF,希望对大家有所帮助!

详细解析Redis中的持久化机制

Redis持久化机制

为什么要持久化

如果Redis再次访问时,发现Redis的数据是空的,就会形成缓存穿透。更重要的是,因为Redis的数据是空的,所以客户端想要访问的key都没有,就会造成大量的请求就会瞬间打到数据库上,造成缓存雪崩(少量的key是穿透,大量的key是雪崩)。

这个时候,数据库可能就挂掉。而又无法保证redis不宕机,所以需要当redis宕机后,迅速将里里面的内容恢复出来。因此需要做一个持久化。持久化是为了恢复数据用的,而不是存储数据用的。【相关推荐:Redis视频教程

RDB

RDB(Redis DataBase),是Redis默认的存储方式,RDB方式是通过快照(snapshotting)完成的。

触发快照的方式

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

  • save 900 1 # 表示15分钟(900秒钟)内至少1个键被更改则进行快照。

  • save 300 10 # 表示5分钟(300秒)内至少10个键被更改则进行快照。

  • save 60 10000 # 表示1分钟内至少10000个键被更改则进行快

N秒内数据集至少有M个改动”这一条件被满足时,自动保存一次数据集。

执行save或者bgsave命令

执行命令save或bgsave可以生成dump.rdb文件,每次命令执行都会将所有redis内存快照到一个新的rdb文件里,并覆盖原有rdb快照文件。

save与bgsave对比:

命令 save bgsave
IO类型 同步 异步
是否阻塞redis其它命令 否(在生成子进程执行调用fork函数时会有短暂阻塞)
复杂度 O(n) O(n)
优点 不会消耗额外内存 不阻塞客户端命令
缺点 阻塞客户端命令 需要fork子进程,消耗内存

配置自动生成rdb文件后台使用的是bgsave方式。

执行flushall命令

flushall

清空Redis之前,保存当前Redis快照

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

第一次主从复制时需要生成rdb文件,会保存当前Redis快照

RDB执行流程

1.png

  • 流程分析

      1. Redis父进程首先判断:当前是否在执行save或bgsave/bgrewriteaof(aof文件重写命令)的子进程,如果在执行则bgsave命令直接返回。
      1. 父进程执行fork(调用操作系统函数复制主进程)操作创建子进程,这个过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令。
      1. 父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令。
      1. 子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行原子替换。(RDB始终完整)
      1. 子进程发送信号给父进程表示完成,父进程更新统计信息。
      1. 父进程fork子进程后,继续工作。

RDB文件结构

2.png

  • 1、头部5字节固定为“REDIS”字符串
  • 2、4字节“RDB”版本号(不是Redis版本号),当前为9,填充后为0009
  • 3、辅助字段,以key-value的形式
  • 4、存储数据库号码
  • 5、字典大小
  • 6、过期key
  • 7、主要数据,以key-value的形式存储
  • 8、结束标志
  • 9、校验和,就是看文件是否损坏,或者是否被修改

RDB的优缺点

优点

  • RDB是二进制压缩文件,占用空间小,便于传输(传给slaver)

  • 主进程fork子进程,可以最大化Redis性能,主进程不能太大,复制过程中主进程阻塞

缺点

  • 不保证数据完整性,会丢失最后一次快照以后更改的所有数据

AOF

AOF(append only file)是Redis的另一种持久化方式。Redis默认情况下是不开启的。开启AOF持久化后,Redis将所有对数据库进行过写入的命令(及其参数)(RESP)记录到AOF文件,以此达到记录数据库状态的目的,

这样当Redis重启后只要按顺序回放这些命令就会恢复到原始状态了。AOF会记录过程,RDB只管结果

AOF持久化实现

配置 redis.conf

# 可以通过修改redis.conf配置文件中的appendonly参数开启 
appendonly yes

# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的。 
dir ./

# 默认的文件名是appendonly.aof,可以通过appendfilename参数修改 
appendfilename appendonly.aof

AOF原理

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

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

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

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

3.png

命令传播

当一个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文件保存到磁盘中。

AOF保存模式

Redis 目前支持三种 AOF 保存模式,它们分别是:

  • AOF_FSYNC_NO :不保存。

  • AOF_FSYNC_EVERYSEC :每一秒钟保存一次。(默认)

  • AOF_FSYNC_ALWAYS :每执行一个命令保存一次。(不推荐)

AOF_FSYNC_NO

从不fsync,将数据交给操作系统来处理。更快,也更不安全的选择。

SAVE只会在以下任意一种情况中被执行:

  • Redis被关闭

  • AOF功能被关闭

  • 系统的写缓存被刷新(可能是缓存已经被写满,或者定期保存操作被执行)

这三种情况下的SAVE操作都会引起Redis主进程阻塞。

AOF_FSYNC_EVERYSEC

SAVE原则上每隔一秒钟就会执行一次,因为SAVE操作是由后台子线程(fork)调用的, 所以它不会引起服务器主进程阻塞,并且在故障时只会丢失1秒钟的数据。

AOF_FSYNC_ALWAYS

每次执行完一个命令之后,WRITE和SAVE都会被执行。每次有新命令追加到AOF文件时就执行一次fsync,非常慢,也非常安全。

因为SAVE是由Redis主进程执行的,所以在SAVE执行期间,主进程会被阻塞,不能接受命令请求。

AOF保存模式对性能和安全性的影响

三种模式的比较

4.png

AOF重写

AOF记录数据的变化过程,越来越大,需要重写“瘦身”

Redis可以在AOF体积变得过大时,自动地在后台(Fork子进程)对AOF进行重写。

重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。

所谓的“重写”其实是一个有歧义的词语,实际上,AOF重写并不需要对原有的AOF文件进行任何写入和读取,它针对的是数据库中键的当前值。

举例说明

set s1 11
set s1 22
set s1 33

lpush list1 1 2 3
lpush list1 4 5 6

AOF重写后

set s1 33

lpush list1 1 2 3 4 5 6

Redis不希望AOF重写造成服务器无法处理请求,所以Redis决定将AOF重写程序放到(后台)子进程里执行,

  • 1、子进程进行AOF重写期间,主进程可以继续处理命令请求。

  • 2、子进程带有主进程的数据副本,使用子进程而不是线程,可以在避免锁的情况下,保证数据的安全性。

不过,使用子进程也有一个问题需要解决:因为子进程在进行AOF重写期间,主进程还需要继续处理命令,而新的命令可能对现有的数据进行修改,这会让当前数据库的数据和重写后的AOF文件中的数据不一致。

为了解决这个问题,Redis增加了一个AOF重写缓存,这个缓存在fork出子进程之后开始启用,Redis主进程在接到新的写命令之后,除了会将这个写命令的协议内容追加到现有的AOF文件之外,还会追加到这个缓存中。

重写过程分析

5.png

Redis在创建新AOF文件的过程中,会继续将命令追加到现有的AOF文件里面,即使重写过程中发生停机,现有的AOF文件也不会丢失。而一旦新AOF文件创建完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。

当子进程在执行AOF重写时,主进程需要执行以下三个工作:

  • 处理命令请求。
  • 将写命令追加到现有的AOF文件中。
  • 将写命令追加到AOF重写缓存中

。这样一来可以保证:现有的AOF功能会继续执行,即使在AOF重写期间发生停机,也不会有任何数据丢失。所有对数据库进行修改的命令都会被记录到AOF重写缓存中。

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

  • 将AOF重写缓存中的内容全部写入到新AOF文件中。
  • 对新的AOF文件进行改名,覆盖原有的AOF文件。

Redis数据库里的+AOF重写过程中的命令------->新的AOF文件---->覆盖老的当步骤1执行完毕之后,现有AOF文件、新AOF文件和数据库三者的状态就完全一致了。

当步骤2执行完毕之后,程序就完成了新旧两个AOF文件的交替。这个信号处理函数执行完毕之后,主进程就可以继续像往常一样接受命令请求了

。在整个AOF后台重写过程中,只有最后的写入缓存和改名操作会造成主进程阻塞,在其他时候,AOF后台重写都不会对主进程造成阻塞,这将AOF重写对性能造成的影响降到了最低。

AOF重写触发方式

  • 1、配置触发
#表示当前aof文件大小超过上一次aof文件大小的百分之多少的时候会进行重写。如果之前没有重写过,以启动时aof文件大小为准
auto-aof-rewrite-percentage 100

#限制允许重写最小aof文件大小,也就是文件大小小于64mb的时候,不需要进行优化
auto-aof-rewrite-min-size 64mb
  • 2、执行bgrewriteaof命令
127.0.0.1:6379>bgrewriteaof‘
Backgroundappendonlyfilerewritingstarted

AOF重写总结

6.png

混合持久化

RDB和AOF各有优缺点,Redis 4.0开始支持rdb和aof的混合持久化。

如果把混合持久化打开,aofrewrite的时候就直接把rdb的内容写到aof文件开头。

RDB的头+AOF的身体---->appendonly.aof

开启混合持久化

aof-use-rdb-preambleyes

AOF文件的载入与数据还原

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

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

  • 1、创建一个不带网络连接的伪客户端(fake client)

因为Redis的命令只能在客户端上下文中执行,而载入AOF文件时所使用的命令直接来源于AOF文件而不是网络连接,所以服务器使用了一个没有网络连接的伪客户端来执行AOF文件保存的写命令,伪客户端执行命令的效果和带网络连接的客户端执行命令的效果完全一样

  • 2、从AOF文件中分析并读取出一条写命令

  • 3、使用伪客户端执行被读出的写命令

  • 4、一直执行步骤2和步骤3,直到AOF文件中的所有写命令都被处理完毕为止

7.png

Redis数据备份策略

  • 1.写crontab定时调度脚本,每小时都copy一份rdb或aof的备份到一个目录中去,仅仅保留最近48小时的备份

  • 2.每天都保留一份当日的数据备份到一个目录中去,可以保留最近1个月的备份

  • 3.每次copy备份的时候,都把太旧的备份给删了

  • 4.每天晚上将当前机器上的备份复制一份到其他机器上,以防机器损坏

RDB和AOF对比

  • 1、RDB存某个时刻的数据快照,采用二进制压缩存储,AOF存操作命令,采用文本存储(混合)

  • 2、RDB性能高、AOF性能较低

  • 3、RDB在配置触发状态会丢失最后一次快照以后更改的所有数据,AOF设置为每秒保存一次,则最多丢2秒的数据

  • 4、Redis以主服务器模式运行,RDB不会保存过期键值对数据,Redis以从服务器模式运行,RDB会保存过期键值对,当主服务器向从服务器同步时,再清空过期键值对。AOF写入文件时,对过期的key会追加一条del命令,当执行AOF重写时,会忽略过期key和del命令。

更多编程相关知识,请访问:编程视频!!

以上是详细解析Redis中的持久化机制的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:掘金社区。如有侵权,请联系admin@php.cn删除
REDIS:NOSQL方法的优势REDIS:NOSQL方法的优势Apr 27, 2025 am 12:09 AM

Redis是NoSQL数据库,提供高性能和灵活性。1)通过键值对存储数据,适合处理大规模数据和高并发。2)内存存储和单线程模型确保快速读写和原子性。3)使用RDB和AOF机制进行数据持久化,支持高可用性和横向扩展。

REDIS:了解其架构和目的REDIS:了解其架构和目的Apr 26, 2025 am 12:11 AM

Redis是一种内存数据结构存储系统,主要用作数据库、缓存和消息代理。它的核心特点包括单线程模型、I/O多路复用、持久化机制、复制与集群功能。 Redis在实际应用中常用于缓存、会话存储和消息队列,通过选择合适的数据结构、使用管道和事务、以及进行监控和调优,可以显着提升其性能。

REDIS与SQL数据库:关键差异REDIS与SQL数据库:关键差异Apr 25, 2025 am 12:02 AM

Redis和SQL数据库的主要区别在于:Redis是内存数据库,适用于高性能和灵活性需求;SQL数据库是关系型数据库,适用于复杂查询和数据一致性需求。具体来说,1)Redis提供高速数据访问和缓存服务,支持多种数据类型,适用于缓存和实时数据处理;2)SQL数据库通过表格结构管理数据,支持复杂查询和事务处理,适用于电商和金融系统等需要数据一致性的场景。

REDIS:它如何充当数据存储和服务REDIS:它如何充当数据存储和服务Apr 24, 2025 am 12:08 AM

REDISACTSASBOTHADATASTOREANDASERVICE.1)ASADATASTORE,ITUSESIN-MEMORYSTOOGATOFORFOFFASTESITION,支持VariousDatharptructuresLikeKey-valuepairsandsortedsetsetsetsetsetsetsets.2)asaservice,ItprovidespunctionslikeItionitionslikepunikeLikePublikePublikePlikePlikePlikeAndluikeAndluAascriptingiationsmpleplepleclexplectiations

REDIS与其他数据库:比较分析REDIS与其他数据库:比较分析Apr 23, 2025 am 12:16 AM

Redis与其他数据库相比,具有以下独特优势:1)速度极快,读写操作通常在微秒级别;2)支持丰富的数据结构和操作;3)灵活的使用场景,如缓存、计数器和发布订阅。选择Redis还是其他数据库需根据具体需求和场景,Redis在高性能、低延迟应用中表现出色。

REDIS的角色:探索数据存储和管理功能REDIS的角色:探索数据存储和管理功能Apr 22, 2025 am 12:10 AM

Redis在数据存储和管理中扮演着关键角色,通过其多种数据结构和持久化机制成为现代应用的核心。1)Redis支持字符串、列表、集合、有序集合和哈希表等数据结构,适用于缓存和复杂业务逻辑。2)通过RDB和AOF两种持久化方式,Redis确保数据的可靠存储和快速恢复。

REDIS:了解NOSQL概念REDIS:了解NOSQL概念Apr 21, 2025 am 12:04 AM

Redis是一种NoSQL数据库,适用于大规模数据的高效存储和访问。1.Redis是开源的内存数据结构存储系统,支持多种数据结构。2.它提供极快的读写速度,适合缓存、会话管理等。3.Redis支持持久化,通过RDB和AOF方式确保数据安全。4.使用示例包括基本的键值对操作和高级的集合去重功能。5.常见错误包括连接问题、数据类型不匹配和内存溢出,需注意调试。6.性能优化建议包括选择合适的数据结构和设置内存淘汰策略。

REDIS:现实世界的用例和示例REDIS:现实世界的用例和示例Apr 20, 2025 am 12:06 AM

Redis在现实世界中的应用包括:1.作为缓存系统加速数据库查询,2.存储Web应用的会话数据,3.实现实时排行榜,4.作为消息队列简化消息传递。Redis的多功能性和高性能使其在这些场景中大放异彩。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器