【Redis】持久化(上)---RDB

文章目录

持久化的概念

Redis支持AOFRDB两种持久化机制,持久化功能能有效的避免因进程退出而导致的数据丢失 的问题,当下次重启的时候利用之前持久化的文件即可实现数据恢复 .

所以此时我们要明确一个常见的误区:Redis不仅仅会将数据保存在内存中,还会将数据保存在磁盘中 ,实现持久化存储

RDB

RDB持久化是指把当前进程数据生成快照 保存到硬盘 中的过程,触发RDB持久化过程分为手动触发自动触发

  • 快照:快照可以理解为把当前内存 中存储的数据拍一个照片,生成一个文件,即是一种瞬时的保存
  • RDB:相当于定期备份 ,把内存中所有的数据写入硬盘中,生成一个快照

手动触发

手动触发的意思就是由 程序员通过Redis客户端来执行持久化的命令

  • save命令:阻塞当前的Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成阻塞时间过长 ,基本不采用 .(Redis单线程 ,阻塞了Redis接受其他客户端的指令)
  • bgsave命令::Redis进程执行fork操作创建子进程 ,RDB持久化过程是由子进程 负责的,完成之后自动结束 .阻塞只发生在fork阶段,一般来说时间比较短 (Redis在主线程中只进行了fork创建子进程的操作)

自动触发

Redis运行自动触发RDB持久化机制,这个触发机制在实战中才是比较有价值的.

  • 使用save配置.如save m n表示m秒内数据集发生了n次修改,自动进行RDB持久化.(可在配置文件中进行修改)
  • 从节点进行全量复制 操作时,主节点自动进行RDB持久化,所有将RDB文件发送给从节点
  • 执行shutdown命令关闭Redis时,执行RDB持久化.(使用showdown等命令关闭Redis属于正常关闭 ,如果发生异常关闭 ,可能会导致数据的丢失)

bgsave命令的运行流程

  • 执行bgsave命令,Redis父进程判断当前进程是否存在其他正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回
  • 父进程执行fork创建子进程,fork过程中父进程会阻塞,通过info stats命令查看last_fork_usec选项,可以获取最近一次fork操作的耗时,单位为毫秒
  • 父进程fork完成之后,bgsave命令返回Background saving started信息不再阻塞父进程,可以相应其他的命令
  • 子进程创建RDB文件.根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换 .执行lastsave命令可以获得最后一次生成RDB的时间,对应info统计的rdb_last_save_time选项
  • 进程发送信号给父进程表示完成 ,父进程更新统计信息

RDB文件的处理

  • 静态保存 :RDB文件保存在dir配置指定的目录(默认为/var/lib/redis下),文件名通过dbfilename配置(默认dump.rdb)指定.
  • 动态保存 :可以通过执行config set dir {newDir}config set dbfilename {dbFilename}运行期间动态执行,当下次运行时RDB文件会被保存在新的目录中
  • 压缩 :Redis默认采用LZF算法对生成的RDB文件进行压缩处理 ,压缩后的文件远远小于内存大小,可以通过参数config set rdbcompression{yes|no}来进行动态修改
  • 校验 :如果Redis启动时加载到损坏的RDB文件,会拒绝启动 .这时可以使用Redis提供的redis-check-dump工具检测RDB文件并获取对应的错误报告

RDB的优缺点

优点

  • RDB是一个紧凑压缩的二进制文件 ,代表Redis某个时间点上的数据快照 .非常适用于备份 ,全量复制 等场景.即适合定期备份的场景
  • 由于RDB是以二进制来组织数据 ,而AOF是以文本的形式来组织数据,所以Redis加载RDB恢复数据远远快于 AOF的方式

缺点

  • RDB方式数据没办法做到实时持久化/秒级持久化 .因为bgsave每次运行都要执行fork创建子进程,属于重量级 操作,频繁执行成本过高,所以在两次快照数据存储之间的数据可能存在数据丢失的可能
  • RDB文件使用特定的二进制格式保存,Redis版本演进过程中有多个RDB版本,兼容性可能有风险.

RDB效果展示

我们先来大致总结一下RDB文件的触发条件:

  • 手动触发:savebgsave,其中最常使用的是bgsave
  • 自动触发:
    • 在配置文件中进行触发条件的配置save m n
    • 正常关闭Redis时,会触发RDB,但是异常关闭Redis时,可能会导致没有触发RDB持久化导致数据丢失

接下来我们使用bgsave来进行RDB效果展示

先展示正常存储的情况:

  • Redis中没有存放任何数据时,我们来观察一下rdb文件中的数据情况
  • 接下来向Redis'中存放几个key
  • 再执行bgsave,手动触发RDB持久化
  • 再来观察RDB文件中的数据改变

    我们发现,数据中出现了key1,key2,key3等的身影,说明数据已经被持久化到磁盘文件中了

如果我们不进行bgsave手动触发呢?

我们来看看具体的情况(在执行之前已经清空了所有的数据,恢复到原始状态):

  • 先向Redis中添加几个数据:

  • 不执行bgsave直接退出,此时打开rdb文件观察:

    没有发现明显的key数据的身影.

  • 再打开Redis观察数据:

    这里为什么RDB文件中不存在数据,但是在Redis服务端中还能查询到对应的数据呢?

    这是因为,我们的数据虽然没有被持久化到对应的磁盘文件dump.rdb文件中,但是依旧保存在内存 中,所以如果我们在没有断开Redis服务端的情况下,还是可以再一次查询到对应的数据的.但是,如果我们此时模拟异常关闭的情况 ,即kill -9 Redis-server的进程ID,再启动对应的Redis,我们再来观察数据是否还存在:

  • kill -9 Redis-server的进程ID

  • 再启动Redis:redis-server /etc/redis/redis.conf

  • 查询数据情况:

    此时我们发现,数据不存在,这样便验证了我们的猜想:刚才的数据是存储在内存中的,而不是磁盘中 ,同时,我们也得出结论:异常关闭 会导致数据丢失

接下来我们来验证一下:正常关闭是否会触发RDB持久化行为
redis-cli shutdown属于正常关闭Redis的行为

  • Redis中存放多个数据

  • 再执行正常的关闭Redis的行为:redis-cli shutdown,再重启Redis

  • 查看其中的数据:

  • 查看RDB文件:

    发现正常关闭Redis 的行为自动触发RDB持久化行为.

相关推荐
isolusion33 分钟前
git仓库的基本概念和流程以及一些基本命令
git
2401_871151071 小时前
12月第十九讲:Redis应用Redis相关解决方案
数据库·redis·缓存
scoone2 小时前
VSCode 中 Git 功能比较:内置 Git、GitLens 与 Git History 插件
ide·git·vscode
赛博末影猫2 小时前
git全教程(长期更新)
git
Y编程小白3 小时前
Git版本控制工具--基础命令和分支管理
大数据·git·elasticsearch
o(╥﹏╥)6 小时前
github如何给本机绑定 ssh密钥(MACOS)
运维·gitee·ssh·github
Pafey7 小时前
git 删除鉴权缓存及账号信息
git·缓存
weisian1518 小时前
Redis篇--常见问题篇2--缓存雪崩(过期时间分散,缓存预热,多级缓存)
数据库·redis·缓存
databook8 小时前
解锁 Git Log 更多实用技巧
git
wang_yb8 小时前
解锁 Git Log 更多实用技巧
git·databook