首页 > 数据库 >05 内存快照:宕机,Redis如何快速恢复?

05 内存快照:宕机,Redis如何快速恢复?

时间:2024-02-20 20:35:17浏览次数:35  
标签:快照 05 主线 宕机 Redis 内存 RDB 数据

内存快照:指内存中的数据在某一个时刻的状态以文件的形式写到磁盘上,类似于照片。

快照文件就称为 RDB 文件,其中,RDB 就是 Redis DataBase 的缩写。

两个关键问题

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

给哪些内存数据做快照?

Redis 的数据都在内存中,执行的是全量快照把内存中的所有数据都记录到磁盘中

RDB 文件的生成是否会阻塞主线程,关系到是否会降低 Redis 的性能。

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

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

快照时数据能修改吗?

对内存数据做快照时,数据若能被修改,则 Redis 还能正常处理写操作。否则,所有写操作都得等到快照完了才能执行,降低性能。

你可能会想到,用 bgsave 避免阻塞啊。这里我就要说到一个常见的误区了,避免阻塞正常处理写操作并不是一回事。此时,主线程的确没有阻塞,可以正常接收请求,但是,为了保证快照完整性,主线程只能处理读操作,因为不能修改正在执行快照的数据

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

写时复制机制保证快照期间数据可修改
  • 如果主线程对数据也都是读操作(键值对 A),主线程和 bgsave 子进程相互不影响。
  • 如果主线程要修改一块数据(键值对 C),这块数据就会被复制一份,生成该数据的副本(键值对 C’),主线程在这个数据副本上进行修改。同时,bgsave 子进程可以继续把原来的数据写入 RDB 文件

多久做一次快照?

bgsave 执行时不阻塞主线程,但如果频繁地执行全量快照,也会带来两方面的开销。

  1. 频繁将全量数据写入磁盘,会给磁盘带来很大压力。
  2. bgsave 子进程需要通过 fork 操作从主线程创建出来。子进程在创建后不会再阻塞主线程,但是,fork 这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。

增量快照:

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

增量快照示意图

Redis 4.0 中提出了一个混合使用 AOF 日志和内存快照的方法。

内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作

内存快照和AOF混合使用

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

关于 AOF 和 RDB 的选择问题,三点建议:

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

问:

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

内存资源和 CPU 资源两方面分析了风险:

内存不足的风险:Redis fork 一个 bgsave 子进程进行 RDB 写入,如果主线程再接收到写操作,就会采用写时复制。写时复制需要给写操作的数据分配新的内存空间。本在持久化过程中,为了保存 80% 写操作涉及的数据,写时复制机制会在实例内存中,为这些数据再分配新内存空间,分配的内存量相当于整个实例数据量的 80%,整个系统内存的使用量就接近饱和了。此时,如果实例还有大量的新 key 写入或 key 修改,云主机内存很快就会被吃光。

如果云主机开启了 Swap 机制,就会有一部分数据被换到磁盘上,当访问磁盘上的这部分数据时,性能会急剧下降。如果云主机没有开启 Swap,会直接触发 OOM,整个 Redis 实例会面临被系统 kill 掉的风险。

主线程和子进程竞争使用 CPU 的风险生成 RDB 的子进程需要 CPU 核运行,主线程本身也需要 CPU 核运行,而且,如果 Redis 还启用了后台线程,此时,主线程、子进程和后台线程都会竞争 CPU 资源。由于云主机只有 2 核 CPU,这就会影响到主线程处理请求的速度。

标签:快照,05,主线,宕机,Redis,内存,RDB,数据
From: https://www.cnblogs.com/itiancong/p/18023981

相关文章

  • 04 AOF日志:宕机,Redis如何避免数据丢失
    Redis的持久化主要有两大机制,即AOF(AppendOnlyFile)日志和RDB快照。Redis用于避免数据丢失的AOF方法数据库的写前日志(WriteAheadLog,WAL),在实际写数据前,先把修改的数据记到日志文件中,以便故障时进行恢复。AOF日志正好相反,是写后日志,Redis是先执行命令,把数据写入内......
  • CF1905D Cyclic MEX 题解
    题意:给定一个长度为\(n\)的排列\(a\),\(a_i\in[0,n-1]\)。你可以将这个排列进行循环移位,最小化\(\sum_{i=1}^{n}\text{mex}_{j=1}^ia_j\)的值。首先我们可以先计算出最初情况下每一个\(i\)位置的\(\text{mex}\)值。这个序列一定是单调非严格递增的。首先有一个比......
  • day05
    day05目录day05自定义指令指令介绍自定义指令自定义指令语法自定义指令—携指令的值需求语法自定义指令—v-loading指令的封装场景需求分析实现准备代码插槽—默认插槽作用需求问题插槽的基本语法代码示例插槽—后备内容(默认值)插槽的后备内容语法效果插槽—具名插槽需......
  • 代码随想录算法训练营第十八天 | 112. 路径总和,113. 路径总和ii ,106.从中序与后序遍
     513.找树左下角的值 已解答中等 相关标签相关企业 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层最左边 节点的值。假设二叉树中至少有一个节点。 示例1:输入:root=[2,1,3]输出:1示例2:输入:[1,2,3,4,null,5,6,n......
  • 读十堂极简人工智能课笔记05_无监督学习
    1. 自我改善1.1. 只有学会了如何学习和改变的人,才称得上是受过教育的人1.1.1. 卡尔·罗杰斯1.2. 人工智能如果只是学习纯理论的游戏(从国际象棋和围棋到电脑游戏),其结果已然可以令人惊叹1.3. 让大多数机器人玩叠叠乐游戏(用积木搭成塔,慢慢从塔中抽出积木,然后搭在最顶上),结果......
  • P2042 [NOI2005] 维护数列 题解
    题目链接:维护数列比较不好码的题,首先确保自己会一种文艺平衡树的书写,这点因人而异,比较推荐初学者学\(fhq\)平衡树,坑比较少,比较好码,写平衡树合并、持久化类的题时,也比较好写。注意到空间需求比较大,还涉及删除,我们的删除用各种树类数据结构中最常用的回收标记用于新的节点开辟。......
  • 20240205打卡
    在AndroidStudio中使用碎片(Fragments)加载界面,并实现滑动视图切换页面:1.**创建项目**:在AndroidStudio中创建一个新项目。2.**添加碎片**:在`res/layout`目录下创建您的碎片布局文件。您可以使用XML定义碎片的布局。例如,创建一个`fragment_one.xml`和`fragment_two.xml`......
  • P1059 [NOIP2006 普及组] 明明的随机数
    1.题目介绍[NOIP2006普及组]明明的随机数题目描述明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了\(N\)个\(1\)到\(1000\)之间的随机整数\((N\leq100)\),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学......
  • 爬虫_059_urllib post请求百度翻译
    目录分析百度翻译找接口编写代码需要注意的点修改代码返回数据解析最后的说明分析百度翻译找接口编写代码importurllib.requestimporturllib.parseheaders={'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)......
  • 爬虫_058_urllib get请求的urlencode方法
    目录urllib.parse.urlencode()quote方法使用的不是很经常的。因为quote的作用是将汉字转为百分号编码后的ASCII字符串。如果你的路径当中只有一个参数,你这样使用quote拼接一下url,这是没有问题的。如果你的路径当中有多个参数,并且参数都是中文的,你还使用quote,就TMD懵逼了。......