【Redis分析】(一) 主从同步

news2024/9/22 7:33:44

主从复制 - 数据备份, 读写分离, 手动高可用

  1. 负载均衡: 主结点只负责处理写请求, 从节点负责读请求;
  2. 主从复制, 主机挂了, 我们可以手动切换从机, 还可以搭配哨兵实现自动切换, 实现高可用;
  3. 需要注意的是, 在主从模式下, 假设进行同步的过程中主节点宕机了, 那么从节点此时还没有同步到所有的数据, 会发生数据不一致问题;

开启主从复制

通常有以下三种方式:

  • 在 slave 直接执行命令:replicaof <masterip> <masterport>
  • 在 slave 配置文件中加入:replicaof <masterip> <masterport>
  • 使用启动命令:-- replicaof <masterip> <masterport>

主从同步

主节点

从结点

全量同步

当我们配置好主从同步的时候,由于之前没有进行过任何同步,所以首先会进行一次全量数据同步到从库。

主从建立连接

Slave从库会主动和Master主库进行通信,发送psync 命令,该命令会捎带两个参数过去给Master,第一个参数是主库ID(runID),redis 在启动的时候,都会为自己生成一个ID,第二个是Slave复制Maser数据的偏移量offset。

Slave第一次和Master进行通信,由于一开始不知道Master的ID,所以传递了 ?;
由于是第一次复制,offset 传递 -1 表示第一次要进行全量复制。

接着Master接收到了Slave传递过来的命令以及相应的参数,一看是? 和 -1 ,那么就知道这个Slave要进行全量的复制,Master会给Slave 发送一个 fullresync 命令,告诉Slave接下来要开始全量复制,并带上自己的 ID,Slave 接收到这两个参数后会保存起来。

发送rdb文件

Master接着就会执行bgsave, fork 子进程,完成rdb文件的生成,生成完rdb文件后,会发送rdb文件给Slave,Slave会接收rdb文件,在进行接收之前,会先清空Slave自己的数据库数据【这个过程是阻塞的】,清空完成后,开始接收rdb文件,接收完成之后,就加载rdb文件到内存中。

这里还有一个问题,就是在接收rdb文件的时候,Master可能会有新的写操作过来,由于rdb是某一时刻的内存快照,所以之后的数据,是无法进行传输的;

这里redis采用了一个 replication_buffer 来解决,在生成rdb开始,新的写请求数据都会放到这个缓冲区一份,等待rdb传输完成之后,Master接着就会传输这个缓冲区的数据到 Slave,Slave开始接收,接收完成,主从数据保持一致了

**只要一个Slave和Master 建立好连接,对应的 replication_buffer 就会建立,如果断开连接,那么这个缓冲区就会释放。每个 Slave 都有一个replication_buffer **

增量复制

全量复制结束后, 就进入命令传播阶段, 通过一个长连接, 持续不断地将主库收到的写命令同步给从机;

命令传播阶段网络中断了,怎么办?

如果网络发生中断,最早的时候会再走一次全量复制。

后来对这个过程做了优化,采用增量复制的机制;

还记得全量复制的时候,会返回给Slave一个偏移量吗?其实Slave在接收数据之后,会增加这个偏移量来记录当前接收Master多少数据了。

如果网络发生了中断,就会重试和Master重新连接,连接之后,会发送自己的offset给Master,Master会根据Slave发送的偏移量来决定是给Slave做增量复制还是做全量复制。

从开始第一次主从复制开始,那么新的写请求在写入replication buffer的同时,也都会写入到一个叫做 repl_backlog_buffer 的缓冲区内,这是一个环形缓冲区,会记录Master接收的写命令和这条命令的偏移量(从第一次开始主从复制开始),这样Slave再重新连接之后,就可以从这里接着发送命令给Slave了。

所有 Slave 共用同一个 backlog_buffer!

在这里插入图片描述

注意连接没有断开的时候,这两个缓冲区是同时存在,如果连接断开,那么对应Slave的replication buffer缓冲区就会被删除

其实就是环形的每段记录着当前命令和偏移量,随着当前写入的offset不断增大,就会覆盖之前的数据

Master 会记录自己接收的写请求的最新偏移量, 当有 Slave 重连的时候, 与 Slave 的同步进度偏移量进行对比, 如果没有超过环形缓冲区长度, 可以用 backlog_ buffer 中的内容做增量复制, 否则做全量;

命令传播

全量同步完成后, 会进入命令传播阶段 ( 增量同步也是通过命令传播实现的 )

slave 默认会以每秒一次的频率,向 master 发送命令:REPLCONF ACK ,其中 reploff 是 slave 当前的复制偏移量。

发送REPLCONF ACK 命令对于主从服务器的作用:

1)检测 master 和 slave 的网络连接状态。

2)汇报自己的复制偏移量,检测命令丢失,master 会对比复制偏移量,如果发现 slave 的复制偏移量小于自己,会从 repl_backlog_buffer 向 slave 发送未同步的数据。

总结

到现在整个redis 主从复制的过程就讲解完成了,现在来做下总结。

主从同步分为两个类型:

全量同步

全量同步redis 会执行bgsave 来生成rdb文件,然后发送给从库,从库接收之前会先清空从库的数据空,防止之前有数据造成数据的污染,接收完rdb文件之后,就会就加载rdb文件到内存,这时同步其实并没有完成,在进行生成rdb文件的时候,还会有新的写请求过来,此时这些写请求会缓存在一个缓冲区内,这个缓冲区叫做 replication buffer,当从库加载完rdb之后,就会接收这个缓冲区的所有写命令了,到此全量复制就结束了。

由于生产rdb是会阻塞主线程,这个过程很耗费资源,如果采用一个主多个从的方式,那么势必会增加主库的压力,所以从库不是越多越好;

增量同步

如果主从断开连接了,redis 主库会判断是进行全量复制还是增量复制,主库会根据从库发送过来的 runID 和 offset 判断,如果runID和主库的ID相同,并且主从的 offset 差距没有超过 repl_backlog_buffer 缓冲区的长度,就会复制 offset 之间的 repl_backlog_buffer 的命令给Slave。

两个缓冲区:

  • replication buffer

replication buffer 是在从库和主库建立连接成功后创建的,在主从断开后,这个缓冲区也会被主库进行删除,主从库之间复制命令的传输,都会经过这个buffer,而且这个buffer是每个从库独有的。

  • repl_backlog_buffer

主接收到第一个复制请求后,就会建立好这个buffer,这个buffer记录当前 Master 接收到的新的写操作命令 offset 和命令本身,是所有 Slave 公用的 buffer,Slave 发送psync之后,会和Master的offset进行比较,来决定是否进行增量复制。

注意点:

  1. Redis 单机内存越大越好吗? 不, 越大, Fork 子进程的时间越长, 执行 BGSAVE 和 BGREWRITEAOF 时主进程阻塞时间就越长; 主从同步的时候也会涉及到 BGSAVE;
  2. 为什么用 RDB 而不是 AOF ? 文件小, 恢复快;
  3. 如果想减少因为连接断开导致的全量同步, 可以适当增加 back_log 的大小;
  4. 如果 RDB 文件比较大, 或者网速比较慢, replication_buffer 会满, 主库会和从断开连接,删除buffer,如果从再来请求链接,可能会造成恶性循环。可以适当调大;

目前仍存在的问题

主机掉线后需要手动切换从机

  1. 可以用 Sentinel 解决;

主从过期时间不一致;

  1. 由于网络原理, 从机接收到写命令的时间会比主机晚, 使用 expire pexpire 命令设置过期时间的以后, 是以命令执行时间为起点的相对时间;
  2. 就会导致从机键值对的过期时间延迟; 可以使用 expireat, 设置绝对过期时间, 这里需要注意主从时间要同步;

从机挂掉后主机的runId 和 offset 会丢失; 只能全量同步;

  1. 改进: rdb 会记录 runId 和 offset, 这样从机从 rdb 恢复后, 如果来得及, 还是能增量的, 也不会丢失数据;

主机挂掉后, 剩下的从机, 都要重新和新选出来的主机做全量同步; 会有数据丢失, 且效率低下;

  1. PSYNC2.0 进行了改进, 原本的 runId 和 offset 都变成了两个, 这里简称为 id, id2, offset, offset2;
  2. 对于主机, id 是自己的id, id2 是上一任主机的id; 对于从机, id 是 现任主机id, id2 是上一任主机id;
  3. offset 是当前的偏移量, offset2 是上一任主机没挂的时候, 同步的偏移量;
  4. 发生主从切换后, 就可以通过 id2 知道原本都从属于同一个主机, 可以尝试进行增量同步;

数据量大, 写操作频繁时, 可能导致 replication_buffer 溢出, 无法解决海量数据的问题

  1. 用Redis集群解决;

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

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

相关文章

Ubuntu | 右上角网络图标消失,有线网络在设置中消失,虚拟机没网

目录 第一步&#xff1a;删除 NetworkManager 缓存文件第二步&#xff1a;修改 /etc/NetworkManager/NetworkManager.conf第三步&#xff1a;重启 NetworkManager第四步&#xff1a;右上角网络图标出现 参考博客&#xff1a;虚拟机没网&#xff0c;重启网络服务&#xff1a;Fai…

手机操作技巧:如何进入锁定的Android手机

被锁定在您的 Android 手机之外可能是一种令人沮丧的经历&#xff0c;尤其是当您存储了重要文件和数据时。幸运的是&#xff0c;您可以尝试几种方法来重新获得对手机的访问权限。在这篇博文中&#xff0c;我们将探讨可用于解锁锁定的 Android 手机的各种技术和工具。我们还将提…

80.游戏的分辨率修改思路与分析

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;易道云信息技术研究院 上一个内容&#xff1a;79.游戏分析工具闪屏问题优化与数据被修改高亮 GAMEHACKER2.exe 工具下载地址&#xff…

Neo4j图数据库Docker部署至服务器

Neo4j图数据库Docker部署至服务器 文章目录 Neo4j图数据库Docker部署至服务器1. Neo4j介绍2. 拉取Docker镜像3. 创建容器并运行4. 导入数据&#xff08;可选&#xff09;5. 访问测试 1. Neo4j介绍 Neo4j 是一种基于图数据库管理系统&#xff0c;它专门用于存储和查询图数据结构…

Vuepress,搭建自己的技术文档

Vuepress Vuepress用于构建静态站点&#xff0c;非常适合搭建技术文档。如果手头上有开源项目&#xff0c;或者公司内部有项目需要做官网&#xff0c;且官网中大部分都是介绍、用法之类的文章。那么Vuepress是不二选择&#xff01; 我们看到的一些项目的技术文档&#xff0c;…

河北学术会议:机器视觉、图像处理与影像技术领域

第二届机器视觉、图像处理与影像技术国际会议&#xff08;MVIPIT 2024&#xff09;将于2024年9月13日-15日在中国张家口召开。MVIPIT2024聚焦机器视觉、图像处理与影像技术&#xff0c;旨在为专家、学者和研究人员提供一个国际平台&#xff0c;分享研究成果&#xff0c;讨论问题…

WebSocket可拓展业务组件搭建,无侵入实现WebSocket通信信息自定义业务消费

组件概述 面对C端产品&#xff0c;往往会携带有客户端和服务端的双端通信以实现实时交互的效果&#xff0c;但是目前HTTP1.1并不支持双端通信&#xff0c;因此&#xff0c;对于聊天室、多人实时游戏等场景&#xff0c;就需要用到一个新的通信协议&#xff1a;WebSocket。 更多…

UE5-C++入门教程(二)---编写Editor类别的自定义模型实现小球规划路线的可视化

前言 本教程将以图文教程的形式讲述如何快速入门通过C使用UE5.4进行项目编写。UE5的教程系列 第一期&#xff1a;UE5-C入门教程(一)&#xff1a;使用代码创建一个指定目标的移动小球-CSDN博客 UE5与ROS2实战->基于UE5和ROS2的激光雷达深度RGBD相机小车的仿真指南(一)—Unre…

MoneyPrinterTurbo的部署,在服务器Ubuntu22.04系统下——点动科技

在服务器Ubuntu22.04系统下&#xff0c;MoneyPrinterTurbo的部署 一、ubuntu22.04基本环境配置1.1 更换清华Ubuntu镜像源1.2 更新包列表&#xff1a;2. 安装英伟达显卡驱动2.1 使用wget在命令行下载驱动包2.2 更新软件列表和安装必要软件、依赖2.2 卸载原有驱动2.3 安装驱动2.4…

Axure高端交互元件库:助力产品与设计

用户体验&#xff08;UX&#xff09;和用户界面&#xff08;UI&#xff09;设计对于任何产品的成功都至关重要。为了在这个竞争激烈的市场中脱颖而出&#xff0c;设计师和产品开发团队需要依赖强大的工具来创造引人注目且功能丰富的交互界面。下面介绍一款Axure精心制作的"…

物联网(IoT)详解

物联网&#xff08;IoT&#xff09;详解 1. IoT定义简介2. IoT工作原理3. IoT关键技术4. 物联网与互联网区别5. IoT使用场景6. 开源物联网平台7. 参考资料 1. IoT定义简介 首先第一个问题&#xff0c;什么是物联网&#xff08;IoT&#xff09;? 物联网&#xff08;英文&#…

Linux:CentOS配置

一&#xff0c;安装VMware 这个可以通过官网获取 vmware下载 也可以联系我&#xff0c;我发给你 二&#xff0c;安装CentOS Centos官网找要下载的版本&#xff1a; https://vault.centos.org/ 阿里云镜像&#xff1a;https://mirrors.aliyun.com/centos-vault/?spma2c6h.13…

如何搭建redis哨兵集群

1. 构建redis镜像 FROM redis:7.0.15-alpine3.20# install tools RUN apk add curl --no-cache &&\apk add bash --no-cache # COPY redis.conf /usr/local/etc/redis/redis.confCMD [ "redis-server", "/usr/local/etc/redis/redis.conf"] dock…

一起学习LeetCode热题100道(45/100)

45.二叉树的右视图(学习) 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4] 示例 2: 输入: [1,null,3] 输出: [1,3] 示例 …

【微信小程序】自定义组件 - 数据、方法和属性

1. data 数据 2. methods 方法 在小程序组件中&#xff0c;事件处理函数和自定义方法需要定义到 methods 节点中&#xff0c;示例代码如下&#xff1a; 3. properties 属性 在小程序组件中&#xff0c;properties 是组件的对外属性&#xff0c;用来接收外界传递到组件中的数…

如何使用docker打包后端项目并部署到阿里云k8s集群上

如何使用docker打包后端项目并部署到阿里云k8s集群上 1. 引言 在现代软件开发中,容器化技术已经成为主流,而Kubernetes (K8s) 是管理容器的首选平台之一。本文将详细介绍如何将一个后端项目使用Docker打包,并将其部署到阿里云的Kubernetes集群上。 2. 前置条件 阿里云账号…

sentinel集成springcloud实现限流熔断

Sentinel 是由阿里巴巴开源的一款流量控制和熔断降级组件,旨在通过灵活的流量控制和熔断降级机制,帮助开发者保护微服务架构中的应用和服务。 官网&#xff1a;home | Sentinel (sentinelguard.io) 一、安装sentinel 1.方式一&#xff1a;用docker-compose 安装 docker-com…

回归预测|基于粒子群优化深度神经网络DNN的数据回归预测Python程序PSO-DNN 多特征输入单输出

回归预测|基于粒子群优化深度神经网络DNN的数据回归预测Python程序PSO-DNN 多特征输入单输出 文章目录 前言回归预测|基于粒子群优化深度神经网络DNN的数据回归预测Python程序PSO-DNN 多特征输入单输出 一、PSO-DNN模型1. 粒子群优化&#xff08;PSO&#xff09;简介2. 深度神经…

java版知识付费saas租户平台的核心功能设计:打造高效、个性化的学习体验

随着互联网技术的飞速发展&#xff0c;我国在线教育行业迎来了新的变革&#xff0c;知识付费平台应运而生。这种新兴的在线教育模式&#xff0c;以用户需求为导向&#xff0c;以优质内容为核心&#xff0c;通过互联网技术手段&#xff0c;为用户提供便捷、高效的学习渠道。知识…

基于PyTorch的MNIST手写数字GAN生成器

文章目录 前言小笔记关键特性技术栈使用场景贡献者&#xff1a; 完整代码代码解析1. 导入必要的库2. 设备配置3. 超参数设置4. 创建样本目录5. 图像处理6. 加载MNIST数据集7. 创建数据加载器8. 定义判别器&#xff08;Discriminator&#xff09;D9. 定义生成器&#xff08;Gene…