RDB内存快照:宕机后,Redis如何实现快速恢复数据

问题聚焦:

  • AOF方法进行故障恢复的时候,需要逐一把操作日志执行一遍,如果操作日志非常多,Redis恢复缓慢。如何在宕机时快速恢复Redis?

之前我们分析了Redis避免数据丢失的AOF方法,这个方法的缺点就是如果操作日志非常多,Redis恢复缓慢。这时就需要使用Redis持久化的另一种机制:内存快照(RDB,Redis DataBase)。所谓内存快照,就是指内存中的数据在某一个时刻的状态记录。这就类似于照片,当你给朋友拍照时,一张照片就能把朋友一瞬间的形象完全记下来。

对Redis来说,实现类似照片记录效果的方式,就是把某一时刻的状态以文件的形式写到磁盘上,也就是快照。

和AOF相比,RDB记录的是某一时刻的数据,并不是操作,所以在做数据恢复时,我们可以直接把RDB文件读入内存,很快地完成恢复。

但但内存快照也并不是最优选项,我们还要考虑两个关键问题:

  • 对哪些数据做快照?这关系到快照的执行效率问题;
  • 做快照时,数据还能被增删改吗?这关系到Redis是否被阻塞,能否同时正常处理请求。

下面主要对这两个问题进行分析

给哪些内存数据做快照?

Redis的数据都在内存中,为了提供所有数据的可靠性保证,它执行的是全量快照,即把内存中的所有数据都记录到磁盘中。

当然这样做的好处是一次性记录了所有数据,但会花费很多时间。

对于Redis而言,它的单线程模型就决定了,我们要尽量避免所有会阻塞主线程的操作,所以我们需要思考,RDB文件的生成是否会阻塞主线程,这就关系到是 否会降低Redis的性能。

Redis提供了两个命令来生成RDB文件,分别是save和bgsave。

  • save:在主线程中执行,会导致阻塞;
  • bgsave:创建一个子进程,专门用于写入RDB文件,避免了主线程的阻塞,这也是Redis RDB文件生成的默认配置。

此时我们就可以通过bgsave命令来执行全量快照,这既提供了数据的可靠性保证,也避免了对Redis的性能影响

快照时数据能修改吗?

首先我们要明白在做快照时也不希望数据“动”,也就是不能被修改。

  • 假设内存数据量是4GB,磁盘的写入带宽是0.2GB/s,简单来说,至少需要20s(4/0.2 = 20)才能做完。如果在时刻t+5s时,一个还没有被写入磁盘的内存数据A,被修改成了 A’,那么就会破坏快照的完整性,因为A’不是时刻t时的状态。

但是,如果快照执行期间数据不能被修改,Redis就不能处理对这些数据的写操作,那无疑就会给业务服务造成巨大的影响。

当然由于前文说到bgsave避免阻塞,我们这里要区分清楚避免阻塞和正常处理写操作并不是一回事。

  • 此时,主线程的确没有阻塞,可以正常接收请求,但是,为了保证快照完整性,它只能处理读操作,因为不能修改正在执行快照的数据。

  • 为了快照而暂停写操作,肯定是不能接受的。所以这个时候,Redis就会借助操作系统提供的写时复制技术 (Copy-On-Write, COW),在执行快照的同时,正常处理写操作。

简单来说,bgsave子进程是由主线程fork生成的,可以共享主线程的所有内存数据。bgsave子进程运行后,开始读取主线程的内存数据,并把它们写入RDB文件。

此时,如果主线程对这些数据也都是读操作(例如图中的键值对A),那么,主线程和bgsave子进程相互不影响。但是,如果主线程要修改一块数据(例如图中的键值对C),那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave子进程会把这个副本数据写入RDB文件,而在这个过程中,主线程仍然可以直接修改原来的数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-grob9lyR-1618156402973)(C:\Users\cfs\Desktop\redis11.png)]

这既保证了快照的完整性,也允许主线程同时对数据进行修改,避免了对正常业务的影响。

自此,我们就解决了对“哪些数据做快照”以及“做快照时数据能否修改”这两大问题:Redis会使用 bgsave对当前内存中的所有数据做快照,这个操作是子进程在后台完成的,这就允许主线程同时可以修改数据。

那么考虑另一个问题:多久做一次快照?我们在拍照的时候,还有项技术叫“连拍”,可以记录人或物连续多个瞬间的状态。那么,快照也适合“连拍”吗?

多久做一次快照?可以每秒做一次快照吗?

由上文我们知道每次快照都是由bgsave子进程在后台执行,也不会阻塞主线程。那为了在宕机时尽量少丢失数据,是不是可以使快照的间隔尽量小,是不是可以每秒做一次快照?

这种想法其实是错误的。虽然bgsave执行时不阻塞主线程,但是,如果频繁地执行全量快照,也会带来两方面的开销 。

  • 1.频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。

  • 2.bgsave子进程需要通过fork操作从主线程创建出来。虽然,子进程在创建后不会再阻塞主线程,但是,fork这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁fork出 bgsave 子进程,这就会频繁阻塞主线程了。

这时我们就可以使用另一种好方法:增量快照。

  • 在第一次做完全量快照后,T1和T2时刻如果再做快照,我们只需要将被修改的数据写入快照文件。但是这么做的前提是我们需要记住哪些数据被修改了。这需要我们使用额外的元数据信息去记录哪些数据被修改了,这也会带来额外的空间开销问题

  • 额外的空间开销问题:如果我们对每一个键值对的修改,都做个记录,那么,如果有1万个被修改的键值对,我们就需要有1万条额外的记录。而且,有的时候,键值对非常小,比如只有32字节,而记录它被修改的元数据信息,可能就需要 8字节,这样为了“记住”修改,引入的额外空间开销较大。这对于内存资源宝贵的Redis来说,有些得不偿失。

通过上面的分析我们知道,快照的恢复速度快,但是快照的频率不好把握,如果频率太低, 两次快照间一旦宕机,就可能有比较多的数据丢失。如果频率太高,又会产生额外开销,那么,还有什么方法既能利用RDB的快速恢复,又能以较小的开销做到尽量少丢数据呢?

Redis 4.0中提出了一个混合使用AOF日志和内存快照的方法。简单来说,内存快照以一定的频率执行,在两次快照之间,使用AOF日志记录这期间的所有命令操作。

这样一来,快照不用很频繁地执行,这就避免了频繁fork对主线程的影响。而且,AOF日志也只需记录两次快照间的操作,也就是说,不需要记录所有操作了,因此,就不会出现文件过大的情况了,也可以避免重写开销。

如下图所示,T1和T2时刻的修改,用AOF日志记录,等到第二次做全量快照时,就可以清空AOF日志,因为此时的修改都已经记录到快照中了,恢复时就不再用日志了。

RDB内存快照:Redis如何实现快速恢复数据相关推荐

  1. 宕机后,redis如何实现快速恢复?(RDB 内存快照)

    AOF 记录的是操作命令,而不是实际的数据,所以使用 AOF 方法进行故障恢复的时候,需要逐一把操作日志都执行一遍.如果操作日志非常多,redis 就会恢复得很缓慢,影响到正常使用.所以,redis ...

  2. Redis持久化:RDB内存快照

    AOF 方法好处:每次执行只需要记录操作命令,需要持久化的数据量不大.一般而言,只要你采用的不是 always 的持久化策略,就不会对性能造成太大影响. 但是,也正因为记录的是操作命令,而不是实际的数 ...

  3. 04 | 内存快照:宕机后, Redis 如何实现快速恢复

    文章目录 1. RDB内存快照的局限性 2. 给哪些内存数据做快照 3. 快照时数据能修改吗 4. 可以每秒做一次快照吗 4. 数据快速恢复 Redis 一另一种种持久化方法:内存快照.所谓内存快照, ...

  4. redis 什么是冷数据_redis 冷数据存储格式

    92题 一般来说,建立INDEX有以下益处:提高查询效率:建立唯一索引以保证数据的唯一性:设计INDEX避免排序. 缺点,INDEX的维护有以下开销:叶节点的'分裂'消耗:INSERT.DELETE和 ...

  5. Redis核心技术与实战-学习笔记(五)内存快照RDB

    一.为什么需要RDB AOF 方法优势:每次执行只需要记录操作命令,需要持久化的数据量不大.在进行写后日志只要不采用always(同步写回)的持久化策略就不会对性能造成太大影响. AOF方法劣势:AO ...

  6. 内存快照:宕机后,Redis如何实现快速恢复?

    上节课,我们学习了Redis避免数据丢失的AOF方法.这个方法的好处,是每次执行只需要记录操作命令,需要持久化的数据量不大.一般而言,只要你采用的不是always的持久化策略,就不会对性能造成太大影响 ...

  7. 05 _ 内存快照:宕机后,Redis如何实现快速恢复?

    用AOF方法进行故障恢复的时候,需要逐一把操作日志都执行一遍.如果操作日志非常多,Redis就会恢复得很缓慢,影响到正常使用.这当然不是理想的结果.那么,还有没有既可以保证可靠性,还能在宕机时实现快速 ...

  8. Redis 内存快照:宕机后,Redis如何实现快速恢复?

    上节课,我们学习了 Redis 避免数据丢失的 AOF 方法.这个方法的好处,是每次执行只需要记录操作命令,需要持久化的数据量不大.一般而言,只要你采用的不是 always 的持久化策略,就不会对性能 ...

  9. 图解 Redis丨这就是 RDB 快照,能记录实际数据的

    摘要:所谓的快照,就是记录某一个瞬间东西,比如当我们给风景拍照时,那一个瞬间的画面和信息就记录到了一张照片.RDB 快照就是记录某一个瞬间的内存数据,记录的是实际数据. 本文分享自华为云社区<图 ...

最新文章

  1. SpringCloud配置中心-Config
  2. MFC中的文件读写技术
  3. 函数式编程语言天生就慢吗?
  4. linux指令:输出重定向与追加- 输出重定向 - 表示追加
  5. Linux经典书籍推荐-转
  6. Git基础知识与常用命令
  7. 第10章第4节:使用iSlide的统一色彩命令统一修改某个颜色 [PowerPoint精美幻灯片实战教程]
  8. python识别二维码
  9. 文件MD5/SHA等校验码校验
  10. JavaScipt基础(持续更新)
  11. org.springframework.dao.InvalidDataAccessApiUsageException:The given object has a null identifi的解决方案
  12. Android~获取WiFi MAC地址和IP方法汇总
  13. 黏贴图片到word文档图片显示不全,只显示一行(保姆级图文)
  14. deep deepfm wide 区别_FM算法和DeepFM算法
  15. c语言高精度算法(加法)
  16. 我的十年青春(10至20):写博10年1700万PV、创业5年30万学员
  17. 股票level2数据接口获取逐笔成交数据的过程
  18. SBIO | 浙大陈云组综述农业中细菌与真菌的互作机制
  19. 10 个免费的服务器监控工具
  20. 1.1微处理器与微型计算机的发展概述

热门文章

  1. Microsoft Visual C++ 2005 Redistributable---win下安装软件“嘭”的一声报错!
  2. 金坷垃-easy (模拟
  3. 华为Nova9怎么解账号锁Nova9Pro忘记密码ID账号锁解除方案开机设备解锁帐号软件使用方法
  4. 法兰克机械手手动操作_法兰克机械手操作说明
  5. 计算1加到100的和
  6. C语言课程设计:医院管理系统
  7. 大数据的10大发展趋势
  8. 一篇文章了解_docker
  9. Hash(哈希)简述 —— Hash函数、Hash值、HashTable、HashMap
  10. 去电流程分析---之一