redis持久化详解之RDB
目录
redis持久化 :
redis数据是存在内存里的,这样虽然很快(官方提供的数据大概是 QPS: 10w+/S),但也会导致关机或者进程退出数九就会永久丢失 ,需要将数据以某种形式定时写入磁盘,这样就可以利用磁盘恢复数据,这就是redis持久化,简单来说就是将数据从内存写入磁盘。
redis持久化分为RDB和AOF ;rdb是将数据写入磁盘生成一个.rdb的文件 ;aof是将每次执行的命令保存到磁盘生成一个.aof的文件
触发机制
手动触发(save)和自动触发(bgsave)
save命令:阻塞当前redis进程,直到RDB过程完成。对内存大的实例会造成长时间阻塞
bgsave命令:redis会执行fork操作创建子进程,在子进程内完成RDB过程,阻塞只会发生在子进程内,不影响主进程
显然 bgsave 命令是针对 save 阻塞问题做的优化。 因此 Redis 内部所有的涉及 RDB 的操作都采用 bgsave 的方式
自动触发RDB持久化机制:
- 配置save 如“save m n” 标识 m秒内数据存在n次修改时,自动触发
- 如果从节点执行全量复制操作,主节点自动执行bgsave 生成RDB文件并发送给从节点
- 执行debug reload 命令重新加载redis时,也会自动触发bgsave
- 默认没有执行shutdown命令时,没有开启AOF时也会自动执行bgsave
运行流程如下图:
流程解释:
- 执行bgsave时,父进程判断当前是否有子进程在执行,如 RDB/AOF 如果存在bgsave则直接返回
- 父进程fork出一个子进程,fork 操作过程中父进程会阻塞,可以通过info status 命令查看latest_fork_usec选项,可以获取最近一个fork操作的耗时。单位为微秒
- 父进程fork完成后,bgsave命令会返回“Background saving started”信息,并不在阻塞父进程
- 子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后替换原有文件。执行 lastsave 命令可以获取最后一次生成 RDB的时间, 对应 info 统计的 rdb_last_save_time 选项。
- 进程发送信号给傅父进程标识完成,父进程更新信息。执行 lastsave 命令可以获取最后一次生成 RDB的时间, 对应 info 统计的 rdb_last_save_time 选项。
服务器配置自动化触发,可以在配置中指定
# 90s内至少达到一条写命令
save 90 1
# 30s内至少达至10条写命令
save 30 10
# 60s内至少达到10000条写命令
save 60 10000
PS:与手动触发类型,也会fork一个子进程来完成,但触发时间不要太短,容易频繁写入,影响性能,也不要配置太长,会导致数据丢失
RDB 文件的处理
1.保存:
RDB 文件保存在 dir 配置指定的目录下, 文件名通过 dbfilename 配置指定。 可以通过执行 config set dir{newDir}和 config set dbfilename{newFileName}运行期动态执行, 当下次运行时 RDB 文件会保存到新目录.当遇到坏盘或磁盘写满等情况时, 可以通过 config set dir{newDir}在线修改文件路径到可用的磁盘路径, 之后执行 bgsave 进行磁盘切换, 同样适用于 AOF 持久化文件。
2.压缩:
Redis 默认采用 LZF 算法对生成的 RDB 文件做压缩处理, 压缩后的文件远远小于内存大小, 默认开启, 可以通过参数 config set rdbcompression{yes|no}动态修改。
虽然压缩 RDB 会消耗 CPU, 但可大幅降低文件的体积, 方便保存到硬盘或通过网络发送给从节点, 因此线上建议开启。
RDB优点
1.RDB非常适用与备份,可以设置每小时备份一次,并且在每月的每一天也备份一个,这样的话, 即使遇上问题, 也可以随时将数据集还原到不同的版本
2. RDB可以最大化redis性能,父进程只需要fork出一个子进程,让子进程去操作,本身不需要进行I/O操作
3. 在大数据恢复时RDB比AOF要快
RDB缺点
1.没办法做到实时/毫秒级数据持久化,如果服务器宕机,会造成某个时间段的数据丢失,比如我们设置10分钟同步一次或5分钟达到1000次写入就同步一次, 那么如果还没达到触发条件服务器就死机了, 那么这个时间段的数据会丢失。
2.使用bgsave时如果数据量过大,fork时也会造成阻塞,另外fork也是消耗内存的。
针对RDB的问题,redis提供了AAOF持久化来解决,一般是RDB+AOF一起做持久化,以AOF为主