[Redis][持久化][上][RDB]详细讲解
目录
0.前言
- Redis ⽀持 RDB 和 AOF 两种持久化机制,持久化功能有效地避免因进程退出造成数据丢失问题,当下次重启时利⽤之前持久化的⽂件即可实现数据恢复
- Redis如何做到持久化?
- 当要插入一个新的数据的时候,就需要把这个数据,同时写入到内存和硬盘上
- 硬盘的数据只是在Redis重启的时候,用来恢复内存中的数据的
- 当查询某个数据的时候,直接从内存读取
1.RDB
0.是什么?
- RDB 持久化是把当前进程数据⽣成快照保存到硬盘的过程,触发 RDB 持久化过程分为**⼿动触发** 和**⾃动触发**
1.触发机制
- 手动触发分别对应
save
和bgsave
命令:
save
:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例造成长时间阻塞,基本不采用
bgsave
:Redis进程执行fock
操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束,阻塞只发生在fock
阶段,一般时间很短
- Redis内部的所有涉及RDB的操作都采用类似
bgsave
的方式
- Redis运行自动触发RDB持久化机制,该触发机制才是在实战中有价值的
- 使用
save
配置,如save m n
表示m
秒内数据集发生了n
次修改,自动RDB持久化
- 从节点进⾏全量复制操作时,主节点⾃动进⾏RDB持久化,随后将RDB⽂件内容发送给从结点
- 执行
shutdown
命令关闭Redis时,执行RDB持久化
2.流程说明
bgsave
是主流的RDB持久化方式,主要流程如下:
- 执⾏
bgsave
命令,Redis⽗进程判断当前进程是否存在其他正在执⾏的⼦进程
- 例如 :RDB/AOF⼦进程,如果存在
bgsave
命令直接返回
- ⽗进程执⾏
fork
创建⼦进程,fork
过程中⽗进程会阻塞,通过info stats
命令查看latest_fork_usec
选项,可以获取最近⼀次fork
操作的耗时,单位为微秒
- ⽗进程
fork
完成后,bgsave
命令返回"Background saving started"
信息并不再阻塞⽗进程,可以继续响应其他命令
- ⼦进程创建RDB⽂件,根据⽗进程内存⽣成临时快照⽂件,完成后对原有⽂件进⾏原⼦替换 。执⾏
lastsave
命令可以获取最后⼀次⽣成RDB的时间,对应info
统计的rdb_last_save_time
选项
- 进程发送信号给父进程表示完成,父进程更新统计信息
3.RDB文件的处理
- 保存 :
- RDB⽂件保存在
dir
配置指定的⽬录(默认/var/lib/redis/
)下,⽂件名通过 dbfilename
配置(默认dump.rdb
)指定
- 可以通过执⾏
config set dir {newDir}
和config set dbfilename {newFilename}
运⾏期间动态执⾏,当下次运⾏时RDB⽂件会保存到新⽬录
- 压缩 :Redis默认采⽤LZF算法对⽣成的RDB⽂件做压缩处理,压缩后的⽂件远远⼩于内存⼤⼩,默认开启,可以通过参数
config set rdbcompression {yes|no}
动态修改
- 注意 :虽然压缩 RDB会消耗CPU,但可以⼤幅降低⽂件的体积,⽅便保存到硬盘或通过⽹络发送到从节点,因此建议开启
- 校验 :如果Redis启动时加载到损坏的RDB⽂件会拒绝启动,此时可以使⽤Redis提供的
redis check-dump
⼯具检测RDB⽂件并获取对应的错误报告
4.RDB的优缺点
- 优点 :
- RDB是⼀个紧凑压缩的⼆进制⽂件 ,代表Redis在某个时间点上的数据快照,⾮常适⽤于备份,全量复制等场景
- 例如 :每6⼩时执⾏
bgsave
备份,并把RDB ⽂件复制到远程机器或者⽂件系统(如 hdfs)⽤于灾备
- Redis加载RDB恢复数据远远快于AOF的方式
- RDB以二进制的方式来组织数据,直接把数据读取到内存中,按照字节的格式取出来,放到结构体/对象中即可
- AOF使用文本的方式来组织数据,需要进行一系列的字符串切分操作
- 缺点 :
- RDB⽅式数据没办法做到实时持久化 / 秒级持久化 ,因为
bgsave
每次运⾏都要执⾏fork
创建⼦进程,属于重量级操作,频繁执⾏成本过⾼
- RDB ⽂件使⽤特定⼆进制格式保存,Redis 版本演进过程中有多个 RDB 版本,兼容性可能有⻛险