Redis持久化技术之RDB快照 学习笔记

前言

所谓快照,就是记录某一瞬间的内存数据,因此,不同于AOF日志记录的是操作命令,RDB文件的内容是二进制数据。因此在Redis恢复数据时,采用RDB的效率会更高,直接将RDB文件读入内存即可,不需要像AOF那样还需要额外执行命令来恢复数据

RDB实现原理

Redis提供了两个命令来生成RDB文件,区别在于是否在主进程里执行:

  • save:在主进程里生成RDB文件,由于和执行操作命令在同个进程,所以如果写入时间过长,会阻塞主进程
  • bgsave:创建一个子进程来生成RDB文件,避免阻塞主进程

Redis并没有提供专门用于加载RDB文件的命令,是在服务器启动时自动执行RDB文件的加载

不过,如果采用的是bgsave命令,可以通过配置来实现命令自动执行,默认配置如下:

复制代码
save 900 1
save 300 10
save 60 10000

解释:

  • 900秒之内,对数据库进行了至少1次修改,就会执行bgsave
  • 300秒之内,对数据库进行了至少10次修改,就会执行bgsave
  • 60秒之内,对数据库进行了至少10000次修改,就会执行bgsave

性能分析

注意:Redis的快照是全量快照,即每次执行快照时,都是把内存中的所有数据记录到磁盘中。

可以认为执行快照是一个比较重的操作,如果太频繁可能对Redis产生性能影响;但是如果频率太低,发生故障时,丢失的数据会更多。

通常设置至少5分钟才保存一次RDB快照,这时如果Redis发生宕机,最多丢失5分钟数据

这就是RDB快照的缺点,在发生服务器故障时,丢失的数据会比AOF持久化方式更多,因为RDB快照是采用全量快照的方式,因此执行频率不能太频繁,否则影响Redis性能,而AOF日志可以秒级记录操作命令,相对丢失的数据更少。

bgsave写时复制

执行bgsave过程中,Redis依然可继续处理命令,主进程会通过fork()创建子进程,此时父子进程共享同一片内存数据,页表执行同个物理内存空间。

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

写时复制的目的是减少创建子进程的性能损耗,从而加快创建子进程速度,毕竟创建子进程是会阻塞主进程的。

数据不一致

bgsave过程中,如果主进程修改了共享数据,发生写时复制后,RDB快照保存的是原来的内存数据,而主进程刚修改的数据,只能交由下一次的bgsave命令。

如果恰好系统在RDB快照文件创建完毕后宕机,那么Redis将丢失主进程此前在该写快照期间修改的数据

内存占用激增

在Redis执行RDB持久化期间,刚fork时,主进程和子进程共享同一物理内存数据,但途中主进程处理了写操作,修改了共享内存,于是当前被修改数据的物理内存就被复制一份。

极端情况下,如果所有的共享内存都被修改了,此时的内存占用将是原来的2倍。

因此,针对写操作多的场景,要留意下RDB快照记录过程的内存变化,防止OOM。

参考

《小林coding》

相关推荐
阿镇吃橙子3 分钟前
一些手写及业务场景处理问题汇总
前端·算法·面试
逆袭的小黄鸭4 分钟前
JavaScript:作用域与作用域链的底层逻辑
前端·javascript·面试
Smilejudy9 分钟前
不可或缺的相邻引用
后端
惜鸟9 分钟前
Elasticsearch 的字段类型总结
后端
rebel11 分钟前
Java获取excel附件并解析解决方案
java·后端
微客鸟窝13 分钟前
Redis常用数据类型和命令
后端
熊猫片沃子14 分钟前
centos挂载数据盘
后端·centos
微客鸟窝15 分钟前
Redis配置文件解读
后端
不靠谱程序员17 分钟前
"白描APP" OCR 软件 API 逆向抓取
后端·爬虫
小华同学ai19 分钟前
6.4K star!企业级流程引擎黑马,低代码开发竟能如此高效!
后端·github