redis原理 3:未雨绸缪 —— 持久化

news2024/11/15 9:22:21

redis原理 3:未雨绸缪 —— 持久化

Redis 的数据全部在内存里,如果突然宕机,数据就会全部丢失,因此必须有一种机制来保证 Redis 的数据不会因为故障而丢失,这种机制就是 Redis 的持久化机制。

Redis 的持久化机制有两种,第一种是快照,第二种是 AOF 日志。快照是一次全量备份,AOF 日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而 AOF 日志记录的是内存数据修改的指令记录文本。AOF 日志在长期的运行过程中会变的无比庞大,数据库重启时需要加载 AOF 日志进行指令重放,这个时间就会无比漫长。所以需要定期进行 AOF 重写,给 AOF 日志进行瘦身。

img
img

快照原理

我们知道 Redis 是单线程程序,这个线程要同时负责多个客户端套接字的并发读写操作和内存数据结构的逻辑读写。

在服务线上请求的同时,Redis 还需要进行内存快照,内存快照要求 Redis 必须进行文件 IO 操作,可文件 IO 操作是不能使用多路复用 API。

这意味着单线程同时在服务线上的请求还要进行文件 IO 操作,文件 IO 操作会严重拖垮服务器请求的性能。还有个重要的问题是为了不阻塞线上的业务,就需要边持久化边响应客户端请求。持久化的同时,内存数据结构还在改变,比如一个大型的 hash 字典正在持久化,结果一个请求过来把它给删掉了,还没持久化完呢,这尼玛要怎么搞?

那该怎么办呢?

Redis 使用操作系统的多进程 COW(Copy On Write) 机制来实现快照持久化,这个机制很有意思,也很少人知道。多进程 COW 也是鉴定程序员知识广度的一个重要指标。

fork(多进程)

Redis 在持久化时会调用 glibc 的函数fork产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。子进程刚刚产生时,它和父进程共享内存里面的代码段和数据段。这时你可以将父子进程想像成一个连体婴儿,共享身体。这是 Linux 操作系统的机制,为了节约内存资源,所以尽可能让它们共享起来。在进程分离的一瞬间,内存的增长几乎没有明显变化。

img
img

用 Python 语言描述进程分离的逻辑如下。fork函数会在父子进程同时返回,在父进程里返回子进程的 pid,在子进程里返回零。如果操作系统内存资源不足,pid 就会是负数,表示fork失败。

py复制代码pid = os.fork()
if pid > 0:
    handle_client_requests()  # 父进程继续处理客户端请求
if pid == 0:
    handle_snapshot_write()  # 子进程处理快照写磁盘
if pid < 0:
    # fork error

子进程做数据持久化,它不会修改现有的内存数据结构,它只是对数据结构进行遍历读取,然后序列化写到磁盘中。但是父进程不一样,它必须持续服务客户端请求,然后对内存数据结构进行不间断的修改。

这个时候就会使用操作系统的 COW 机制来进行数据段页面的分离。数据段是由很多操作系统的页面组合而成,当父进程对其中一个页面的数据进行修改时,会将被共享的页面复制一份分离出来,然后对这个复制的页面进行修改。这时子进程相应的页面是没有变化的,还是进程产生时那一瞬间的数据。

img
img

随着父进程修改操作的持续进行,越来越多的共享页面被分离出来,内存就会持续增长。但是也不会超过原有数据内存的 2 倍大小。另外一个 Redis 实例里冷数据占的比例往往是比较高的,所以很少会出现所有的页面都会被分离,被分离的往往只有其中一部分页面。每个页面的大小只有 4K,一个 Redis 实例里面一般都会有成千上万的页面。

子进程因为数据没有变化,它能看到的内存里的数据在进程产生的一瞬间就凝固了,再也不会改变,这也是为什么 Redis 的持久化叫「快照」的原因。接下来子进程就可以非常安心的遍历数据了进行序列化写磁盘了。

AOF 原理

AOF 日志存储的是 Redis 服务器的顺序指令序列,AOF 日志只记录对内存进行修改的指令记录。

假设 AOF 日志记录了自 Redis 实例创建以来所有的修改性指令序列,那么就可以通过对一个空的 Redis 实例顺序执行所有的指令,也就是「重放」,来恢复 Redis 当前实例的内存数据结构的状态。

Redis 会在收到客户端修改指令后,进行参数校验进行逻辑处理后,如果没问题,就立即将该指令文本存储到 AOF 日志中,也就是先执行指令才将日志存盘。这点不同于leveldb、hbase等存储引擎,它们都是先存储日志再做逻辑处理。

Redis 在长期运行的过程中,AOF 的日志会越变越长。如果实例宕机重启,重放整个 AOF 日志会非常耗时,导致长时间 Redis 无法对外提供服务。所以需要对 AOF 日志瘦身。

AOF 重写

Redis 提供了 bgrewriteaof 指令用于对 AOF 日志进行瘦身。其原理就是开辟一个子进程对内存进行遍历转换成一系列 Redis 的操作指令,序列化到一个新的 AOF 日志文件中。序列化完毕后再将操作期间发生的增量 AOF 日志追加到这个新的 AOF 日志文件中,追加完毕后就立即替代旧的 AOF 日志文件了,瘦身工作就完成了。

fsync

AOF 日志是以文件的形式存在的,当程序对 AOF 日志文件进行写操作时,实际上是将内容写到了内核为文件描述符分配的一个内存缓存中,然后内核会异步将脏数据刷回到磁盘的。

这就意味着如果机器突然宕机,AOF 日志内容可能还没有来得及完全刷到磁盘中,这个时候就会出现日志丢失。那该怎么办?

Linux 的glibc提供了fsync(int fd)函数可以将指定文件的内容强制从内核缓存刷到磁盘。只要 Redis 进程实时调用 fsync 函数就可以保证 aof 日志不丢失。但是 fsync 是一个磁盘 IO 操作,它很慢!如果 Redis 执行一条指令就要 fsync 一次,那么 Redis 高性能的地位就不保了。

所以在生产环境的服务器中,Redis 通常是每隔 1s 左右执行一次 fsync 操作,周期 1s 是可以配置的。这是在数据安全性和性能之间做了一个折中,在保持高性能的同时,尽可能使得数据少丢失。

Redis 同样也提供了另外两种策略,一个是永不 fsync——让操作系统来决定何时同步磁盘,很不安全,另一个是来一个指令就 fsync 一次——非常慢。但是在生产环境基本不会使用,了解一下即可。

运维

快照是通过开启子进程的方式进行的,它是一个比较耗资源的操作。

  1. 遍历整个内存,大块写磁盘会加重系统负载
  2. AOF 的 fsync 是一个耗时的 IO 操作,它会降低 Redis 性能,同时也会增加系统 IO 负担

所以通常 Redis 的主节点是不会进行持久化操作,持久化操作主要在从节点进行。从节点是备份节点,没有来自客户端请求的压力,它的操作系统资源往往比较充沛。

但是如果出现网络分区,从节点长期连不上主节点,就会出现数据不一致的问题,特别是在网络分区出现的情况下又不小心主节点宕机了,那么数据就会丢失,所以在生产环境要做好实时监控工作,保证网络畅通或者能快速修复。另外还应该再增加一个从节点以降低网络分区的概率,只要有一个从节点数据同步正常,数据也就不会轻易丢失。

Redis 4.0 混合持久化

重启 Redis 时,我们很少使用 rdb 来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 rdb 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。

Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。

img
img

于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。

思考题

  1. 有人说 Redis 只适合用来做缓存,当数据库来用并不合适,你怎么看?
  2. 为什么 Redis 先执行指令再记录aof日志而不是像其它存储引擎一样反过来呢?

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/835661.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超越年龄限制:保持体能与积极心态的重要性(AI)

机器人和人工智能&#xff0c;没有年龄限制&#xff0c;并且越来越强&#xff0c;代表了最先进的生产力方向。 AI&#xff1a; 机器人和人工智能的发展代表了最先进生产力的方向&#xff0c;它们可以帮助人们更高效地完成各种任务&#xff0c;从而推动经济和社会的发展。机器人…

SpringDataJPA框架使用笔记

SpringDataJPA框架使用笔记 什么是JPA jpa概念 JPA是Java中用于实现对象关系映射ORM的API标准&#xff0c; JPA提供了一种将JAVA对象映射到关系数据库的方式&#xff0c; 使开发人员可以使用面向对象的方式操作数据库&#xff0c;而不需要编写繁琐的SQL语句。 jpa中的一些概…

牵手科瑞物业,合合信息智能文字识别技术助力企业沉淀数据资产

名片是商务场景中信息传递的重要载体。比起传统的纸质名片&#xff0c;可动态化呈现个人及企业信息&#xff0c;洞察访客偏好的数字名片已成为企业对外展示、拓展客户的重要工具。近期&#xff0c;合合信息旗下名片全能王与科瑞物业达成合作。通过推动企业数字名片在科瑞物业各…

【若依管理系统】开发功能流程总结

1.在菜单管理中&#xff0c;新增需要创建的菜单&#xff0c;如图 并添加查询、新增、修改、删除等按钮和对应的权限和路径 例如如果没有添加查询按钮&#xff0c;那么在修改的时候&#xff0c;会存在报错&#xff1a;没有权限。上图对应后台代码 2.domain中创建设计的表结构及操…

优化全域广告投放效果的方法与技巧

好久不见&#xff01;不少读者催更的《企业广告投放逻辑精讲》系列继续更新啦&#xff01;感谢各位忠实读者的支持&#xff01; 经过前两章的学习&#xff0c;想必你已经了解了广告投放的正确方式&#xff0c;但事实上&#xff0c;掌握方法只是基础&#xff0c;相当于你要学习…

【计算机视觉】干货分享:Segmentation model PyTorch(快速搭建图像分割网络)

一、前言 如何快速搭建图像分割网络&#xff1f; 要手写把backbone &#xff0c;手写decoder 吗&#xff1f; 介绍一个分割神器&#xff0c;分分钟搭建一个分割网络。 仓库的地址&#xff1a; https://github.com/qubvel/segmentation_models.pytorch该库的主要特点是&#…

Python web实战之Django用户认证详解

关键词&#xff1a; Python Web 开发、Django、用户认证、实战案例 概要 今天来探讨一下 Django 的用户认证吧&#xff01;在这篇文章中&#xff0c;我将为大家带来一些有关 Django 用户认证的最佳实践。 1. Django 用户认证 在开发 Web 应用程序时&#xff0c;用户认证是一个…

Android系统APP之SettingsProvider

前言 SettingsProvider顾名思义是一个提供设置数据共享的Provider&#xff0c;SettingsProvider和Android系统其它Provider有很多不一样的地方&#xff0c;如&#xff1a; SettingsProvider只接受int、float、string等基本类型的数据&#xff1b;SettingsProvider由Android系…

喜讯!箱讯AnyCase荣获“2023年度苏州市服务型制造示范平台”

近日&#xff0c;苏州市工业和信息化局公示了“2023年度苏州市服务型制造示范企业&#xff08;平台&#xff09;”名单。箱讯科技&#xff08;上海&#xff09;有限公司子公司苏州箱讯供应链管理有限公司荣耀上榜。 ​ 添加图片注释&#xff0c;不超过 140 字&#xff08;可选…

IFC纹理及着色器研究

最近&#xff0c;yorgunkirmizi 讨论了纹理、着色器、纹理坐标以及所有此类内容在 IFC 中的工作原理。 我们在破译什么是可能的、什么是不可能的方面已经取得了一些重大进展&#xff0c;所以我想我应该打开这个线程&#xff0c;以便其他人也可以参与其中&#xff0c;或者至少密…

恒运资本:货币调控精准有力 8月流动性合理充裕

8月3日&#xff0c;中国人民银行以利率投标方式展开30亿元逆回购操作&#xff0c;由于当日有1140亿元逆回购到期&#xff0c;公开商场完成净回笼1110亿元。 专家表示&#xff0c;为坚持流动性合理富余&#xff0c;估计央即将根据流动性供求和商场利率改变&#xff0c;灵敏运用多…

【雕爷学编程】MicroPython动手做(39)——机器视觉之图像基础

MixPY——让爱(AI)触手可及 MixPY布局 主控芯片&#xff1a;K210&#xff08;64位双核带硬件FPU和卷积加速器的 RISC-V CPU&#xff09; 显示屏&#xff1a;LCD_2.8寸 320*240分辨率&#xff0c;支持电阻触摸 摄像头&#xff1a;OV2640&#xff0c;200W像素 扬声器&#…

阿里云平台WoSignSSL证书应用案例

沃通CA与阿里云达成合作并在阿里云平台上线WoSign品牌SSL证书。自上线以来&#xff0c;WoSignSSL证书成为阿里云“数字证书管理服务”热销证书产品&#xff0c;获得阿里云平台客户认可&#xff0c;助力阿里云平台政府、金融、教育、供应链、游戏等各类行业客户实现网站系统数据…

美团前端研发框架Rome实践和演进趋势

本文整理自美团技术沙龙第76期《大前端研发协同效能提升与实践》&#xff0c;为大家介绍了美团到店前端研发框架Rome实践和演进趋势。 具体来讲&#xff0c;本文首先介绍了Rome整体的工程生态、演变路径、规模化升级以及工程框架外的开发辅助工具&#xff1b;第二部分&#xff…

主流CRM有哪些特点和优势?

现如今&#xff0c;CRM系统是企业实现数字化转型&#xff0c;提高销售收入的首选工具。但市场上有众多CRM品牌&#xff0c;每家都有自己的特点和优势&#xff0c;企业该如何进行选择&#xff1f;下面我们就来进行主流CRM系统比较&#xff0c;并说说什么CRM产品比较好? 主流CR…

控制器(IP盒子类似网关)收不到工位板的状态数据包的问题排查解决

控制器(IP盒子类似网关)收不到工位板的状态数据包 问题描述 如下图通信框图所示&#xff0c;控制器工位板程序通过RS422和控制器(类似网关)通信&#xff0c;控制器在将数据转发给Linux应用程序。 一开始设备装好&#xff0c;整个通信是没有任何问题的。 然后在很久之后&…

【C#学习笔记】装箱和拆箱

文章目录 装箱和拆箱性能消耗装箱拆箱 比较var&#xff0c;object&#xff0c;dynamic&#xff0c;\<T\>varobject\<T\> 泛型dynamic 装箱和拆箱 在讲引用类型object的时候&#xff0c;我们说它是万能的&#xff0c;却没说它万能在哪里。 除了object为每一种变量…

收集 301 医院 451 名老年冠心病患者数据,湖北麻城人民医院推出机器学习模型,准确预测患者一年内死亡率

内容一览&#xff1a;据国际糖尿病联盟 (IDF) 统计&#xff0c;2021 年中国糖尿病患者数量占全球 26%。而糖尿病患者血糖长期失控&#xff0c;有极高风险引起冠心病等并发症。近期&#xff0c;湖北省麻城市人民医院研究人员分析比较了多种模型&#xff0c;并用其中表现最优的机…

Scratch 之 两点之间距离的测算

1.前言 在Scratch中&#xff0c;对于坐标系上的两点&#xff0c;我们可以确定通过x坐标或y坐标之差确定两点横坐标或是纵坐标上的距离&#xff0c;那么如何知道两点之间的直线距离呢&#xff1f; 2.勾股定理 对于一个直角三角形&#xff0c;两条直角边的平方和等于斜边的平方&a…

电动自行车上架eBay的UL2849、16CFR1512测试标准

在奥运经济的带动下&#xff0c;今年以来运动自行车消费有较大幅度增长&#xff0c;其中高端消费者对进口自行车需求扩张&#xff0c;上半年竞赛型自行车进口量同比增长49.5%。另外&#xff0c;电助力自行车在国际市场也倍受追捧&#xff0c;国际自行车贸易总额的60%来自中国&a…