Redis系列:RDB内存快照提供持久化能力
1 介绍
从上一篇的 《深刻理解高性能Redis的本质》 中可以知道, 我们经常在数据库层上加一层缓存(如Redis),来保证数据的访问效率。
这样性能确实也有了大幅度的提升,因为从内存中取数远比从磁盘中快的多,但是本身Redis也是一层服务,也存在宕机、故障的可能性。
一旦服务挂起,可能生产的后果包括如下几方面:
1. Redis的数据是存在内存中的,所以一旦挂起,内存中的数据会全部丢失。
2. I/O从内存层级迁移到磁盘层级,性能极速下降。
3. 原本访问缓存的请求会透过缓存层直接投向数据库,给数据库带来极大的压力,甚至导致雪崩。
所以,缓存层崩溃产生的后果是灾难的。为了避免宕机和宕机后的数据丢失, 为了保证数据的快速恢复,Redis提供了两个持久化数据的能力,RDB Snapshot 和 AOF(Append Only FIle)日志。本章我们先来看看RDB快照的使用。
2 什么是RDB内存快照
大规模高并发的分布式场景,经常会遇到问题就是Redis挂起,导致访问失败,而所有的请求透过缓存层投向数据库,给数据库造成极大的压力,甚至雪崩。
而Redis的数据是存储在高速缓存中,即使我们重启并且恢复使用,缓存池依旧是空的,因为内存被释放了。
重新建立缓存的过程,对数据库也是一个暴击的过程,很可能会导致整个系统调用链的雪崩。参考我的这篇《架构与思维:一次缓存雪崩的灾难复盘》
所以更为稳妥的办法是持久化到磁盘中,这样哪怕重启数据也不会消失。但是如果每次数据的变化(增、删、改)都要写内存并同时写磁盘,这样成本太高,内存+磁盘的持续数据同步,会让 Redis 性能大大降低。而且还要保证原子性操作,避免内存和磁盘的数据不一致。
2.1 使用内存快照
为了避免实时写入高频操作磁盘带来的负面效应。Redis提供了内存快照策略。
工作原理是,Redis在指定的时间间隔内,将内存中的数据集快照定格下来,写入磁盘,并存储在副本文件中。当Redis重启时,这些快照文件会被自动读取并恢复到内存中。打游戏的同学可以想象存盘,下一次恢复游戏,可以从存盘的地方读取游戏直接开始。

如上图,将指定时间的Redis缓存数据进行快照。当发生故障的时候,直接从最接近的时间点进行数据恢复(即21:10的故障按照21点的RDB快照进行恢复),直接将 RDB 文件读入内存完成恢复。
2.2 生成RDB策略
在Redis的RDB持久化方案中,提供了两种模式来生成RDS文件,分别是 SAVE 和 BGSAVE。虽然都是用于创建内存快照并保存到磁盘的命令,但两者在执行方式和影响上有明显的区别。
SAVE命令会阻塞当前Redis服务器进程,直到RDB文件创建完毕。
在执行SAVE命令期间,Redis不能处理其他命令,阻塞主进程,这会导致服务器无法响应其他请求,直到RDB过程完成为止。因此,当数据量较大时,使用SAVE命令可能会对Redis的性能产生较大影响。
BGSAVE命令则会在后台异步进行快照操作,同时Redis还可以继续处理客户端的请求。
BGSAVE命令通过fork一个子进程来完成持久化任务,这样主进程就不会被阻塞,从而保证了Redis的高可用性。但是,由于需要fork一个子进程,BGSAVE命令可能会消耗更多的内存资源。
2.2.1 SAVE模式
save模式是主进程执行,非常不建议使用主进程执行的方式,在笔者的 《深刻理解高性能Redis的本质》 一文中,
我们介绍了它的主操作都是在单线程模型上完成的。所以 RDB 文件生成会影响主线程的网络I/O和键值对读写,导致客户端正常操作被阻塞,所以应该尽量避免。
2.2.2 BGSAVE模式
bgsave是后台异步执行,通过调用glibc函数创建一个子进程专门用于写入RDB文件,从而避免了主线程的阻塞。当执行BGSAVE命令时,Redis会继续处理其他客户端请求(比如Get、Set等),而子进程会在后台完成RDB文件的生成。这是Redis RDB文件生成的默认配置,也是推荐的方式。

上图执行流程如下:
- 执行bgsave命令,Redis主进程判断当前是否存在正在执行的RDB/AOF子进程,若果存在则bgsave命令直接返回。
- 主进程执行fork操作创建子进程,fork操作过程中父进程会阻塞(创建子进程),通过
info stats命令查看latest_fork_usec选项,可以获取最近一个fork操作的耗时,单位为微秒 - 父进程fork完成后,bgsave命令返回
Background saving started信息,之后的操作都是异步的了,不再阻塞主进程,Client的Get、Set等操作依然可以执行。 - fork子进程的做法是通过调用glibc函数进行创建的,这步骤跟第2点对齐,都是会有短暂的阻塞。
- 子进程创建RDB文件,在主进程内存中生成临时快照文件,完成后对原有文件进行原子替换。执行
lastsave命令可以获取最后一次生成RDB的时间,对应rdb_last_save_time选项。 - 子进程发送信号给主进程表示完成,主进程接受到信息并更新统计记录。
以上整个过程保证了快照的完整性,也允许主进程同时对数据进行修改,避免了对正常业务的影响。
2.2.3 避免过频的全量Snapshot
虽然说Redis 使用 bgsave 函数 fork 子进程在后台完成内存中的数据做快照,并不阻塞父进程继续处理客户端的操作。
但过频执行全量数据快照,依然会导致严重的性能开销,主要如下:
- 频繁生成 RDB 文件写入磁盘,磁盘空间占用大,IO压力大,也会降低效率。
- fork 出来的 bgsave 子进程因为共享主线程的资源,一定程度上会影响主线程的运行性能。
2.3 总结
快照的恢复速度快,但是生成 RDB 文件的频率需要把握一个度,频率过低快照间隔数据较大,丢失的数据就会比较多;频率太快,又会消耗额外开销,降低Redis性能。
RDB内存快照优缺点如下:
优点:
- RDB以一种二进制格式+数据压缩的方式写磁盘,文件轻量。
- 数据恢复速度快,用于灾难恢复的场景,加载 RDB 恢复数据远快于 AOF 方式。
缺点:
- 无法做到实时持久化,每次都要创建子进程, 频繁操作成本过高
- 保存后的二进制文件, 存在老版本不兼容新版本 rdb 文件的问题
- 数据恢复不完全,快照时间点和故障时间点之间必然有时间差、数据差
Redis系列:RDB内存快照提供持久化能力的更多相关文章
- Redis系列之-—内存淘汰策略(笔记)
一.Redis ---获取设置的Redis能使用的最大内存大小 []> config get maxmemory ) "maxmemory" ) " --获取当前内 ...
- Redis的两种持久化方式-快照持久化(RDB)和AOF持久化
Redis为了内部数据的安全考虑,会把本身的数据以文件形式保存到硬盘中一份,在服务器重启之后会自动把硬盘的数据恢复到内存(redis)的里边,数据保存到硬盘的过程就称为“持久化”效果. redis有两 ...
- Redis系列2:数据持久化提高可用性
1 介绍 从上一篇的 <深刻理解高性能Redis的本质> 中可以知道, 我们经常在数据库层上加一层缓存(如Redis),来保证数据的访问效率. 这样性能确实也有了大幅度的提升,但是本身Re ...
- linux之 redis 的rdb 转 aof 及主从复
redis持久化RDB基于快照的持久化通过save命令,强制持久化 在redis.conf中dbfilename dbmp.rdbsave 900 1save 300 10save 60 10 ...
- Redis基础篇(四)持久化:内存快照(RDB)
AOF好处是每次执行只需要记录操作命令,记录量不大.但在故障恢复时,需要逐一执行AOF的操作命令,如果日志很大,恢复就很慢. 今天学习另一种持久化方式:内存快照.内存快照,是Redis某一时刻的状态, ...
- Redis持久化——内存快照(RDB)
最新:Redis持久化--如何选择合适的持久化方式 最新:Redis持久化--AOF日志 最新:Redis持久化--内存快照(RDB) 一文回顾Redis五大对象(数据类型) Redis对象--有序集 ...
- Redis系列(三):Redis的持久化机制(RDB、AOF)
本篇博客是Redis系列的第3篇,主要讲解下Redis的2种持久化机制:RDB和AOF. 本系列的前2篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装. Redis系列(二): ...
- redis 系列16 持久化 RDB
一.概述 Redis是内存数据库,一旦服务器进程退出,服务器中的数据库内存数据状态也会消失.为了解决这个问题,Redis提供了RDB 持久化功能,这个功能可以将redis在内存中的数据库状态保存到磁盘 ...
- redis系列:RDB持久化与AOF持久化
前言 什么是持久化? 持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中.XML数 ...
- redis 实战操作RDB和AOF快照持久化
前言:redis是我们常用的缓存方式,今天就来介绍下两种持久化的方式吧,先科普概念,再实战操作 一.RDB Redis将某一时刻的快照(备份的数据库数据)保存成一种称为RDB格式的文件中,这种格式是经 ...
随机推荐
- 提高Android Studio的编译速度(更快出包减少等待)
硬件和软件的准备 对于经常要出包而且一次要出多个渠道APK的同事来说,每次漫长的打包等待是一件消耗生命且无意义事情. google官方提高编译速度的文档:https://developer.andro ...
- Redis安装及使用详解篇
一.什么是Redis? Redis(Remote Dictionary Server ),即远程字典服务. Redis是是现在最受欢迎的NoSQL数据库之一,是一种支持key-value等多种数据结构 ...
- Redis中的key的生存时间和过期时间
目录 1.说明 2.指令 2.1.删除和更新 3.过期时间的保存 4.计算剩余生存时间 5.过期键的删除策略 5.1.定时删除 5.2.惰性删除 5.3.定期删除 1.说明 生存时间: (Time T ...
- Odoo16—即时通信模块discuss
odoo中自带的discuss模块是一个简易版的即时通信系统,虽然简单,但是功能还是挺强劲的.可以发送图文消息,可以语音,可以视频,也可以共享屏幕,看下效果吧! PC端效果 手机端效果 重点说明 没错 ...
- Adoquery.Refresh 慎用。。。。非常严重,会带来各种问题。
adoquery.refresh 各种问题,根本启不到刷新的作用.完全不刷新的节奏. 修改成已经打印后,如果用adoquery.refresh的话,这两个订单 并不会被刷新掉,惨吧......
- MYSQL 3 DAY
目录 MySQL day03 1.约束 1.1.唯一性约束(unique) 1.2.主键约束 1.3.外键约束 2.存储引擎?(整个内容属于了解内容) 2.1.完整的建表语句 2.2.什么是存储引擎呢 ...
- JOISC 2022 记录
Day1 T1 Jail 操作很类似华容道.由于这题是可以树,同时每一个人走的都是最短路,这也就意味着不会出现通过好多个人一起的挪动来匀出空间. 所以如果合法,必然存在一种方案是每一次直接将一个人挪到 ...
- 【Unity3D】阴影原理及应用
1 阴影原理 光源照射到不透明物体上,会向该物体的后面投射阴影,如果阴影区域存在其他物体,这些物体不被光源照射的部分就需要渲染阴影.因此,我们可以将阴影的生成抽象出 2 个流程:物体投射阴影.物体 ...
- ORA-12514问题解决
版本:11.2.0.1.0 - 64bit 本机安装Oracle后链接测试发现以下情况: sqlplus scott/tiger 正常登陆 sqlplus scott/tiger@orcl 登陆失败 ...
- Jsp+Servlet实现文件上传下载(一)--文件上传
文件上传和下载功能是Java Web必备技能,很实用. 本文使用的是Apache下的著名的文件上传组件 org.apache.commons.fileupload 实现 下面结合最近看到的一些资料以及 ...