Redis——认识持久化、RDB、AOF

什么是持久化?也就是数据持久化,当系统重启后仍能恢复保存的数据特性。

这个特性在mysql中最有体现,因为其把数据都保存在磁盘中,其实,redis也具有持久化的特性,

虽然其把数据都保存在内存中(一旦重启,内存中的数据都将清除),但其有自己的持久化策略,在向内存存数据时,同时也像磁盘中存,当重启时,就会从磁盘中获取数据到内存(为什么不向mysql一样直接与磁盘交互?虽然听着确实是麻烦,但因其自有的策略使得整体还是比mysql快的,两边的写是不同策略,理论上两边数据相同,但持久化导致数据不一定一致)

Redis如何实现持久化?

策略:RDB和AOF

RDB

redis database :它会定期地将我们的redis中内存所有数据写入硬盘中,形成一个快照,一旦redis重启了,就会根据快照把内存中的数据恢复。

定期分为两种:手动和自动触发

手动触发:通过redis客户端执行特定命令触发形成快照 :save(如果redis数据过多可能会阻塞其他redis客户端,不建议使用) bgsave(不会影响其他redis客户端,在后台处理,并发编程(实际并非多进程)

自动触发:在redis的配置文件设置,每隔一段时间就触发一次

bgsave的执行流程

首先输入bgsave命令输入,redis进程(父进程)识别命令并判断,当前是否有其他redis客户端工作的子进程,如果有一个子进程正在执行bgsave,则直接返回当前的bgsave,如果没有,父进程会fork出子进程,子进程来处理bgsave命令并生成rdb文件,父进程继续处理其他请求。子进程完成整个持久化过程后,通知父进程,收集退出信息并退出。

redis生成的rdb文件,是存放在redis的工作目录中,在配置文件中设置。(默认在/var/lib/redis)

rdb的持久化操作可以触发多次,当执行rdb镜像操作时,先把生成的快照的数据保存临时文件中,当生成结束后,删除原来的rdb,把新保存的文件改名为dump

除此之外,服务器通过shutdown关闭命令时,会自动触发rdb快照(主从复制也可以)

如果是kill命令(异常重启)退出服务器则不会触发

如果Redis启动时加载到损坏的RDB⽂件会拒绝启动。这时可以使⽤Redis提供的redis check-dump⼯具检测RDB⽂件并获取对应的错误报告。

RDB最大的问题就是,不能实时的持久化保存数据,比如我在两次持久化之间存数据,但在下次持久化之前,服务器因某种原因重启/退出了,那么存的这些数据就会丢失。

AOF很好地解决了这个我问题,接下来我们看看AOF的执行

RDB是⼀个紧凑压缩的⼆进制⽂件,代表Redis在某个时间点上的数据快照。⾮常适⽤于备份,全量复制等场景。⽐如每6⼩时执⾏bgsave备份,并把RDB⽂件复制到远程机器或者⽂件系统中 (如hdfs)用于灾备。

Redis加载RDB恢复数据远远快于AOF的⽅式。

RDB⽅式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运⾏都要执⾏fork创建⼦进程,属于重量级操作,频繁执⾏成本过⾼。

RDB⽂件使⽤特定⼆进制格式保存,Redis版本演进过程中有多个RDB版本,兼容性可能有风险

AOF

其存的并不是数据,而是用户的每一个操作,当redis重启时,就会读取AOF的操作恢复数据,(以AOF为准,AOF启动时,就不会读RDB了,默认关闭)

在配置文件中修改

这就意味着,AOF机制是即写内存又写硬盘,涉及到硬盘,影响redis的性能?不会,其实没有影响。AOF机制先写入内存的缓冲区,积累一定量再写入硬盘。

同样的,如果在缓冲区内的数据未到磁盘中服务器崩溃了也会丢失,尽量避免这种问题,缓冲区有三种刷新机制;

缓冲区的刷新机制

always 一旦存数据到缓冲区立即刷新

everysec:每秒刷新一次

no:由OS控制刷新频率

依然是在配置文件中修改

刷新频率过高必然会导致效率降低,因此要平衡(懂得取舍)

AOF的重写机制

随着redis服务器运行时间逐渐变长,AOF文件记录的操作也会越来越多,一旦文件过大,redis重启时一定会影响效率,因此redis会对AOF文件进行重写,

也并不是都会删除,而是类似整理的操作,删除那些冗余,重复的操作,只保留操作最后的结果,比如AOF有连续的set del set del,那么重写后就是空,因为最后的结果就是不对redis有任何数据操作,这就是重写机制。

重写机制的触发时机

同样分为手动和自动触发

手动:bgrewriteaof 命令

自动触发:根据autoaofrewriteminsize(触发时AOF最小文件大小,默认64mb)和autoaofrewritepercentage(当前aof占用大小相较于上次重写时增加的比例)参数触发

触发流程

和RDB高度相似,创建子进程去完成触发工作,重写时,不关心aof原来的内容,只关心内存最终数据状态,子进程只需要把状态获取并写入新的aof文件即可。(区别于rdb的方式,rdb是二进制存储,aof是文本存储)

在重写过程中,父进程仍能记录内存的变化并写入缓冲区(此时子进程并不知道)这个缓冲区专门存专门存父进程fork后的数据变化并写入新aof文件(子进程退出后)(aof-rewrite-buf)

如果执行重写命令时,发现redis正在生成rdb快照,此时就会等待其执行完毕后再重写

混合持久化

由于aof以文本形式存数据的开销比较大,现在大部分采用混合持久化的模式,即以rdb二进制的方式把数据存aof中。

实际redis启动时都是以aof为主,只有判断aof关闭时才会启动rdb

相关推荐
jiayou6410 小时前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤1 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区2 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1772 天前
《从零搭建NestJS项目》
数据库·typescript
加号33 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏3 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐3 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再3 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
tryCbest3 天前
数据库SQL学习
数据库·sql
jnrjian3 天前
ORA-01017 查找机器名 用户名 以及library cache lock 参数含义
数据库·oracle