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. mysql GTID主从复制故障后不停机恢复同步流程

    GTID实现主从复制数据同步 GTID是一个基于原始mysql服务器生成的一个已经被成功执行的全局事务ID,它由服务器ID以及事务ID组成,这个全局事务ID不仅仅在原始服务器上唯一,在所有主从关系的m ...

  2. MIT-6.006算法导论(2011秋)

    L01 Algorithmic Thinking,Peak Finding 算法定义:高效处理大量数据的程序 在学本课之前最好先学习6.042,本课进阶为6.046 本门课的8个主要章节:算法思想.排 ...

  3. 《高并发下的.NET》第2季 - 故障公告:高并发下全线崩溃

    大家好,非常抱歉,在昨天下午(12月3日)的访问高峰,园子迎来更高的并发,在这样的高并发下,突发的数据库连接故障造成博客站点全线崩溃,由此给您带来很大的麻烦,请您谅解. 最近,我们一边在忙于AWS合作 ...

  4. MacOS JMeter安装(多图)

    本文基于 MacOS 环境下进行 Jmeter 的安装. 一.下载JMeter 本文选用 JMeter 5.3 版本安装,5.3 版本需要 JDK 1.8 + 版本环境. Jmeter 5.3 下载: ...

  5. 一种更优雅的Flutter Dialog解决方案

    前言 系统自带的Dialog实际上就是Push了一个新页面,这样存在很多好处,但是也存在一些很难解决的问题 必须传BuildContext loading弹窗一般都封装在网络框架中,多传个contex ...

  6. 大数据开发-Hive-常用日期函数&&日期连续题sql套路

    前面是常用日期函数总结,后面是一道连续日期的sql题目及其解法套路. 1.当前日期和时间 select current_timestamp -- 2020-12-05 19:16:29.284 2.获 ...

  7. 转:解析HTTP协议六种请求方法,get,head,put,delete,post有什么区别

    解析HTTP协议六种请求方法,get,head,put,delete,post有什么区别 标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5.HEAD ...

  8. msfvenom命令自动补全工具下载=>msfvenom-zsh-completion

    msfvenom参数和命令很多,各种payload和encoder经常让⼈眼花缭乱,特别是对英语不好的⼈来说有些命令可能很容易忘记. 所以 Green_m 开发了⼀个zsh插件,可以⾃动化的补全msf ...

  9. 3、tensorflow变量运算,数学运算

    import tensorflow as tf import numpy as np a = tf.range(1,7) a = tf.reshape(a,[2,3]) b = tf.constant ...

  10. html标签和body标签的区别

    首先想要总结这个问题就是因为在开发的过程中,在设置body的高度的时候,在浏览器窗口中并不起作用,一直都会显示是浏览器窗口的大小,所以想要搞清楚这面的原因. 一.前提 在页面的设计中,当我们没有为一个 ...