AOF好处是每次执行只需要记录操作命令,记录量不大。但在故障恢复时,需要逐一执行AOF的操作命令,如果日志很大,恢复就很慢。

今天学习另一种持久化方式:内存快照。内存快照,是Redis某一时刻的状态,以文件的形式保存在磁盘上。这个快照文件就称为RDB文件,其中RDB就是Redis Database的缩写。

当故障恢复时,只要把RDB文件读入内存即可,恢复速度很快。但是内存快照并不是最优选项,为什么呢?

我们还需要考虑两个问题:

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

对哪些数据做快照?

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

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

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

做快照时,数据还能被增删改吗?

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

Redis借助操作系统提供的写时复制技术(Copy-On-Write,COW),在执行快照的同时,正常处理写操作。

bgsave子进程是由主线程fork生成的,可以共享主线程的所有内存数据。

当主线程要修改数据时,通过COW复制一份副本出来给bgsave子进程。

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

可以每秒做一次快照吗?

如果内存快照每隔几分钟执行一次,这样就可能出现丢失数据的风险。那么是否可以每秒做一次快照吗?

如果频繁地执行全量快照,会带来两方面开销:

  • 一是频繁将全量数据写入磁盘,会给磁盘带来很大压力。
  • 二是bgsave子进程需要从主线程fork出来,fork创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。

既然频繁执行全量快照不行,那还有什么其他好方法吗?

第一个方法是做增量快照

在第一次做完全量快照后,T1和T2时刻如果再做快照,只需要将被修改的数据写入快照文件就行了。如下图所示:

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

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

拓展

使用一个2核CPU、4GB内存、500GB磁盘的云主机运行Redis,Redis数据库的数据量大小差不多是2GB,使用了RDB做持久化保证。当时Redis的运行负载以修改操作为主,写读比例差不多在8:2左右,也就是说,如果有100个请求,80个请求执行的是修改操作。在这个场景下,用RDB做持久化有什么风险吗?

主要有两方面风险:内存资源风险CPU资源风险

内存资源风险

Redis fork子进程做RDB持久化,由于写的比例为80%,那么在持久化过程中,“写时复制”会重新分配整个实例80%的内存副本,大约需要重新分配1.6GB内存空间,这样整个系统的内存使用接近饱和。

如果此时父进程又有大量新key写入,很快机器内存就会被吃光,如果机器开启了Swap机制,那么Redis会有一部分数据被换到磁盘上。

当Redis访问这部分在磁盘上的数据时,性能会急剧下降,已经达不到高性能的标准。

如果没有开启Swap,会直接触发OOM,父子进程会面临被系统kill掉的风险。

CPU资源风险

虽然子进程在做RDB持久化,但生成RDB快照过程会消耗大量的CPU资源。

虽然Redis处理请求是单线程的,但Redis Server还有其他线程在后台工作,例如AOF每秒刷盘、异步关闭文件描述符这些操作。

由于机器只有2核CPU,这也就是意味着父进程占用了超过一半的CPU资源。

此时子进程做RDB持久化,可能会产生CPU竞争,导致的结果是父进程处理请求延迟增大,子进程生成RDB快照的时间也会变长,整个Redis Server性能下降。

如果Redis进程绑定了CPU,那么子进程会继续父进程的CPU亲和性属性,子进程必然会与父进程争夺同一个CPU资源,整个Redis Server的性能必然会受到影响。

因此如果Redis需要开启定时RDB和AOF重写,进程一定不要绑定CPU。

参考资料

Redis基础篇(四)持久化:内存快照(RDB)的更多相关文章

  1. Redis持久化——内存快照(RDB)

    最新:Redis持久化--如何选择合适的持久化方式 最新:Redis持久化--AOF日志 最新:Redis持久化--内存快照(RDB) 一文回顾Redis五大对象(数据类型) Redis对象--有序集 ...

  2. Redis基础学习(四)—Redis的持久化

    一.概述      Redis的强大性能很大程度上都是因为数据时存在内存中的,然而当Redis重启时,所有存储在内存中的数据将会丢失,所以我们要将内存中的数据持久化. Redis支持两种数据持久化的方 ...

  3. Redis的两种持久化方式-快照持久化(RDB)和AOF持久化

    Redis为了内部数据的安全考虑,会把本身的数据以文件形式保存到硬盘中一份,在服务器重启之后会自动把硬盘的数据恢复到内存(redis)的里边,数据保存到硬盘的过程就称为“持久化”效果. redis有两 ...

  4. Redis基础篇(三)持久化:AOF日志

    Redis是内存数据库,但是一旦服务器宕机,内存中的数据将会全部丢失. 最简单的恢复方式是从后端数据库恢复,但这种方式有两个问题: 频繁访问数据库,会给数据库带来巨大的压力: 从数据库中读取相比从Re ...

  5. Redis基础篇(五)AOF与RDB比较和选择策略

    RDB和AOF对比 关于RDB和AOF的优缺点,官网上面也给了比较详细的说明redis.io/topics/pers- RDB 优点: RDB快照是一个压缩过的非常紧凑的文件,保存着某个时间点的数据集 ...

  6. Redis 中的数据持久化策略(RDB)

    Redis 是一个内存数据库,所有的数据都直接保存在内存中,那么,一旦 Redis 进程异常退出,或服务器本身异常宕机,我们存储在 Redis 中的数据就凭空消失,再也找不到了. Redis 作为一个 ...

  7. redis基础篇

    1.redis常见的数据结构 redis是一种以键值对存储的高性能内存数据库,有五种常用的数据类型,string,list,hash,set,zset. 2.redis的过期时间 redis中的key ...

  8. Redis的两种持久化方式-快照持久化和AOF持久化

    Redis为了内部数据的安全考虑,会把本身的数据以文件形式保存到硬盘中一份,在服务器重启之后会自动把硬盘的数据恢复到内存(redis)的里边,数据保存到硬盘的过程就称为"持久化"效 ...

  9. docker+k8s基础篇四

    Docker+K8s基础篇(四) pod控制器 A:pod控制器类型 ReplicaSet控制器 A:ReplicaSet控制器介绍 B:ReplicaSet控制器的使用 Deployment控制器 ...

随机推荐

  1. 没有wget Loading mirror speeds from cached hostfile

    问题描述 新装的系统,没有一些常用命令的rpm包.使用ifconfig,报错 Loading mirror speeds from cached hostfile解决 网上解决方案是换数据下载源,但是 ...

  2. 团队作业第三次 —— UML设计

    这个作业要求在哪里 https://edu.cnblogs.com/campus/fzzcxy/2018SE2/homework/11366 这个作业的目标 <团队一起设计UML图> 团队 ...

  3. MockWebServer使用指南(转载)

    转载自(http://blog.csdn.net/shensky711/article/details/52771797 ) MockWebServer介绍 MockWebServer是square出 ...

  4. 面试官:说一下List排序方法

    1. 前言 排序算是比较高频的面试题了,节前面试了的两家公司都有问到排序问题,整理后分享给大家(文末见总结). 通常我们想到实现排序就是 Collections 工具类的 sort() 方法,而 so ...

  5. 问题:PyCharm调试方法Force Step over与step over的区别

    Force Step over与step over的差别是,后者在执行到函数时,如果函数中设置了断点,会在该函数断点处暂停,等待进一步调试指令,而Force Step over不论函数中是否有断点,都 ...

  6. 超详细讲解mysql存储过程中的in/out/inout

    存储过程 大概定义:用一个别名来描述多个sql语句的执行过程. 最简单 delimiter // create PROCEDURE p1() begin select * from userinfo; ...

  7. windows server2012无法安装.Net FrameWork 3.5功能

    问题描述: 现象1:安装完服务器系统,在安装SQL Server 2012,安装到中间提示安装SQL Server 2012过程中出现"启用windows功能NetFx3时出错"以 ...

  8. python 练习洗牌

    生成随机数需要引入random模块,学习下random模块中常用的几个函数: random.random() 用于生成一个0到1的随机符点数: 0 <= n < 1.0 random.un ...

  9. Jmeter(三十二) - 从入门到精通 - Jmeter Http协议录制脚本工具-Badboy5(详解教程)

    1.简介 这一篇文章,宏哥主要想讲解一下,录制完脚本不是就完事了,我们有时候还需要断言,看结果是否和我们预期的结果一致.这在测试中都是很重要的.用句老话说:只看结果不看过程. 2.录制脚本 想要断言, ...

  10. Scrum 冲刺 第六篇

    Scrum 冲刺 第六篇 每日会议照片 昨天已完成工作 队员 昨日完成任务 黄梓浩 完成app项目架构搭建 黄清山 完成部分个人界面模块数据库的接口 邓富荣 完成登录注册接口 钟俊豪 完成部分博客圈模 ...