超详细Redis入门教程——Redis 主从集群(上)

news2024/10/5 12:44:46

前言

在这里插入图片描述

本文小新为大家带来 Redis 主从集群 相关知识,具体内容包括主从集群搭建(包括:伪集群搭建与配置分级管理容灾冷处理),主从集群搭建(包括:主从复制原理数据同步演变过程)等进行详尽介绍~

不积跬步,无以至千里;不积小流,无以成江海。每天进步一点点,在成为强者的路上,小新与大家共同成长!

📌博主主页:小新要变强 的主页
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
👉Java微服务开源项目可参考:企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)

↩️本文上接:超详细Redis入门教程——Redis 持久化


目录

文章标题

  • 前言
  • 目录
  • 一、主从集群搭建
    • 1️⃣伪集群搭建与配置
    • 2️⃣分级管理
    • 3️⃣容灾冷处理
  • 二、主从复制原理
    • 1️⃣主从复制过程
    • 2️⃣数据同步演变过程
  • 后记

在这里插入图片描述
为了避免 Redis 的单点故障问题,我们可以搭建一个 Redis 集群,将数据备份到集群中的其它节点上。若一个 Redis 节点宕机,则由集群中的其它节点顶上。

一、主从集群搭建

Redis 的主从集群是一个“一主多从”的读写分离集群。集群中的 Master 节点负责处理客户端的读写请求,而 Slave 节点仅能处理客户端的读请求。只所以要将集群搭建为读写分离模式,主要原因是,对于数据库集群,写操作压力一般都较小,压力大多数来自于读操作请求。所以,只有一个节点负责处理写操作请求即可。

1️⃣伪集群搭建与配置

在采用单线程 IO 模型时,为了提高处理器的利用率,一般会在一个主机中安装多台 Redis,构建一个 Redis 主从伪集群。当然,搭建伪集群的另一个场景是,在学习 Redis,而学习用主机内存不足以创建多个虚拟机。

下面要搭建的读写分离伪集群包含一个 Master 与两个 Slave。它们的端口号分别是:6380、6381、6382。

🍀(1) 复制 redis.conf

在 redis 安装目录中 mkdir 一个目录,名称随意。这里命名为 cluster。然后将 redis.conf文件复制到 cluster 目录中。该文件后面会被其它配置文件包含,所以该文件中需要设置每个 Redis 节点相同的公共的属性。

在这里插入图片描述

🍀(2) 修改 redis.conf

在 redis.conf 中做如下几项修改:

A、masterauth

在这里插入图片描述

因为我们要搭建主从集群,且每个主机都有可能会是 Master,所以最好不要设置密码验证属性 requirepass。如果真需要设置,一定要每个主机的密码都设置为相同的。此时每个配置文件中都要设置两个完全相同的属性:requirepass 与 masterauth。其中 requirepass 用于指定当前主机的访问密码,而 masterauth 用于指定当前 slave 访问 master 时向 master 提交的访问密码,用于让 master 验证自己身份是否合法。

B、 repl-disable-tcp-nodelay

在这里插入图片描述

该属性用于设置是否禁用 TCP 特性 tcp-nodelay。设置为 yes 则禁用 tcp-nodelay,此时master 与 slave 间的通信会产生延迟,但使用的 TCP 包数量会较少,占用的网络带宽会较小。相反,如果设置为 no,则网络延迟会变小,但使用的 TCP 包数量会较多,相应占用的网络带宽会大。

tcp-nodelay:为了充分复用网络带宽,TCP 总是希望发送尽可能大的数据块。为了达到该目的,TCP 中使用了一个名为 Nagle 的算法。

Nagle 算法的工作原理是,网络在接收到要发送的数据后,并不直接发送,而是等待着数据量足够大(由 TCP 网络特性决定)时再一次性发送出去。这样,网络上传输的有效数据比例就得到了大大提升,无效数据传递量极大减少,于是就节省了网络带宽,缓解了网络压力。

tcp-nodelay 则是 TCP 协议中 Nagle 算法的开头。

🍀(3) 新建 redis6380.conf

新建一个 redis 配置文件 redis6380.conf,该配置文件中的 Redis 端口号为 6380。

在这里插入图片描述

🍀(4) 再复制出两个 conf 文件

再使用 redis6380.conf 复制出两个 conf 文件:redis6381.conf 与redis6382.conf。然后修改其中的内容。

在这里插入图片描述

修改 redis6381.conf 的内容如下:

在这里插入图片描述

修改 redis6382.conf 的内容如下:

在这里插入图片描述

🍀(5) 启动三台 Redis

分别使用 redis6380.conf、redis6381.conf 与 redis6382.conf 三个配置文件启动三台 Redis。

在这里插入图片描述
🍀(6) 设置主从关系

再打开三个会话框,分别使用客户端连接三台 Redis。然后通过 slaveof 命令,指定 6380 的 Redis 为 Master。

在这里插入图片描述

🍀(7) 查看状态信息

通过 info replication 命令可查看当前连接的 Redis 的状态信息。

在这里插入图片描述

2️⃣分级管理

若 Redis 主从集群中的 Slave 较多时,它们的数据同步过程会对 Master 形成较大的性能压力。此时可以对这些 Slave 进行分级管理。

在这里插入图片描述

设置方式很简单,只需要让低级别 Slave 指定其 slaveof 的主机为其上一级 Slave 即可。不过,上一级 Slave 的状态仍为 Slave,只不过,其是更上一级的 Slave。

例如,指定 6382 主机为 6381 主机的 Slave,而 6381 主机仍为真正的 Master 的 Slave。

在这里插入图片描述

此时会发现,Master 的 Slave 只有 6381 一个主机。

3️⃣容灾冷处理

在 Master/Slave 的 Redis 集群中,若 Master 出现宕机怎么办呢?有两种处理方式,一种是通过手工角色调整,使 Slave 晋升为 Master 的冷处理;一种是使用哨兵模式,实现 Redis集群的高可用 HA,即热处理。

无论 Master 是否宕机,Slave 都可通过 slaveof no one 将自己由 Slave 晋升为 Master。如果其原本就有下一级的 Slave,那么,其就直接变为了这些 Slave 的真正的 Master 了。而原来的 Master 也会失去这个原来的 Slave。

在这里插入图片描述

二、主从复制原理

1️⃣主从复制过程

当一个 Redis 节点(slave 节点)接收到类似 slaveof 127.0.0.1 6380 的指令后直至其可以从 master 持续复制数据,大体经历了如下几个过程:

在这里插入图片描述

在这里插入图片描述

🍀(1) 保存 master 地址

当 slave 接收到 slaveof 指令后,slave 会立即将新的 master 的地址保存下来。

🍀(2) 建立连接

slave 中维护着一个定时任务,该定时任务会尝试着与该 master 建立 socket 连接。如果连接无法建立,则其会不断定时重试,直到连接成功或接收到 slaveof no one 指令。

🍀(3) slave 发送 ping 命令

连接建立成功后,slave 会发送 ping 命令进行首次通信。如果 slave 没有收到 master 的回复,则 slave 会主动断开连接,下次的定时任务会重新尝试连接。

🍀(4) 对 slave 身份验证

如果 master 收到了 slave 的 ping 命令,并不会立即对其进行回复,而是会先进行身份验证。如果验证失败,则会发送消息拒绝连接;如果验证成功,则向 slave 发送连接成功响应。

🍀(5) master 持久化

首次通信成功后,slave 会向 master 发送数据同步请求。当 master 接收到请求后,会 fork出一个子进程,让子进程以异步方式立即进行持久化。

🍀(6) 数据发送

持久化完毕后 master 会再 fork 出一个子进程,让该子进程以异步方式将数据发送给slave。slave 会将接收到的数据不断写入到本地的持久化文件中。

在 slave 数据同步过程中,master 的主进程仍在不断地接受着客户端的写操作,且不仅将新的数据写入到了 master 内存,同时也写入到了同步缓存。当 master 的持久化文件中的数据发送完毕后,master 会再将同步缓存中新的数据发送给 slave,由 slave 将其写入到本地持久化文件中。数据同步完成。

🍀(7) slave 恢复内存数据

当 slave 与 master 的数据同步完成后,slave 就会读取本地的持久化文件,将其恢复到本地内存,然后就可以对外提供读服务了。

🍀(8) 持续增量复制

在 slave 对外提供服务过程中,master 会持续不断的将新的数据以增量方式发送给 slave,以保证主从数据的一致性。

2️⃣数据同步演变过程

🍀(1) sync 同步

Redis 2.8 版本之前,首次通信成功后,slave 会向 master 发送 sync 数据同步请求。然后master 就会将其所有数据全部发送给 slave,由 slave 保存到其本地的持久化文件中。这个过程称为全量复制。

但这里存在一个问题:在全量复制过程中可能会出现由于网络抖动而导致复制过程中断。当网络恢复后,slave 与 master 重新连接成功,此时slave 会重新发送 sync 请求,然后会从头开始全量复制。

由于全量复制过程非常耗时,所以期间出现网络抖动的概率很高。而中断后的从头开始不仅需要消耗大量的系统资源、网络带宽,而且可能会出现长时间无法完成全量复制的情况。

🍀(2) psync 同步

Redis 2.8 版本之后,全量复制采用了 psync(Partial Sync,不完全同步)同步策略。当全量复制过程出现由于网络抖动而导致复制过程中断时,当重新连接成功后,复制过程可以“断点续传”。即从断开位置开始继续复制,而不用从头再来。这就大大提升了性能。

为了实现 psync,整个系统做了三个大的变化:

A、复制偏移量

系统为每个要传送数据进行了编号,该编号从 0 开始,每个字节一个编号。该编号称为复制偏移量。参与复制的主从节点都会维护该复制偏移量。

在这里插入图片描述

master 每发送过一个字节数据后就会进行累计。统计信息通过 info replication 的master_repl_offset 可查看到。同时,slave 会定时向 master 上报其自身已完成的复制偏移量给 master,所以 master 也会保存 slave 的复制偏移量 offset。

在这里插入图片描述

slave在接收到 master 的数据后,也会累计接收到的偏移量。统计信息通过 info replication 的 slave_repl_offset 可查看到。

B、 主节点复制 ID

当 master 启动后就会动态生成一个长度为 40 位的 16 进制字符串作为当前 master 的复制 ID,该 ID 是在进行数据同步时 slave 识别 master 使用的。通过 info replication 的 master_replid 属性可查看到该 ID。

C、 复制积压缓冲区

当 master 有连接的 slave 时,在 master 中就会创建并维护一个队列 backlog,默认大小为 1MB,该队列称为复制积压缓冲区。master 接收到了写操作数据不仅会写入到 master 主存,写入到 master 中为每个 slave 配置的发送缓存,而且还会写入到复制积压缓冲区。其作用就是用于保存最近操作的数据,以备“断点续传”时做数据补偿,防止数据丢失。

D、 psync 同步过程

在这里插入图片描述

psync 是一个由 slave 提交的命令,其格式为 psync <master_replid> <repl_offset>,表示当前 slave 要从指定的 master 中的 repl_offset+1 处开始复制。repl_offset 表示当前 slave 已经完成复制的数据的 offset。该命令保证了“断点续传”的实现。

在第一次开始复制时,slave 并不知道 master 的动态 ID,并且一定是从头开始复制,所以其提交的 psync 命令为 PSYNC ? -1。即 master_replid 为问号(?),repl_offset 为-1。

如果复制过程中断后 slave 与 master 成功连接,则 slave 再次提交 psyn 命令。此时的 psyn 命令的 repl_offset 参数为其前面已经完成复制的数据的偏移量。

其实,并不是slave提交了psyn命令后就可以立即从master处开始复制,而是需要master 给出响应结果后,根据响应结果来执行。master 根据 slave 提交的请求及 master 自身情况会给出不同的响应结果。响应结果有三种可能:

  • FULLRESYNC <master_replid> <repl_offset>:告知 slave 当前 master 的动态 ID及可以开始全量复制了,这里的 repl_offset 一般为 0
  • CONTINUE:告知 slave 可以按照你提交的 repl_offset 后面位置开始“续传”了
  • ERR:告知 slave,当前 master 的版本低于 Redis 2.8,不支持 psyn,你可以开始全量复制了

E、 psync 存在的问题

  • psync 数据同步过程中,若 slave 重启,在 slave 内存中保存的 master 的动态 ID 与续传 offset都会消失,“断点续传”将无法进行,从而只能进行全量复制,导致资源浪费。
  • 在 psync 数据同步过程中,master 宕机后 slave 会发生“易主”,从而导致 slave 需要从新 master进行全量复制,形成资源浪费。

🍀(3) psync 同步的改进

Redis 4.0 对 psync 进行了改进,提出了“同源增量同步”策略。

A、 解决 slave 重启问题

针对“slave 重启时 master 动态 ID 丢失问题”,改进后的 psync 将 master 的动态 ID 直接写入到了 slave 的持久化文件中。

slave 重启后直接从本地持久化文件中读取 master 的动态 ID,然后向 master 提交获取复制偏移量的请求。master 会根据提交请求的 slave 地址,查找到保存在 master 中的复制偏移量,然后向 slave 回复FULLRESYNC <master_replid> <repl_offset>,以告知 slave 其马上要开始发送的位置。然后 master 开始“断点续传”。

B、 解决 slave 易主问题

slave 易主后需要和新 master 进行全量复制,本质原因是新 master 不认识 slave 提交的 psync 请求中“原 master 的动态 ID”。如果 slave 发送 PSYNC <原 master_replid> <repl_offset> 命令,新master能够识别出该slave要从原master复制数据,而自己的数据也都是从该master 复制来的。那么新 master 就会明白,其与该 slave“师出同门”,应该接收其“断点续传” 同步请求。

而新 master 中恰好保存的有“原 master 的动态 ID”。由于改进后的 psync 中每个 slave 都在本地保存了当前 master 的动态 ID,所以当 slave 晋升为新的 master 后,其本地仍保存有之前 master 的动态 ID。而这一点也恰恰为解决“slave 易主”问题提供了条件。通过 master 的 info replicaton 中的 master_replid2 可查看到。如果尚未发生过易主,则该值为 40 个 0。

🍀(4) 无盘操作

Redis 6.0 对同步过程又进行了改进,提出了“无盘全量同步”与“无盘加载”策略,避免了耗时的 IO 操作。

  • 无盘全量同步:master 的主进程 fork 出的子进程直接将内存中的数据发送给 slave,无需经过磁盘。
  • 无盘加载:slave 在接收到 master 发送来的数据后不需要将其写入到磁盘文件,而是直接写入到内存,这样 slave就可快速完成数据恢复。

🍀(5) 共享复制积压缓冲区

Redis 7.0 版本对复制积压缓冲区进行了改进,让各个 slave 的发送缓冲区共享复制积压缓冲区。这使得复制积压缓冲区的作用,除了可以保障数据的安全性外,还作为所有 slave 的发送缓冲区,充分利用了复制积压缓冲区。


后记

在这里插入图片描述

👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~

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

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

相关文章

MySQL数据库从入门到精通学习第7天(表数据的增、删、改操作)

表数据的增、删、改操作 使用INSERT...VALUES语句插入数据修改数据删除数据 使用INSERT…VALUES语句插入数据 语法&#xff1a; INSERT [INTO] 数据表名[(字段名...)] VALUES ({值 | DEFAULT},...),()...; [INTO] 数据表名&#xff1a;可选项&#xff0c;用于指定被操作的数…

手把手教你rtsp流媒体分析(引导篇,欢迎订阅专栏)

系列音视频开发 文章目录 系列音视频开发前言一、RTSP是什么&#xff1f;二、RTP是什么&#xff1f;三、RTCP是什么&#xff1f;四、RTSP 源码学习五、H265 RTSP流总结 前言 在安防行业中&#xff0c;onvif协议与gb协议是两种标准&#xff0c;gb是国内安防行业的标准&#xff…

Go Web下gin框架使用(二)

〇、gin 路由 Gin是一个用于构建Web应用程序的Go语言框架&#xff0c;它具有简单、快速、灵活的特点。在Gin中&#xff0c;可以使用路由来定义URL和处理程序之间的映射关系。 r : gin.Default()// 访问 /index 这个路由// 获取信息r.GET("/index", func(c *gin.Con…

康耐视In-Sight2800相机的使用

In-Sight2800相机注册分类程序 一、登录相机 二、图像导入 IS相机支持拍摄图像和从文件中导入图像 如选择从文件中导入图像&#xff0c;文件夹选择位置在页面左下方&#xff0c;如下图 三、注册分类器 在检查模块注册分类器&#xff0c;注册图像需要一张一张去学习&#x…

儿童节到了,我用HTML和CSS画了一个小朋友

文章目录 前言一、关于HTML和CSS二、开始编码2.1 在HTML正文中配置好元素2.2 开始写各个元素的CSS2.3 效果图展示 总结 前言 官方告知我今天参加活动会得勋章&#xff0c;于是想了半天&#xff0c;总得创作一点东西&#xff0c;于是翻出来多年前的箱底技术&#xff0c;用CSSHT…

Kubernetes集群架构与组件介绍

个人博客 一、集群架构 二、主要组件 1.kubelet 该组件运行在每个Kubernetes节点上&#xff0c;用于管理节点。用来接收、处理、上报kube-apiserver组件下发的任务。 主要负责所在节点上的Pod资源对象的管理&#xff0c;例如Pod资源对象的创建、修改、监控、删除、驱逐及Pod…

内网安全:初探隧道技术

目录 防火墙必备知识 域控-防火墙组策略对象同步 域控 - 防火墙组策略不出网上线 MSF上线 CS - ICMP上线 注意&#xff1a;隧道技术是后渗透手段&#xff0c;是在已经取得权限后的手段 域控-组策略同步 防火墙必备知识 学习防火墙的目标是知道了解防火墙的一些常见配置…

ChatGPT应用助推跨境电商发展,低代码凭啥不行?!

随着互联网信息技术的不断发展&#xff0c;随之衍生的诸多产业也在蓬勃发展&#xff0c;而跨境电商就是互联网信息技术发展下的典型产物。 如何定义&#xff1f; 跨境电商指的是通过互联网销售商品或服务&#xff0c;跨越国家或地区边界&#xff0c;实现国际贸易的一种商业模式…

Linux 实操篇-实用指令

Linux 实操篇-实用指令 指定运行级别 基本介绍 运行级别说明&#xff1a; 0 &#xff1a;关机 1 &#xff1a;单用户【找回丢失密码】 2&#xff1a;多用户状态没有网络服务 3&#xff1a;多用户状态有网络服务 4&#xff1a;系统未使用保留给用户 5&#xff1a;图形界…

开发移动端官网总结_Vue2.x

目录 1、自定义加载中效果 2、HTML页面注入环境变量 / 加载CDN和本地库 3、在 Vue 中使用 wow.js 4、过渡路由 5、全局监听当前设备&#xff0c;切换PC端和移动端 6、移动端常用初始化样式 7、官网默认入口文件 8、回到顶部滑动过渡效果&#xff08;显示与隐藏、滑动置…

由于找不到vcruntime140_1.dll无法继续执行此代码的三个解决方法

vcruntime140_1.dll是Microsoft Visual C Redistributable for Visual Studio的一部分&#xff0c;它是一个DLL文件&#xff0c;包含用于运行Microsoft Visual C创建的应用程序所需的Microsoft Visual C组件的代码和数据。这个DLL通常会随着应用程序安装到Windows系统中。如果这…

Dart语法学习

最近在学习flutter相关方面的知识&#xff0c;里面用到了Dart语言&#xff0c;于是写下这篇博客记录学习的一门过程。如果你有其他编程语言的经验&#xff08;尤其是Java和JavaScript&#xff09;&#xff0c;可以很快的上手Dart语言&#xff0c;Dart 在设计时应该是同时借鉴了…

Spring Cloud Alibaba - Nacos源码分析

目录 一、源码 1、为什么要分析源码 2、看源码的方法 二、Nacos服务注册与发现源码剖析 1、Nacos核心功能点 2、Nacos服务端/客户端原理 2.1、nacos-example 2.2、Nacos-Client测试类 3、项目中实例客户端注册 一、源码 1、为什么要分析源码 1. 提升技术功底&#x…

Golang内存泄露场景与定位方式

个人博客 一、产生原因 Golang有自动垃圾回收机制&#xff0c;但是仍然可能会出现内存泄漏的情况。以下是Golang内存泄漏的常见可能原因&#xff1a; 循环引用&#xff1a;如果两个或多个对象相互引用&#xff0c;且没有其他对象引用它们&#xff0c;那么它们就会被垃圾回收机…

【计算机网络实验】BGP和OSPF协议仿真实验

实验内容  BGP和OSPF协议仿真实验 实验目的 &#xff08;1&#xff09;学习BGP协议的配置方法&#xff1b; &#xff08;2&#xff09;验证BGP协议的工作原理&#xff1b; &#xff08;3&#xff09;掌握网络自治系统的划分方法&#xff1b; &#xff08;4&#xff09;验证…

3分钟快速了解—App自动化测试是怎么实现H5测试的?

移动端 app 自动化框架很多&#xff0c;但是有一些框架因为不支持混合应用测试&#xff0c;一直没有完全流行。比较典型的是经典的 Python 框架 uiautomator2, 这个框架简单好用&#xff0c;没有 appium 那样复杂的 api 调用&#xff0c;受到不少 python 自动化工程师的青睐。 …

C++《stack和queue的一些OJ题目》

本文主要讲解C中stack和queue的一些OJ题目 文章目录 1、[最小栈](https://leetcode.cn/problems/min-stack/)2、[栈的压入、弹出序列](https://www.nowcoder.com/practice/d77d11405cc7470d82554cb392585106?tpId13&&tqId11174&rp1&ru/activity/oj&qru/ta…

路径规划算法:基于乌鸦优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于乌鸦优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于乌鸦优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法乌鸦…

驱动开发:内核解析PE结构节表

在笔者上一篇文章《驱动开发&#xff1a;内核解析PE结构导出表》介绍了如何解析内存导出表结构&#xff0c;本章将继续延申实现解析PE结构的PE头&#xff0c;PE节表等数据&#xff0c;总体而言内核中解析PE结构与应用层没什么不同&#xff0c;在上一篇文章中LyShark封装实现了K…

ChatGPT国内免费使用方法【国内免费使用地址】

当下人工智能技术的快速发展&#xff0c;聊天机器人成为了越来越多人们日常生活和工作中的必备工具。如何在国内免费使用ChatGPT聊天机器人&#xff0c;成为了热门话题。本文将为你详细介绍ChatGPT国内免费使用方法&#xff0c;让你轻松拥有聊天机器人助手&#xff0c;提高工作…