Redis:浅谈Redis集群的复制原理

server/2024/11/9 16:34:00/

Redis_0">一、Redis集群方案

主从复制集群:手动切换的主从复制集群、带有哨兵的HA的主从复制集群
分片集群:客户端实现路由索引的分片集群、使用中间件代理层的分片集群Redis自身实现的Cluster分片集群

Redis_3">二、Redis主从复制的原理

1、主从复制机制

当一个master实例和一个slave实例连接正常时, master 会发送一连串的命令流来保持对slave的更新,以便于将自身数据集的改变复制给 slave , 包括客户端的写入、key的过期或被逐出等等。

当master和slave之间的连接断开之后,因为网络问题、或者是主从意识到连接超时, slave重新连接上master会尝试进行部分同步,这意味着它会尝试只获取在断开连接期间内丢失的命令流。

当无法进行部分重同步时, slave会请求进行全量重同步。这会涉及到一个更复杂的过程,例如master需要创建所有数据的快照,将之发送给 slave ,之后在数据集更改时持续发送命令流到slave。

2、主从复制的关注点

Redis使用异步复制:slave和master之间异步地确认处理的数据量。

一个master可以拥有多个slave,slave可以接受其他slave的连接。除了多个slave可以连接到同一个master之外,slave之间也可以像层叠状的结构(cascading-likestructure)连接到其他slave。自Redis4.0起,所有的sub-slave将会从master收到完全一样的复制流。

Redis复制在master侧是非阻塞的。这意味着master在一个或多个slave进行初次同步或者是部分重同步时,可以继续处理查询请求。

Redis复制在slave侧大部分也是非阻塞的。当slave进行初次同步时,它可以使用旧数据集处理查询请求,假设你在redis.conf中配置了让Redis这样做的话。在初次同步之后,旧数据集必须被删除,同时加载新的数据集。此外,你也可以配置如果复制流断开,Redis的slave会返回一个error给客户端。slave在这个短暂的时间窗口内(如果数据集很大,会持续较长时间),会阻塞到来的连接请求。自Redis4.0开始,可以配置Redis使删除旧数据集的操作在另一个不同的线程中进行,但是,加载新数据集的操作依然需要在主线程中进行并且会阻塞slave。

三、主从复制的具体过程

每一个Redis的master都有一个replicationID,这是一个较大的伪随机字符串,标记了一个给定的数据集。每个master也持有一个偏移量offset,master将自己产生的复制流发送给slave时,发送多少个字节的数据,自身的偏移量就会增加多少,目的是当有新的操作修改自己的数据集时,它可以以此更新slave的状态。偏移量offset即使在没有一个slave连接到master时,也会自增,所以基本上每一对给定的ReplicationID,offset都会标识一个master数据集的确切版本。

当slave连接到master时,它们使用PSYNC命令来发送它们记录的旧的master节点的replicationID和它们至今为止处理的偏移量。通过这种方式,master能够仅发送slave所需的增量部分。但是如果master的缓冲区中没有足够的命令积压缓冲记录,或者如果slave引用了不再知道的历史记录(replicationID),则会转而进行一个全量重同步:在这种情况下,slave会得到一个完整的数据集副本,从头开始。

下面是一个全量同步的工作细节:
master开启一个后台保存进程,以便于生产一个RDB文件。同时它开始缓冲所有从客户端接收到的新的写入命令。当后台保存完成时,master将数据集文件传输给slave,slave将之保存在磁盘上,然后加载文件到内存。再然后master会发送所有缓冲的命令发给slave。这个过程以指令流的形式完成并且和Redis协议本身的格式相同。

你可以用telnet自己进行尝试。在服务器正在做一些工作的同时连接到Redis端口并发出SYNC命令。你将会看到一个批量传输,并且之后每一个master接收到的命令都将在telnet回话中被重新发出。事实上SYNC是一个旧协议,在新的Redis实例中已经不再被使用,但是其仍然向后兼容:但它不允许部分重同步,所以现在PSYNC被用来替代SYNC。

之前说过,当主从之间的连接因为一些原因崩溃之后,slave能够自动重连。如果master收到了多个slave要求同步的请求,它会执行一个单独的后台保存,以便于为多个slave服务。

补充-无需磁盘参与的复制:正常情况下,一个全量重同步要求在磁盘上创建一个RDB文件,然后将它从磁盘加载进内存,然后slave以此进行数据同步。如果磁盘性能很低的话,这对master是一个压力很大的操作。Redis2.8.18是第一个支持无磁盘复制的版本。在此设置中,子进程直接发送RDB文件给slave,无需使用磁盘作为中间储存介质。


http://www.ppmy.cn/server/110548.html

相关文章

量化面试:什么是蒙特卡罗模拟?

蒙特卡罗模拟(Monte Carlo Simulation)是一种利用随机抽样来解决复杂问题的统计学方法,通常用于评估不确定性对系统和过程的影响。在投资和量化交易中,蒙特卡罗模拟被广泛用于风险分析、资产定价、投资组合优化和预测等多个领域。…

强化学习实操入门随笔

碎碎念:经过思考,打通底层逻辑,我认为未来ai的功能是在沟通领域代替人,未来人-人模式(媒介是死的语言,比如看古人留下的文字、聊天的暂时不在)会变成人-ai替身-人模式(符合本人想法的…

龙芯+FreeRTOS+LVGL实战笔记(新)——00关于本专栏

本专栏是笔者另一个专栏《龙芯RT-ThreadLVGL实战笔记》的姊妹篇,主要的区别在于实时操作系统的不同,章节的安排和任务的推进保持一致,并对源码做了改进和优化,各位可以先到本人主页下去浏览另一专栏的博客列表(目前已撰…

【whisper】使用whisper实现语音转文字

whisper需要ffmpeg支持 官网下载ffmpeg https://www.gyan.dev/ffmpeg/builds/下载完毕后解压放到合适的位置 添加环境变量 在cmd中输入以下 ffmpeg -version出现下面结果代表成功 安装whisper pip install openai-whisper在vscode中运行 测试代码 import whisperif __n…

【C++ Primer Plus习题】8.7

问题: 解答: #include <iostream>using namespace std;template <typename T> T SumArray(T arr[], int n) {T sum arr[0] - arr[0];for (int i 0; i < n; i){sum arr[i];}return sum; }template <typename T> T SumArray(T *arr[], int n) {T sum *…

QIIME2宏基因组学教程--2024年春季莱顿和苏黎世教程

最近在qiime2论坛发现有人发布了qiime2宏基因组的教程&#xff0c;这里分享一下&#xff0c;只是alpha版本&#xff0c;不成熟&#xff0c;大家谨慎了解。qiime2的专用格式对于折腾宏基因组还是有点不妥的&#xff0c;个人观点&#xff0c;但是好在他能让分析标准化&#xff0c…

通义说【线性代数】线性组合

在数学中&#xff0c;线性组合&#xff08;linear combination&#xff09;是指从一组向量出发&#xff0c;通过这组向量与一组标量相乘并将结果向量相加所得到的新向量。简单来说&#xff0c;线性组合就是将向量按一定的权重&#xff08;标量&#xff09;相加。 假设我们有一…

RK3568 Android 11 蓝牙BluetoothA2dpSink 获取用于生成频谱的PCM

Android 中的 A2DP Sink A2DP Sink 在 Android 系统中主要用于 接收 其他蓝牙设备&#xff08;如手机、平板、电脑等&#xff09;发送过来的 高质量的立体声音频。简单来说&#xff0c;它让你的 Android 设备可以充当一个 蓝牙音箱 或 耳机 的角色。 核心功能&#xff1a; 接…