【Redis—主从复制】

news2024/9/25 19:15:59

概念

  • 如果把数据都存储到一台服务器上,当服务器出现宕机后,数据会丢失。而把数据备份到多台服务器上,那么当一台服务器发生故障后,其他服务器仍然可以继续提供服务。由于是多台服务器,所以服务器之间的数据要保持一致性
  • 于是Redis提供了主从复制模式,采用的是「读写分离」的方式。主服务器负责读写,从服务器一般只负责读

注意:第一次同步是全量同步的方式。

在这里插入图片描述

主从服务器同步流程

  • 使用replicaof(Redis 5.0 之前使用 slaveof)命令形成主服务器和从服务器的关系。
# 服务器 B 执行这条命令,此时服务器 B 就会变成服务器 A 的「从服务器」
replicaof <服务器 A 的 IP 地址> <服务器 A 的 Redis 端口号>

主从服务器间的第一次同步的过程可分为三个阶段:

  • 第一阶段是建立链接、协商同步;
  • 第二阶段是主服务器同步数据给从服务器;
  • 第三阶段是主服务器发送新写操作命令给从服务器。

具体流程
在这里插入图片描述

  1. 执行了 replicaof 命令后,从服务器就会给主服务器发送psync命令,该命令包含主服务器的 runID(每个Redis服务器启动的唯一标识) 复制进度 offset。第一次同步runID="?",offset=-1
  2. 主服务器收到 psync 命令后,会用 FULLRESYNC (全增量)作为响应命令返回给对方。
  3. 主服务器会执行 bgsave 命令来fork一个子进程生成 RDB 文件(异步的,不会阻塞主线程),然后把文件发送给从服务器。
  4. 从服务器收到 RDB 文件后,会先清空当前的数据,然后载入 RDB 文件。
    • 在此期间 写操作命令并没有记录到刚刚生成的 RDB 文件中,这时主从服务器间的数据就不一致了。
    • 为了保证主从服务器的数据一致性,主服务器在下面这三个时间间隙中将收到的写操作命令,写入到 replication buffer 缓冲区里:
      • 主服务器生成 RDB 文件期间;
      • 主服务器发送 RDB 文件给从服务器期间;
      • 「从服务器」加载 RDB 文件期间;
  5. 从服务器加载完数据后,会回复一个确认消息给主服务器。主服务器将 replication buffer 缓冲区里所记录的写操作命令发送给从服务器,服务器执行发来的命令。

命令传播

  • 主从服务器在完成第一次同步后,双方之间就会维护一个 TCP 长连接。目的是避免频繁的 TCP 连接和断开带来的性能开销。

分摊压力

问题

  • 主服务器会做两件耗时的操作:生成 RDB 文件和传输 RDB 文件。当从服务器比较多的时候,就会带来两个问题:
    1. 如果主服务器的内存数据非大,在执行 fork() 函数时是会阻塞主线程的,从而使得 Redis 无法正常处理请求;
    2. 传输 RDB 文件会占用主服务器的网络带宽,会对主服务器响应命令请求产生影响。

解决办法

  • 主服务器生成 RDB 和传输 RDB 的压力可以分摊到充当经理角色的从服务器。
'在「从服务器」上执行下面这条命令,使其作为目标服务器的从服务器'
replicaof <目标服务器的IP> 6379

在这里插入图片描述

增量复制

  • 主从第一次同步后就是保持长连接,但是由于网络问题,连接可能断开,当网络恢复后,主从服务器会采用增量复制的方式继续同步
    在这里插入图片描述
    增量复制的流程
  • 从服务器在恢复网络后,会发送 psync 命令给主服务器,此时的 psync 命令里的 offset 参数不是 -1;
  • 主服务器收到该命令后,然后用 CONTINUE 响应命令告诉从服务器接下来采用增量复制的方式同步数据;
  • 主服务将主从服务器断线期间,所执行的写命令发送给从服务器,然后从服务器执行这些命令。

主服务器
在这里插入图片描述

  • repl_backlog_buffer,是一个「环形」缓冲区,用于主从服务器断连后,从中找到差异的数据;
    • 在主服务器进行命令传播时,不仅会将写命令发送给从服务器,还会将写命令写入到 repl_backlog_buffer 缓冲区里。
  • replication offset,标记上面那个缓冲区的同步进度,主从服务器都有各自的偏移量,主服务器使用 master_repl_offset 来记录自己「写」到的位置,从服务器使用 slave_repl_offset 来记录自己「读」到的位置。
    • 网络断开恢复后,从服务器会通过 psync 命令将自己的复制偏移量 slave_repl_offset 发送给主服务器,主服务器根据自己的 master_repl_offset - slave_repl_offset 的值决定执行增量还是全量
      • 从服务器要读取的数据还在 repl_backlog_buffer 缓冲区里,那么主服务器将采用增量同步的方式;
      • 从服务器要读取的数据已经不存在 repl_backlog_buffer 缓冲区里,那么主服务器将采用全量同步的方式。

总结

  • 为了避免在网络恢复时,主服务器频繁地使用全量同步的方式,我们应该调整下 repl_backlog_buffer 缓冲区大小,尽可能的大一些,减少出现从服务器要读取的数据被覆盖的概率,从而使得主服务器采用增量同步的方式。

面试题

1.Redis主从节点时长连接还是短连接?

  • 长连接

2.怎么判断 Redis 某个节点是否正常工作?

  • 通过互相的 ping-pong 心态检测机制,如果有一半以上的节点去 ping 一个节点的时候没有 pong 回应,集群就会认为这个节点挂掉了,会断开与这个节点的连接。
    • Redis 主节点默认每隔 10 秒对从节点发送 ping 命令,判断从节点的存活性和连接状态。
    • Redis 从节点每隔 1 秒发送 replconf ack{offset} 命令。
      • 监测主从节点网络状态;
      • 上报自身复制偏移量, 检查复制数据是否丢失, 如果从节点数据丢失, 再从主节点的复制缓冲区中拉取丢失数据。

3.主从复制架构中,过期key如何处理?

  • 主节点处理了一个key或者通过淘汰算法淘汰了一个key,这个时间主节点模拟一条del命令发送给从节点,从节点收到该命令后,就进行删除key的操作。

4.Redis 是同步复制还是异步复制?

  • Redis 主节点每次收到写命令之后,先写到内部的缓冲区,然后异步发送给从节点。

5.主从复制中两个 Buffer(replication buffer 、repl backlog buffer)有什么区别?

  • 出现的阶段不一样:
    • repl backlog buffer 是在增量复制阶段出现,一个主节点只分配一个 repl backlog buffer;
    • replication buffer 是在全量复制阶段和增量复制阶段都会出现,主节点会给每个新连接的从节点,分配一个 replication buffer;
  • 这两个 Buffer 都有大小限制的,当缓冲区满了之后,发生的事情不一样:
    • 当 repl backlog buffer 满了,因为是环形结构,会直接覆盖起始位置数据;
    • 当 replication buffer 满了,会导致连接断开,删除缓存,从节点重新连接,重新开始全量复制。

6.为什么会出现主从数据不一致?

  • 主从节点间的命令复制是异步进行的,所以无法实现强一致性保证(主从数据时时刻刻保持一致)。
  • 主节点并不会等到从节点实际执行完命令后,再把结果返回给客户端,而是主节点自己在本地执行完命令后,就会向客户端返回结果了。如果从节点还没有执行主节点同步过来的命令,主从节点间的数据就不一致了。

7.如何应对主从数据不一致?

  • 第一种方法,尽量保证主从节点间的网络连接状况良好,避免主从节点在不同的机房。
  • 第二种方法,可以开发一个外部程序来监控主从节点间的复制进度
    • 如果某个从节点的进度差值大于我们预设的阈值,可以让客户端不再和这个从节点连接进行数据读取。不过,为了避免出现客户端和所有从节点都不能连接的情况,我们需要把复制进度差值的阈值设置得大一些。

8.主从切换如何减少(不可能保证数据完全不丢失)数据丢失?
主从切换过程中,产生数据丢失的情况有两种:

  • 异步复制同步丢失
  • 集群产生脑裂数据丢失

异步复制同步丢失?

  • 主从复制时异步的,当客户端发送写请求给主节点的时候,客户端会返回 ok,接着主节点将写请求异步同步给各个从节点,如果此时主节点还没来得及同步给从节点时发生了断电,那么主节点内存中的数据会丢失。

减少异步复制的数据丢失的方案

  • Redis 配置里有一个参数 min-slaves-max-lag,当主从数据复制和同步延迟超过该值,那么主节点会拒绝接收任何请求
    • 假设将 min-slaves-max-lag=10s,如果数据同步完成所需要时间超过10s,master 就拒绝写入新请求。这样主从数据控制在10s内,即使主节点宕机也只损失10s数据
  • 对于客户端,当客户端发现 master 不可写后,将数据暂时写入本地缓存和磁盘中,在一段时间(等 master 恢复正常)后重新写入 master 来保证数据不丢失,也可以将数据写入 kafka 消息队列,等 master 恢复正常,再隔一段时间去消费 kafka 中的数据,让将数据重新写入 master 。

集群产生脑裂数据丢失?

  • 由于网络问题,主从节点之间失去联系,当主节点与客户端正常,主从数据不同步;哨兵重新选取主节点,此时有两个主节点。等网络恢复,旧主节点会降级为从节点,再与新主节点进行同步复制的时候,由于会从节点会清空自己的缓冲区,所以导致之前客户端写入的数据丢失了。

减少脑裂的数据丢的方案

  • min-slaves-to-write x,主节点必须要有至少 x 个从节点连接,如果小于这个数,主节点会禁止写数据。
  • min-slaves-max-lag x,主从数据复制和同步的延迟不能超过 x 秒,如果主从同步的延迟超过 x 秒,主节点会禁止写数据。
  • 主节点连接的从节点中至少有 N 个从节点,「并且」主节点进行数据复制时的 ACK 消息延迟不能超过 T 秒,否则,主节点就不会再接收客户端的写请求了。

9.主从如何做到故障自动切换?

  • 主节点挂了 ,从节点是无法自动升级为主节点的,这个过程需要人工处理,在此期间 Redis 无法对外提供写操作。
  • 此时,Redis 哨兵机制起作用,哨兵在发现主节点出现故障时,由哨兵自动完成故障发现和故障转移,并通知给应用方,从而实现高可用性。

文章节选自https://xiaolincoding.com/

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

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

相关文章

SwiftUI 如何动态条件显示和隐藏 Toolbar 按钮且不做无谓刷新

功能需求 在 SwiftUI 中我们可以非常容易的定制导航栏 Toolbar 中按钮的显示,包括折叠、分组和按条件动态显示和隐藏等。 如上图所示,我们仅用寥寥几行代码就实现了 SwiftUI 导航栏 Toolbar 按钮的折叠、分组和按条件动态显示隐藏等功能。 在本篇博文中,您将学到以下内容:…

Spring Cache的使用

目录 一、前言二、什么是Spring Cache&#xff1f;三、Spring Cache常用注解四、使用方法1.导入依赖2.开启缓存注解3.Cacheables4.CachePut5.CacheEvict6.Caching 一、前言 在日常开发工作中&#xff0c;缓存是一个很常见的技术手段&#xff0c;它可以有效地提高系统性能。当系…

6.1.1 图:基本概念

一&#xff0c;基本概念 1.基本定义 &#xff08;1&#xff09;图的定义 顶点集不可以是空集&#xff0c;但边集可以是空集。 &#xff08;2&#xff09; 有向图的表示&#xff1a; 圆括号 无向图的表示&#xff1a; 尖括号 简单图、多重图&#xff1a; 简单图&#xff1a;…

Java中变量的学习

目录 概述&#xff1a;Java中的成员包含五部分 第一部分&#xff1a;变量 &#xff08;1&#xff09;Java中的变量分类 &#xff08;2&#xff09;成员变量和局部变量的位置区别 &#xff08;3&#xff09;Java中成员变量作用域/Java权限修饰符 &#xff08;4&#xff09;…

IntelliJ IDEA 社区版2021.3配置SpringBoot项目详细教程及错误解决方法

目录 一、SpringBoot的定义 二、Spring Boot 优点 三、创建一个springboot的项目 四、使用IDEA创建SpringBoot失败案例 一、SpringBoot的定义 Spring 的诞⽣是为了简化 Java 程序的开发的&#xff0c;⽽ Spring Boot 的诞⽣是为了简化 Spring 程序开发的。 Spring Boot 翻…

maven从入门到精通 第一章 Maven核心程序解压与配置

这里写自定义目录标题 一 为什么要使用Maven1 依赖管理 帮助管jar包2 构建管理 脱离IDE进行运行2.1 传统方式&#xff0c;就是打包成war包&#xff0c;然后放在tomacat上运行2.2 一个程序的运行步骤 二 maven的工作机制1 配置maven1.1 关注 Maven 的核心配置文件&#xff1a;co…

Android Glide加载图片、网络监听、设置资源监听

再搞事情之前首先创建一个项目&#xff0c;就命名为GlideDemo吧。    一、项目配置 创建好之后&#xff0c;在app模块下build.gradle的dependencies闭包中添加如下依赖&#xff1a; //glide//glideimplementation com.github.bumptech.glide:glide:4.11.0annotationProcess…

mysql的一次死锁记录

表结构 create table lzy_test.test_lzy (id int not null primary key,name varchar(128) default null,age int default 0 null,constraint key_name unique (name) );表中数据 idnameage1lzy104lzy412336lzy609lzy90 事务死锁的过程 隔离级别RC 事务A…

【沐风老师】3dMax创建缝线插件StitchLines使用方法详解

3dMax创建缝线插件使用方法详解 3dMax创建缝线插件StitchLines&#xff0c;一键生成车缝线建模&#xff0c;该脚本与可编辑多边形、可编辑样条线或 编辑多边形修改器一起使用&#xff0c;创建一条样条曲线&#xff08;车缝线&#xff09;&#xff0c;它将以几何体形式在视口中和…

云时通OMS:为零售品牌商打造高效的全渠道订单管理!

传统的零售企业围绕“人、货、场” 三要素来展开营销&#xff0c;其目标是基于“场”将货销售给更多的人。随着数字技术的应用&#xff0c;新零售模式下的“场”除了传统的线下店铺外&#xff0c;还拓展了多元化的线上渠道&#xff0c;比如小程序、企业APP、第三方平台、电商直…

学系统集成项目管理工程师(中项)系列17a_范围管理(上)

1. 包括确保项目做且只做所需的全部工作&#xff0c;以成功完成项目的各个过程 2. 项目工作明确划定边界 2.1. 什么是包括在项目之内的 2.2. 什么是不包括在项目之内的 3. 项目其他各方面管理的基础 4. 编制范围管理计划过程 4.1. 对如何定义、确认和控制项目范围的过程进…

归一化处理(2023寒假每日一题 14)

在机器学习中&#xff0c;对数据进行归一化处理是一种常用的技术。 将数据从各种各样分布调整为平均值为 0 0 0、方差为 1 1 1 的标准分布&#xff0c;在很多情况下都可以有效地加速模型的训练。 这里假定需要处理的数据为 n n n 个整数 a 1 , a 2 , ⋯ , a n a_1,a_2,⋯…

零入门kubernetes网络实战-30->基于bridge+veth pair+DNAT技术来实现外网可以访问内网的方案

《零入门kubernetes网络实战》视频专栏地址 https://www.ixigua.com/7193641905282875942 本篇文章视频地址(稍后上传) 通过DNAT技术可以将brige虚拟网桥管理的内网中的服务暴露出来&#xff0c;以供外网访问。 1、测试环境介绍 两台centos虚拟机 # 查看操作系统版本 cat /…

Typora 文字快捷修改颜色

Typora 设置字体上色快捷键 1. 安装AutoHotKey AutoHotkey 是一种 免费 和 开源 的微软Windows自定义脚本语言&#xff0c;最初旨在 提供简单的键盘快捷键或热键 &#xff0c; 快速创建宏和软件自动化 。 基于成熟的做法&#xff0c;本脚本也采用 AutoHotKey 实现。 AutoHot…

精炼计算机网络——物理层(一)

文章目录 前言2.1物理层的基本概念2.2 数据通信的基础知识2.2.1 数据通信系统的模型2.2.3 信道的极限容量 2.3 物理层下面的传输媒体2.3.1 导引型传输媒体2.3.2 非导引型传输媒体 总结 前言 经历了两篇文章的学习&#xff0c;相信读者们一定对计算机网络有了一个基础的了解。接…

vue3+element-plus 通过v-infinite实现下拉滚动无限加载

v-infinite官网 v-infinite-scroll无限滚动组件使用详解 1、v-infinite-scroll"load" //load无限滚动加载的方法2、infinite-scroll-disabled //是否禁用无限滚动加载3、infinite-scroll-delay //节流时延&#xff0c;单位为ms4、infinite-scroll-distance //触发加载…

深入理解Java Class文件格式 constant_UTF_info

首先&#xff0c; 让我们回顾一下关于class文件格式的之前两篇博客的主要内容。 在 深入理解Java Class文件格式&#xff08;一&#xff09; 中&#xff0c; 讲解了class文件在整个java体系结构中的位置和作用&#xff0c; 讲解了class文件中的魔数和版本号相关的信息&#xff…

GitHub上“千金难求”的Spring Boot趣味实战全彩版手册,太干了

本书内容极其丰富&#xff0c;不仅涵盖了Spring MVC、MyBatis Plus、SpringData JPA、Spring Security、Quartz等主流框架&#xff0c;整合了MySQL、Druid、Redis、RabbitMQ、Elasticsearch等互联网常用技术与中间件&#xff0c;还涉及单元测试、异常处理、日志、Swagger等技术…

Vue——Vue2项目开发流程以及Element组件库的使用

Vue项目开发流程&#xff08;Vue2演示&#xff09; 在使用Vue提供的脚手架创建的项目文件里面&#xff0c;可以看见引入了三个组件 一个是Vue组件&#xff0c;有了这个下面才可以新建一个Vue实例 一个是App组件&#xff0c;下面将其使用一个render函数打包成了一个DOM元素放…

Redis分片集群和亿级访问量数据处理

一、redis分片集群 1.简介 业务场景&#xff0c;需要存储50G的数据。对于内存和硬盘配置不足&#xff0c;选用两种方式 一种&#xff1a;纵向扩展&#xff1a;加内存&#xff0c;加硬盘&#xff0c;提高CPU。简单、直接。RDB存储效率要考虑。成本要考虑。 二种&#xff1a;横…