05 Redis的RDB日志

  • 前言
  • 一、Redis 做内存数据快照的数据
  • 二、Redis 生成 RDB 文件的命令save 和 bgsave
  • 三、Redis 生成RDB文件时的写时复制技术
  • 四、Redis 生成RDB文件时的快照连拍
  • 五、Redis 生成RDB文件时的增量快照
  • 六 Redis 的混合使用 AOF 日志和内存快照RDB
  • 总结

前言

Redis 避免数据丢失的 AOF 方法:

  • 优点:每次执行只需要记录操作命令,需要持久化的数据量不大。只要采用的不是 always 的持久化策略,就不会对性能造成太大影响。
  • 缺点:因为记录的是操作命令,而不是实际的数据,所以用 AOF 方法进行故障恢复的时候,需要逐一把操作日志都执行一遍。如果操作日志非常多,Redis 就会恢复得很缓慢,影响到正常使用。

为避免此问题,Redis提供了另一种持久化方法:内存快照,指内存中的数据在某一个时刻的状态记录。这就类似于照片,当你给朋友拍照时,一 张照片就能把朋友一瞬间的形象完全记下来。

Redis 实现类似照片记录效果的方式,把某一时刻的状态以文件的形式写到磁盘上,也就是快照。即使宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。这个快照文件就称为 RDB ( Redis DataBase)文件。

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

一、Redis 做内存数据快照的数据

Redis 的数据都在内存中,为了提供所有数据的可靠性保证,它执行的是全量快照,把内存中的所有数据都记录到磁盘中,这就类似于给 100 个人拍合影,把每一个人都拍进照片里,一次性记录了所有数据,一个都不少。

给一个人拍照时,只用协调一个人就够了,但是拍 100 人的大合影,却需要协调 100 个人的位置、状态,等等,这当然会更费时费力。给内存的全量数据做快照, 把它们全部写入磁盘也会花费很多时间。而且全量数据越多,RDB 文件就越大,往磁盘上写数据的时间开销就越大。

二、Redis 生成 RDB 文件的命令save 和 bgsave

Redis 的单线程模型就决定了,要尽量避免所有会阻塞主线程的操作,RDB 文件的生成是否会阻塞主线程,这就关系到是否会降低 Redis 的性能。

Redis 提供了两个命令来生成 RDB 文件:

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

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

三、Redis 生成RDB文件时的写时复制技术

在给别人拍照时一旦对方动了,那么这张照片就拍糊了就需要重拍,所以希望对方保持不动。对于内存快照而言,也不希望数据“动”。

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

但是如果快照执行期间数据不能被修改,是会有潜在问题的。在做快照的 20s 时间里,如果这 4GB 的数据都不能被修改,Redis 就不能处理对这些数据的写操作,就会给业务服务造成巨大的影响。

虽然可以用 bgsave 可以避免阻塞,避免阻塞和正常处理写操作并不是一回事。主线程的确没有阻塞,可以正常接收请求,为了保证快照完整性,它只能处理读操作,因为不能修改正在执行快照的数据。

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

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

  • 如果主线程对这些数据也都是读操作(例如图中的键值对 A),那么主线程和 bgsave 子进程相互不影响。

  • 如果主线程要修改一块数据(例如图中的键值对 C), 那么这块数据就会被复制一份,生成该数据的副本。然后bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。

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

四、Redis 生成RDB文件时的快照连拍

对于快照来说,所谓“连拍”就是指连续地做快照。快照的间隔时间变得很短,即使某一时刻发生宕机了,因为上一时刻快照刚执行,丢失的数据也不会太多。但是,这其中的快照间隔时间就很关键了。

如图,先在 T0 时刻做了一次快照,然后又在 T0+t 时刻做了一次快照,在这期间,数据块 5 和 9 被修改了。如果在 t 这段时间内机器宕机了,只能按照 T0 时 刻的快照进行恢复。数据块 5 和 9 的修改值因为没有快照记录,就无法恢复了。

所以要想尽可能恢复数据,t 值就要尽可能小,t 越小,就越像“连拍”。

五、Redis 生成RDB文件时的增量快照

当然也不是t越小越好,虽然 bgsave 执行时不阻塞主线程,但是频繁地执行全量快照也会带来两方面的开销

  • 频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。
  • bgsave 子进程需要通过 fork 操作从主线程创建出来。虽然子进程在创建后不会再阻塞主线程,但是fork 这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁 fork 出 bgsave 子进程,这就会频繁阻塞主线程了。

Redis提供了增量快照:做了一次全量快照后,后续的快照只对修改的数据进行快照记录,避免每次全量快照的开销。

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


缺点

  • 如果对每一个键值对的修改都做个记录,那么如果有 1 万个被修改的键值对,就需要有 1 万条额外的记录。

  • 有的键值对非常小,比如只有 32 字节,而记录它被修改的元数据信息,可能就需要 8 字节,为了“记住”修改,引入的额外空间开销比较大。这对于内存资源宝贵的 Redis 来说,有些得不偿失。

跟 AOF 相比,快照的恢复速度快,但是,快照的频率不好把握,如果频率太低,两次快照间一旦宕机,就可能有比较多的数据丢失。如果频率太高, 又会产生额外开销。

六 Redis 的混合使用 AOF 日志和内存快照RDB

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

优点:

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

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

既能享受到 RDB 文件快速恢复的好处,又能享受到 AOF 只记录操作命令的简单优势。

总结

Redis 用于避免数据丢失的内存快照方法:

  • 优点:可以快速恢复数据库,只需要把 RDB 文件直接读入内存,避免了 AOF 需要顺序、逐一重新执行操作命令带来的低效性能问题;
  • 缺点:内存快照的局限性。它拍的是一张内存的“大合影”,不可避免地会耗时耗力。虽然Redis 设计了 bgsave 和写时复制方式,尽可能减少了内存快照对正常读写的影响,但是频繁快照仍然是不太能接受的。

混合使用 RDB 和 AOF,正好可以取两者之长,避两者之短,以较小的性能开销保证数据可靠性和性能。

使用AOF 和 RDB 的建议:

  • 数据不能丢失时:内存快照和 AOF 的混合使用是一个很好的选择;
  • 允许分钟级别的数据丢失:可以只使用 RDB;
  • 只用 AOF:优先使用 everysec 的配置选项,因为它在可靠性和性能之间取了一个平衡。

05 Redis的RDB日志相关推荐

  1. redis服务器错误日志分析

    未解决的问题 persistence-available no #不用持久化 maxmemory 4gb #内存限制 maxmemory-policy volatile-lru #内存满时,删除设置了 ...

  2. Redis持久化 - RDB和AOF

    一.持久化的作用 1. 什么是持久化 持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘). 持久化Redis所有数据保持在内存中,对数据的更新将异步地保 ...

  3. Redis持久化 RDB和AOF 比较与选择

    Redis持久化方案 Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘.当下次Redis重启时,利 ...

  4. Redis 通过 RDB 方式进行数据备份与还原

    Redis 通过 RDB 方式进行数据备份与还原 Intro 有的时候我们需要对 Redis 的数据进行迁移,今天介绍一下通过 RDB(快照)文件进行 Redis 数据的备份和还原 Redis 持久化 ...

  5. linux 关闭redis 命令_面试必问的 Redis:RDB、AOF、混合持久化

    前言 本来说 Redis 分3篇,但是上周写持久化时发现持久化的内容还越多的,于是持久化就单拆一篇了. 我估计后面的主从复制.哨兵.集群内容也是不少,所以说实话,我也不知道之前说的3篇会拆成几篇了 持 ...

  6. redis rdb aof区别_干货|Redis的RDB和AOF

    作者:Dvelpro 链接:https://blog.nowcoder.net/n/63c9812ce634474280675f3f6bb4d1ca 来源:牛客网 Redis的RDB和AOF 概述 R ...

  7. log4net异步写入日志_redis学习笔记(三)RDB日志

    上文提到了AOF日志,redis会将写命令持久化到AOF日志中,这样做的好处在于只有遇到写命令时才会记录该命令的日志,并且aof中提供了三种写入策略,一般会选用"允许数据有一点丢失,但不希望 ...

  8. Redis 的 RDB 和 AOF

    RDB Redis DataBase 每隔一段时间,把内存中的数据写入磁盘的临时文件,作为快照,恢复的时候把快照文件读进内存,如果宕机重启,那么内存里的数据肯定会没有的,那么再次启动 redis 后, ...

  9. 05 Redis 持久化的设计和实现

    Redis 作为一种非常流行的内存数据库,通过将数据保存在内存中,Redis 得以拥有极高的读写性能.但是一旦进程退出,Redis 的数据就会全部丢失. 为了解决这个问题,Redis 提供了 RDB ...

最新文章

  1. C++中的模板template
  2. Qt Designer信号和槽
  3. 纸牌游戏CardBattle的设计与开发
  4. webuploader 怎么在react中_另辟蹊径搭建阅读React源码调试环境支持所有React版本细分文件断点调试...
  5. 我通过“种树”,拿下鹅厂实习offer
  6. ADO+MFC数据库编程常用语句
  7. Android AppCompatActivity的ActionBar之SearchView、ShareActionProvider以及menu
  8. Java -考研 学习路线(笔记链接汇总)-个人用
  9. 电商系统如何搭建会员体系/会员制玩法?
  10. 计算机最大化快捷键,最大化窗口快捷键,mac窗口最大化快捷键
  11. SQL注入实战 绕WTS-WAF
  12. 每日技巧分享:怎么裁剪音频,快学习起来
  13. android简单计算器源码
  14. 深度学习AI美颜系列----人像静态/动态贴纸特效算法实现
  15. 信号完整性分析系列——1基本概念
  16. Outlook Express Problem --Error Number: 0x800C0133
  17. 沁园春.长沙HTML风格化制作简单代码
  18. 【Xilinx DDR3】Xilinx FPGA DDR3深度介绍
  19. 王者荣耀微信和QQ服务器怎么一起玩游戏,王者荣耀微信和qq能一起吗 可以一起玩吗...
  20. python工程师工作总结_工程师的第一份工作小结

热门文章

  1. TurboMosaic for Mac用六边形瓷砖制作照片马赛克的步骤
  2. 8051(c51)单片机从汇编到C语言,从Boot到应用实践教程
  3. Dubbo+Flutter在线交友平台教程第七天 完善消息功能以及个人主页
  4. LaTex实战笔记 5-段落格式
  5. 道or悼?三分钟看懂史上最逆天的区块链众筹项目The DAO
  6. 在Nvida TX1上搭建ROS
  7. c语言扬声器程序,通过扬声器C编程并播放声音
  8. 如何提高计算机性能计算机组成原理,深入浅出计算机组成原理学习笔记:我们该从哪些方面提升“性能”(第3讲)...
  9. 配置dovecot 以及邮件相关命令
  10. Linux 删除文件夹和文件的命令