Redis 核心原理串讲(中),架构演进之高可用

news2024/12/27 12:46:40

文章目录

  • Redis 核心原理总览(全局篇)
  • 前言
  • 一、持久化
    • 1、RDB
    • 2、AOF
    • 3、AOF 重写
    • 4、混合持久化
    • 5、对比
  • 二、副本
    • 1、同步模式
    • 2、部分重同步
  • 三、哨兵
    • 1、核心能力
    • 2、节点通信
  • 总结


Redis 核心原理总览(全局篇)

正文开始之前,我们先思考下「如何造一个缓存组件?」

该片段是 Redis 原理知识地图,请仔细阅读!(基于 redis6.2

1)最小可用版:

  • 要快:缓存最核心的目的是支持快速访问,硬件层面一般选择「内存」
  • 远程访问:作为缓存组件,要支持单独部署,可以利用现有开源网络库,也可以自己实现。

大部分语言都提供了内存操作,条件 1 很容易满足,条件 2 要支持远程访问,就要和 TCP 连接打交道,我们可以利用开源的网络库,比如 C 版的 libc 等。

原理篇第一部分:将围绕一条请求探索 redis 高性能的核心原理。

2)进阶版:

第一步我们已经有了缓存组件最基本的雏形,并且已经达到了高性能的处理能力,这个时候我们可能有更多的诉求:

  • 稳定:即 尽可能不丢数据、无故障或故障后快速恢复、自动处理故障的能力
  • 可扩展:单机容量或者 QPS 达到上限,支持水平扩展能力。

原理篇第二部分:将围绕 redis 架构演进进行剖析。

全局知识地图:

在这里插入图片描述

前言

本文围绕「架构主线」来透视 Redis「高可靠」的核心原理,在正文开始之前,我们先思考几个问题:

  • Redis 数据丢失风险?
  • 持久化机制会拖慢 Redis 吗?
  • fork 子进程是否会阻塞主线程?不用 fork 操作行不行?
  • 有了持久化还需要副本机制?
  • 能不能自己写个 HA 来代替 Redis 哨兵?

如果你对以上问题了然于胸,这篇文章读起来很容易,权当帮你串联、回顾知识点,如果不是很清楚也没关系,且听我细细道来!


一、持久化

持久化是什么?就 redis 而言,本质就是将内存中不稳定的数据,通过一些刷盘策略写入磁盘,从而达到断电等故障能恢复数据的效果。

如果让你来实现持久化,你会如何考虑?

首先,我们可以「定期全量备份」的方案,5分钟、10分钟一个备份周期,这种方式的好处是,处理起来足够简单,但由于是全量备份,每次消耗不小,因此需要「一定间隔」周期,但丢失数据风险就大了。

我们还可以考虑像 MySQL 的 binlog 方式,记录「明细」,故障时直接进行重放即可,这种方式的好处是数据丢失范围进一步减小,但故障恢复时需要更多的时间,而且数据文件占用空间也更大。

能不能结合两种优点?也是可以的,这就是「混合模式」

1、RDB

RDB 全称 redis database,是以时间为轴线的全量内存快照,存在磁盘上。快照,就是那个时间点内存数据库的全景图,就像拍照一样,把那个瞬间的所有状态“咔”的一声记录下来。

我们来看看 RDB 生成过程:

在这里插入图片描述

redis 提供了两种方式,一种是 save,另一种是 bgsave。两者底层处理原理都一样,最大的区别点在于:

  • SAVE 由主线程执行,会阻塞客户端命令
  • BGSAVE 由 fork 的子进程处理,不会阻塞执行。

redis 提供了一些契机,达到这些条件就可以触发执行 RDB 快照生成,可以在 redis.config 中配置:

save 900 1
save 300 10
save 60 10000

只要满足以下三个条件中的任意一个,BGSAVE 命令就会被执行:

  • 服务器在900秒之内,对数据库进行了至少1次修改。
  • 服务器在300秒之内,对数据库进行了至少10次修改。
  • 服务器在60秒之内,对数据库进行了至少10000次修改。

:save 操作由主线程阻塞执行,而 bgsave 则由子进程来完成(不过复制内存页表项的时候仍然会阻塞主线程)。

2、AOF

全称 Append Only File,像记录日志一样,记录命令明细。

我们来看看 AOF 写入文件的过程:

在这里插入图片描述

首先:

  • 写入:指通过 write 系统调用,将数据从 aof_buf 写入 内核缓冲区。

  • 落盘(同步):指的是将数据从内核缓冲区同步至磁盘中。因为,由于操作系统自身的优化策略,我们通过 write 写入的数据,都是直接进入内核缓冲区,然后会根据内核将数据同步至磁盘。

aof_buf 缓冲区:

redis 服务端提供的缓冲区,请求命令会写入 aof_buf 缓冲区,然后由 aof_buf 缓冲区写入内核缓冲区或者同步至磁盘。

落盘时机:

在主事件循环,通过 beforeSleep 方法触发 flushAppendOnlyFile 调用,这便是入口。那,一条命令,经过哪些过程最终追加到 AOF 文件呢?

  • redis 接收请求命令 cmd,并执行。
  • cmd 执行成功后,通过 feedAppendOnlyFile 方法将命令写入 aof_buf 缓冲区。
  • 下一轮主循环中,通过 flushAppendOnlyFile 尝试写入或者同步。

3 种刷盘策略:

  • no:即 redis 不做任何操作,由内核自行刷盘,Linux 默认 30s 刷一次,效率最高,安全性最低
  • everysec:redis 控制,每秒刷盘一次
  • always:每一轮命令执行完之后,立即刷盘,安全性最高,效率最低

:刷盘策略是指将「内核缓冲区」的数据,通过 fsync 系统调用写入磁盘

3、AOF 重写

上文提到,AOF 实实在在的记录了每一条命令,尤其是出现大量重复 key 的操作,会使得 AOF 看起来冗余且臃肿。

AOF 重写就相当于对 AOF 文件进行压缩,同一个 key 只保留最新的操作记录。

我们来看看 AOF 重写执行过程:

在这里插入图片描述

1)触发重写条件(自动 or 手动)
2)redis 调用 aof.c#rewriteAppendOnlyFileBackground 方法,并 fork 子进程进行处理

  • 2a)子进程重写 AOF 到临时文件
  • 2b)父进程继续接收新命令并累加到 server.aof_rewrite_buf 缓冲区

3)直到 2a 完成后
4)父进程尝试将 server.aof_rewrite_buf 数据写入临时文件,并用临时文件替换原 AOF 文件。

重写时机?

redis 提供了灵活的重写机制,可以自动触发,也可以手动触发。

首先,需要确定是否开启了 AOF 策略,即:

appendonly yes

你可以在命令行输入 BGREWRITEAOF 手动触发重写:

127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started

另外,redis 也提供了自动触发重写条件:

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

每次重写之后都会记录文件大小,作为下一次重写的触发条件:当前文件大小超过上次重写的百分比后,触发重写操作。

同时,为避免 AOF 文件过小而触发重写操作,提供了 auto-aof-rewrite-min-size 参数控制重写条件的下限。

:AOF 重写并不需要从原 AOF 文件中进行压缩,而是直接扫描整个库,把每一个 key / value 转变成写命令,然后追加至临时文件,待重写操作完成后,将临时文件原子性重命名即可。

4、混合持久化

前面我们提到,RDB 记录快照,数据文件相对小,但丢失数据风险较大,AOF 记录明细,数据丢失风险小,但数据文件相对较大。

两者都不完美,能不能只取它们的优点?确实有,这就是「混合持久化」。

redis 4.0 推出了 RDB-AOF 这种混合模式,可以通过下面配置开启:

appendonly yes
aof-use-rdb-preamble yes

可以看到,使用混合模式的前提是,需要先开启 AOF,而 aof-use-rdb-preamble 参数则控制是否使用混合模式。

使用这种模式,当数据重写后,AOF 文件前半部分是 RDB 数据(采用 RDB 数据格式),AOF 文件后半部分继续追加 AOF 数据(AOF 数据格式)。

当采用 RDB-AOF 混合模式时,数据直接从 AOF 文件加载,由于 AOF 文件存储了 RDB 和 AOF 数据,也就达到了 全量加载RDB数据 和 增量加载AOF数据 的策略。

数据写入过程?

前面我们提到混合模式的数据也是直接存到 AOF 文件,前半部分存 RDB 数据、后半部分存 AOF 数据。

相信你也猜到了,整体数据写入过程与 AOF 模式类似,我们来看看:

在这里插入图片描述

文件追加写的部分没有变化,那变化在哪里?AOF 文件重写

你想想,我们的最终目的是「压缩文件」,采用现成的 RDB 方式就可以完成,因此,我们可以考虑直接在重写 AOF 文件时,直接存储 RDB 格式的数据:

在这里插入图片描述

  • fork 子进程直接按照 RDB 格式将快照数据写入 AOF 文件
  • aof_rewrite_buf 缓冲区数据仍然以 AOF 数据格式写入 AOF 文件

整体来看,混合模式的数据写入和 AOF 模式基本一致!!!

5、对比

截止目前 Redis 提供了 AOF、RDB 以及两者混合模式的持久化方式,主要特点如下:

在这里插入图片描述

二、副本

持久化机制保障了数据不丢失,但还无法做到故障秒级切换,那怎么办?副本机制,也就是我们常见的主从结构。

1、同步模式

redis 的复制功能可以分为数据同步命令传播两部分。

  • 数据同步:将从节点保持与主节点一致,一般有完全重同步和部分重同步两种模式。
  • 命令传播:当主从节点状态一致后,后续新的命令通过 TCP 长连接发送至从节点。

当然,我们也可以通过以下三种具体的数据传输形式来区分:

  • 完全重同步,一般是启动时或者主从断开连接过长时间
  • 部分重同步,一般是主从短时间断连
  • 命令传播,也就是命令实时同步

在这里插入图片描述

2、部分重同步

这种模式主要考虑 主从数据同步期间要尽可能的减少数据传输,你想想,主从同步是通过网络进行传输,网络具有不稳定性,如果中断了一小会,难道就要全量重新发一次吗?当然不用

如何实现?环形缓冲区

顾名思义,一块指定大小的缓冲区,可重复循环使用(即,写满了又可以从头开始写,当然就有覆盖较早数据的问题)

在这里插入图片描述

从节点会记录已经从主服务器接收到的数据量(复制偏移量),而主节点会维护一个「复制缓冲区」,记录自己已执行且待发送给从节点的命令请求,同时还需要记录复制缓冲区第一个字节的复制偏移量。

从节点请求时带上自己的复制偏移量,主节点接收后对比复制偏移量刻度是否还在,如果还在说明环形缓冲区还没有被覆盖,直接将这边增量数据发送给从节点。

如果复制偏移量不存在,说明已经被覆盖了,就需要完整将整个 RDB 数据文件全量发给从节点。

三、哨兵

有了副本就能实现秒级故障恢复?还不够,这个时候还需要你手动进行切换

能不能做成自动故障切换?能,这就是哨兵,其本质就是一个监控程序

用一个哨兵似乎就能完成?能,但不够准,网络的复杂性,经常出故障是可能的,所以,我们最好搞多个哨兵

我画了张图,大概是这样:

在这里插入图片描述

1、核心能力

首先,哨兵的主要职责是保障 redis 服务能正常对外提供服务。因此,肯定是要监听 redis 主节点的在线状态。

其次,当主节点挂掉之后,需要进行故障转移,也就是需要知道所有从节点的信息。因此,哨兵的第二项职责便是监听从节点的状态。

另外,前面部分提到,单哨兵可能并不是那么健壮,我们一般需要搞一个哨兵集群。因此,第三项职责便是哨兵节点间的沟通交流。

当然,监听节点的目的是为了获取信息,对这些信息进一步处理并采取相应的行动才是目的:

  • 哨兵集群信息沟通交流
  • master 节点下线判断
  • 哨兵集群 leader 选举
  • 哨兵 leader 执行故障转移
  • 通知客户端,master - slave 变更信息

2、节点通信

哨兵,本质也是一个 redis 服务,既能接收请求又能定期监视相关节点,这是如何做到的?

我们知道,事件是贯穿 redis 的核心机制,客户端发来的请求封装为文件事件,另外还有一些后台周期性的任务封装为时间事件

哨兵的工作过程号称是异步的,比如发出 PING 之后不需要等待响应,而是当响应到来时,通过回调函数来继续处理。哨兵的异步操作是如何实现的?

哨兵在启动时会创建相关连接,并将对应已连接的 fd 向操作系统内核注册,当有请求到来时,和一般的 redis 请求类似,服务正常处理请求即可。

在哨兵主动发起通信时,主要借助于客户端工具 hiredis,其封装了 RESP 通信协议,发送请求时,这个过程不必等待结果返回,因此,异步体现在这里。

我画了张图,大概是这样:

值得注意的是,redis 哨兵的异步过程是与主线程轮训(事件)紧密相连。


总结

本文主要围绕 redis 高可用 进行贯穿讲述,核心问题是要解决 如何确保 redis 无故障或秒级恢复?,我们循序渐进的讲述了三大部分内容:

  • 持久化:RDB 、AOF 持久化机制
  • 副本机制:一主一丛、一主多从 …
  • 哨兵机制:监视、故障转移、通知

把这三部分内容串起来就是这个问题的答案。

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

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

相关文章

【FPGA】Verilog:基本实验步骤演示 | 功能电路创建 | 添加仿真激励 | 观察记录仿真波形

前言: 本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载的完整过程、Verilog语言基本运用,电路设计和Test Bench程序的编写、以及实验开发板的使用,通过观察和数据记录理解仿真和FGPA实现的差异。 目录 Ⅰ. 基础知…

考研政治 马原 易混淆知识点

马哲 1. 哲学基本问题 从何者为第一性,分为唯物主义和唯心主义 从是否具有同一性,分为可知论(有同一性)和不可知论(无同一性) 辩证法:联系,发展的观点看世界,认为发展的…

python对接API二次开发高级实战案例解析:百度地图Web服务API封装函数(行政区划区域检索、地理编码、国内天气查询、IP定位、坐标转换)

文章目录前言一、IP定位1.请求URL2.获取IP定位封装函数3.输出结果二、国内天气查询1.请求url2.天气查询封装函数3.输出结果三、行政区划区域检索1.请求url2.区域检索封装函数3.输出结果四、地理编码1.请求url2.地理编码封装函数3.输出结果五、坐标转换1.请求url2.坐标转换封装函…

一文细说Linux虚拟文件系统原理

在 Unix 的世界里,有句很经典的话:一切对象皆是文件。这句话的意思是说,可以将 Unix 操作系统中所有的对象都当成文件,然后使用操作文件的接口来操作它们。Linux 作为一个类 Unix 操作系统,也努力实现这个目标。 虚拟…

CSS 这个就叫优雅 | 多行文本溢出省略

CSS 这个就叫优雅 | 多行文本溢出省略 文章目录CSS 这个就叫优雅 | 多行文本溢出省略一、文本溢出省略方式二、WebKit内核浏览器解决方法🥙三、通用解决方法四、CSS 预处理器封装🥩五、参考资料💘六、推荐博文🍗一、文本溢出省略方…

小样本学习(Few-Shot Learning)训练参数意义

一、常规参数 1.1 epoch 是指所有的训练数据都要跑一遍。假设有6400个样本,在训练过程中,这6400个样本都跑完了才算一个epoch。一般实验需要训练很多个epoch,直到LOSS稳定后才停止。 1.2 batch_size 中文名称是批大小,之前的640…

【数据结构趣味多】二叉树概念及性质

1.树的定义 定义:树(Tree)是n(n>0)个结点的有限集。n0时称为空树。在任意一棵非空树种; 有且仅有一个根结点(root)。当n>1时,其余结点可分为m(m>0&a…

H13-531云计算HCIE V2.0——400~600常错题和知识点总结

400~600 422、在 FusionCloud 6.x 中,以下关于备份的说法哪项是错误的? A.备份协议支持本地,通过 FTP/SFTP 到第三方服务器及 OBS B. 为了保证系统稳定运行,对管理数据进行备份恢复可以确保在异常时对业务的影响降到…

没有完美的项目,也轮不到你,找到适合自己的,先干起来再说

首先明确一点,没有百分百完美的项目,即使有,也轮不到你。不要认为你必须先找到一个完美的项目,然后再去工作。这个想法最后的结局就是项目一直在找,观望,迟迟不行动,不赚钱。如果你真的想找个项…

C++ 语法基础课 习题7 —— 类、结构体、指针、引用

文章目录例题1. 21.斐波那契数列2. 16.替换空格3. 84.123...n4. 28.O(1)时间删除链表结点5. 36.合并两个排序的链表例题 1. 21.斐波那契数列 Acwing 21.斐波那契数列 class Solution { public:int Fibonacci(int n) {if(n < 1) return n;return Fibonacci(n - 1) Fibon…

并发编程 - ThreadLocal

前言 ThreadLocal 用于解决多线程对于共享变量的访问带来的安全性问题。ThreadLocal 存储线程局部变量。每个线程内置 ThreadLocalMap&#xff0c;ThreadLocalMap 的 key 存储 ThreadLocal 实例&#xff0c;value 存储自定义的值。与同步机制相比&#xff0c;它是一种“空间换…

vue性能优化之预渲染prerender-spa-plugin+vue-meta-info解决seo问题

单页面应用中&#xff0c;web项目只有一个页面&#xff0c;前端根据路由不同进行组件之间的对应切换&#xff0c;动态的渲染页面内容。这就是客户端渲染&#xff0c;具有减少服务器端压力、响应速度快等优点。但是单页应用在优化用户体验的同时&#xff0c;也给我们带来了一些对…

阅读 | 001《人工智能导论》(三)知识应用篇1

文章目录知识应用第9章、专家系统9.1 专家系统概述9.2 推理方法9.3 一个简单的专家系统9.4 非确定性推理9.5 专家系统工具9.6 专家系统的应用9.7 专家系统的局限性9.8 本章小结第10章、计算机视觉10.1 计算机视觉概述10.2 数字图像的类型及机内表示10.3 常用计算机视觉模型和关…

计算机重装系统方法教程

​计算机在使用的过程中出现各种问题也是在所难免的&#xff0c;当计算机出现了一些系统故障问题没有办法解决时&#xff0c;或是计算机使用长了以后运行就会变得越来越慢时&#xff0c;这时大家可以考虑通过电脑重装系统来解决&#xff0c;那么&#xff0c;计算机如何重装系统…

ArcGIS基础实验操作100例--实验71多图层叠加查询

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验71 多图层叠加查询 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&am…

MATLAB——PCM编译码实验

目录MATLAB——PCM编译码一、实验原理1.掌握PCM编码原理和译码原理2. 练习使用Matlab编程实现PCM编码和译码3. 了解失真度的概念&#xff0c;能对译码结果进行失真度分析二、实验原理三、实验要求1、用Matlab产生一模拟信号&#xff0c;如&#xff1a; 或者自己编写一信号&…

“微综艺+虚拟场景”,蓝海创意云利用元宇宙技术撬动流量杠杆

1月1日&#xff0c;抖音微综艺节目“友问必答”2023新年直播盛大开幕&#xff0c;蓝海创意云利用vLive虚拟直播系统为此档节目搭建了专属的“元宇宙问答直播间”&#xff0c;整场直播观看人次突破 30W 人次&#xff0c;最高同时在线人数达 3W 人次&#xff0c;独特的直播形式和…

基于Spring+Mybatis框架的人事管理系统源码+数据库,含视频部署教程

人事管理系统 下载地址&#xff1a;基于SpringMybatis框架的人事管理系统源码数据库 部署说明&#xff1a; 项目启动后&#xff0c;在浏览器中访问地址&#xff1a;http://127.0.0.1:8080/personnel/ 由于很多同学反映部署有问题&#xff0c;所以我录了一个视频来演示一下&…

【Python爬虫项目实战】Python爬虫采集某外包平台数据保存本地

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、开发工具二、环境搭建三、数据来源查询分析四、代码实现1. 发送请求2.数据获取3.解析数据4. 保存数据总结前言 今天给大家介绍的是Python爬虫某外包平台数据…

架构设计---搜索引擎的原理

前言&#xff1a; 搜索引擎的倒排索引&#xff0c;数据的搜索与查找技术是计算机软件的核心算法&#xff0c;这方面已有非常多的技术和实践经验。而对于搜索引擎来说&#xff0c;要面对海量的文档进行快速的内容检索、查询的话&#xff0c;最主要的技术是倒排索引技术。 像百…