当前位置: 首页 > news >正文

【Redis】——RDB快照

Redis 是内存数据库,但是它为数据的持久化提供了两个技术,一个是AOF日志,另一个是RDB快照:

  • AOF 文件的内容是操作命令;
  • RDB 文件的内容是二进制数据。

RDB 快照就是记录某一个瞬间的内存数据,记录的是实际数据,而 AOF 文件记录的是命令操作的日志,而不是实际的数据。

因此在 Redis 恢复数据时, RDB 恢复数据的效率会比 AOF 高些,因为直接将 RDB 文件读入内存就可以,不需要像 AOF 那样还需要额外执行操作命令的步骤才能恢复数据

快照的使用

Redis 提供了两个命令来生成 RDB 文件,分别是 save 和 bgsave,他们的区别就在于是否在「主线程」里执行:

  • 执行了 save 命令,就会在主线程生成 RDB 文件,由于和 执行操作命令 在同一个线程,所以如果写入 RDB 文件的时间太长,阻塞主线程
  • 执行了 bgsave 命令,会创建一个子进程来生成 RDB 文件,这样可以避免主线程的阻塞

Redis  可以 通过配置文件的选项来实现每隔一段时间 自动执行一次 bgsave 命令,默认会提供以下配置:

save 900 1 #900 秒之内,对数据库进行了至少 1 次修改;
save 300 10 #300 秒之内,对数据库进行了至少 10 次修改
save 60 10000 #60 秒之内,对数据库进行了至少 10000 次修改

只要满足上面任何一个条件,都会自动 执行一次 bgsave 命令 生成RDB文件

  • Redis 的快照是全量快照,也就是说每次执行快照,都是把 内存中的「所有数据」都记录到磁盘中。所以 执行快照是一个比较重的操作。
  • 如果 执行频率太频繁,可能会对 Redis 性能产生影响
  • 通常 可能设置 至少 5 分钟才保存一次快照,这时如果 Redis 出现宕机等情况,则意味着最多可能丢失 5 分钟数据

因此redis服务器宕机,RDB快照损失的数据比AOF日志损失的数据要多。

执行快照时,数据能被修改吗?

执行 bgsave 过程中,由于是交给子进程来构建 RDB 文件,主线程还是可以继续工作的,关键的技术就在于写时复制技术(Copy-On-Write, COW)。

执行 bgsave 命令的时候,会通过 fork() 创建子进程,此时 子进程 和 父进程 是共享同一片内存数据的,因为创建子进程的时候,会复制父进程的页表,但是页表指向的相同的物理内存

只有在发生修改内存数据的情况时,物理内存才会被复制一份:

如果主线程(父进程)要修改共享数据里的某一块数据(比如键值对 A)时,就会发生写时复制,于是这块数据的 物理内存就会被复制一份(键值对 A',然后主线程在这个数据副本(键值对 A')进行修改操作。与此同时,bgsave 子进程可以继续把原来的数据(键值对 A)写入到 RDB 文件。 

但是程刚修改的数据,子线程 是没办法在这一时间写入 RDB 文件的,只能交由下一次的 bgsave 快照。

所以 Redis 在使用 bgsave 快照过程中,如果主线程修改了内存数据,不管是否是共享的内存数据,RDB 快照都无法写入主线程刚修改的数据,因为此时主线程(父进程)的内存数据和子进程的内存数据已经分离了,子进程写入到 RDB 文件的内存数据只能是原本的内存数据

 

RDB 和 AOF 合体

即使 RDB 比 AOF 的数据恢复速度快,但是快照的频率不好把握:

  • 如果频率太低,两次快照间一旦服务器发生宕机,就可能会比较多的数据丢失;
  • 如果频率太高,频繁写入磁盘和创建子进程会带来额外的性能开销。

混合使用 AOF 日志和内存快照

它的作用是 既有 AOF 丢失数据少 和 又有 RDB 恢复速度快 的优点;

如果想要开启混合持久化功能,可以在 Redis 配置文件 将下面这个配置项设置成 yes

aof-use-rdb-preamble yes

当开启了混合持久化后,在 AOF 重写日志时:

  1. fork 出来的重写子进程会先将与主线程共享的 内存数据 以 RDB 方式写入到 AOF 文件。
  2. 同时, 主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区里的增量命令会以 AOF 方式写入到 AOF 文件
  3. 写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件

总结:AOF 文件前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据

 

http://www.lryc.cn/news/115138.html

相关文章:

  • 微服务监控技术skywalking的部署与使用(亲测无坑)
  • DLA 神经网络的极限训练方法:gradient checkpointing
  • python excel 操作
  • 记一次Linux启动Mysql异常解决
  • ATFX汇市:美联储年内或仍将加息依次,美指向下空间不大
  • 【博客687】k8s informer的list-watch机制剖析
  • 用Python获取链家二手房房源数据,做可视化图分析数据
  • Yield Guild Games:社区更新 — 2023 年第二季度
  • Stable Diffusion - 运动服 (Gymwear Leggings) 风格服装与背景的 LoRA 配置
  • js-7:javascript原型、原型链及其特点
  • 无涯教程-Perl - continue 语句函数
  • 【贪心算法】leetcode刷题
  • PyMySQL库版本引起的python执行sql编码错误
  • 第二章-算法
  • ‘vue’不是内部或外部命令,也不是可运行的程序或批处理文件的原因及解决方法
  • HBase API
  • Qt6之QListWidget——Qt仿ToDesk侧边栏(1)
  • Prometheus技术文档--基本安装-docker安装并挂载数据卷-《十分钟搭建》
  • Android 数据库之GreenDAO
  • kotlin 编写一个简单的天气预报app(六)使用recyclerView显示forecast内容
  • jpa Page 1 of 0 containing UNKNOWN instances错误关于like问题的解决记录
  • Python实战之使用Python进行数据挖掘详解
  • scala 加载properties文件
  • 备战秋招012(20230808)
  • QT中定时器的使用
  • 【UE4】多人联机教程(重点笔记)
  • 【go】GIN参数重复绑定报错EOF问题
  • 关于MySQL中的binlog
  • 我维护电脑的方法
  • AP51656 电流采样降压恒流驱动IC RGB PWM深度调光 LED电源驱动