【Redis进阶】主从复制

news2024/11/20 8:38:39

1. 主从结构引入

在分布式系统中,涉及到一个严重问题:单点问题
即如果某个服务器程序只有一个节点(单台机器提供服务),就会出现以下两个问题:

  1. 可用性问题,如果这台机器挂了,意味着服务中断
  2. 并发性能问题,单台机器承受的并发量是有上限的

引入分布式系统,也就是为了能解决上述的单点问题,因此往往在redis中会部署多台redis服务器构建redis集群,此时就可以通过这个集群提供更高性能/更稳定的服务,主要的部署结构有以下几种:

  1. 主从模式
  2. 主从+哨兵模式
  3. 集群模式

主从模式:
在若干个redis节点中,有的是"主节点",有的是"从节点",假设有三台物理服务器,分别部署了一个redis-server进程,此时就可以把其中一个节点作为"主节点",另外两个节点作为"从节点",此时引入从节点后主节点上保存的数据就需要同步给从节点,后续主节点进行的数据修改也要同步给从节点

💡 注意:在redis主从模式中,不允许从节点修改数据!

配置主从模式后,就可以实现 “读写分离” ,即通过主节点来处理写操作,从节点处理读操作,这样的结构就可以完美的解决上述出现的"单点问题":

  1. 在可用性方面:如果有一个从节点挂了,那么问题不大,可以继续从其他从节点上读取数据,但是如果挂的是主节点,在当前结构来看还是有一定影响的,但是也可以通过哨兵机制来解决(此处先不介绍),总之相比于单点服务器程序提升了可用性
  2. 在性能方面:实际业务场景读操作频率 >> 写操作频率,因此配置一主多从节点,每个从节点都能分摊请求压力,引入了更多的硬件资源,因此性能也就提高了

2. 主从结构搭建

当前为了简化部署流程,我们使用单台物理服务器,启动多个redis-server进程来模拟多个物理服务器

💡 提示:此处需要保证redis-server进程启动的端口号各不相同!可以在启动时用选项配置或者在配置文件中进行配置

我们需要保存三份redis.conf配置,设置daemonize为yes以后台方式启动,port必须不同

# 绑定ip
bind=0.0.0.0
# 启动端口号
port=6379
# 关闭保护模式
protect-mode=no
# 以后台方式运行
daemonize=yes

image.png
但是当前几个redis服务还是各自为政的,我们还需要进一步通过以下方式配置成主从结构:

  1. 方式一:在配置文件中配置slaveof [masterIP] [masterPort]
  2. 方式二:在redis-server启动命令后使用--slaveof [masterIP] [masterPort]
  3. 方式三:在redis客户端中使用slaveof [masterIP] [masterPort]

此处我们希望能够使配置永久生效,因此选择在配置文件中修改,比如此处将6379端口进程作为主节点,6380和6181端口进程作为从节点,因此需要在从节点的配置文件中配置slaveof [127.0.0.1] [6379]并重启redis服务!

💡 注意:此处如果是使用redis-server方式启动进程,需要搭配kill -9杀死进程,但是如果是使用service redis-server start方式启动,使用kill -9杀死后仍会自动重启,此时必须要搭配service redis-server stop停止

image.png
此时下面几个进程就是redis主节点和从节点之间建立的TCP连接,后续同步机制就是通过这些TCP连接进行通信的,我们可以尝试登陆主节点使用info replication查看主从配置信息:
image.png

3. 主从复制过程

3.1 replid和offset字段含义

redis提供了psync命令用于完成数据同步(psync命令不需要手动执行,redis服务器会在建立好主从关系后,自动执行psync命令),比如从节点就会执行psync replicationid offset从主节点拉取数据
replicationid:当主节点启动时生成 / 从节点晋升成为主节点的时候生成(注意:就算是同一个主节点,每次启动生成的replicationid也是不重复的)我们可以通过info replication进行查看:
image.png

💡 注意:此处replid2在一般情况下是用不到的,但是可能存在以下场景:比如主节点A与从节点B之间配置主从关系,但是由于网络抖动导致B节点认为A主节点挂了,此时B自动晋升为主节点,给自己生成一个replid,同时还会记录之前的主节点信息保存在replid2上,后续如果主节点A恢复就可以手动配置恢复

offset:偏移量,用来记录从节点和主节点之间的数据同步进度,此处主节点和从节点都需要维护双方的偏移量,主节点会收到很多的修改命令,每一个命令都占据相应字节数,主节点就会把这些命令字节数累加作为偏移量,而从节点的偏移量就描述了从节点当前的同步进度,同时从节点每秒都需要上报给主节点当前的复制偏移量
此时replicationid和offset就构成了一组"数据集合",如果说某两台机器上的replid和offset都相同那就说明两者的数据是完全一致的!

3.2 主从数据复制

在redis中使用psync replicationid offset进行数据同步,但是数据同步有两种方式:1、全量同步,2、增量同步主要就是根据offset这个字段值进行区分:

  1. 如果是全量复制,就将offset值置为-1
  2. 如果offset值为正整数,则从当前偏移量开始进行部分复制

3.2.1 全量复制过程

  1. 从节点发送psync命令给主节点进行数据同步,由于是第一次通信不知道主节点replid因此发送psync ? -1
  2. 主节点根据命令判定为全量同步,返回FULLRESYNC响应
  3. 从节点将主节点的replid进行保存
  4. 主节点使用bgsave命令生成rdb持久化文件,同时在这期间接收到的修改命令保存到缓冲区
  5. 主节点生成完毕rdb文件后发送给从节点
  6. 发送完rdb文件后将缓冲区中的数据也以rdb文件格式追加写入,保证主从一致
  7. 从节点清空自身数据信息
  8. 重放rdb文件中的内容复制数据
  9. 如果还开启了AOF持久化功能,则会执行bgrewriteaof重写,得到最近的AOF文件

🍬 提示:主节点进行全量复制的过程也支持无硬盘模式(diskless),即主节点生成rdb文件的过程可以不保存在硬盘上,而是直接将数据进行网络传输(省去了多次硬盘IO操作)同理从节点加载数据也可以直接进行加载,但是网络传输的开销仍然很大,因此全量复制的开销也是比较大的!

runid和replicationid的区别:
在一个redis服务器上会出现replid和runid两个概念,但是这两个是不一样的,我们可以通过info replication查看replid,可以通过info server查看runid:

  • slave1:

    image.png
    image.png

  • slave2:

    image.png image.png

他们之间的区别概括如下:

  1. 在应用场景上:replid主要作用于主从复制的场景,runid则主要作用于哨兵模式中
  2. 在产生方式上:replid是在主从结构中由主节点启动的时候分配的(主从结构中replid相同),而runid则是每一个节点启动后系统分配的(每个节点均不同)

3.2.2 部分复制过程

在全量复制过程中,开销是比较大的,有些情况下从节点已经复制了主节点上的大部分数据,此时就需要"部分复制"了:比如说出现了网络抖动,此时主节点上最新的修改内容就无法及时同步给从节点,当从节点恢复之后就需要重新建立连接并进行部分同步
部分复制

  1. 当出现网络抖动时,主从节点之间超过repl-timeout时间,主节点就会认为从节点故障并中断连接
  2. 在这期间主节点依旧响应客户端命令,暂时将这些内容写入复制积压缓冲区(repl-backlog-buffer)中
  3. 当从节点恢复后就会重新建立与主节点之间的连接
  4. 从节点将之前保存的replicationidoffset作为psync参数发送给主节点,请求部分复制
  5. 主节点接收到psync请求后解析出部分复制,就会尝试在复制积压缓冲区查找合适数据,并响应continue给从节点
  6. 主节点将同步的数据发送给从节点,保证数据一致性

repl-backlog-buffer:
就是内存中类似于一个环形队列这样的数据结构,会保存最近的一些修改操作,但是总量毕竟还是有上限的,随着时间推移,会逐步删除最早的一些数据
image.png
当主节点接收到从节点的psync replid offset的时候就会先根据offset的值去repl-backlog-buffer查找有无这部分数据,如果有就会从该偏移量开始将后续的数据返回给从节点,如果没有那就只能进行全量复制了

3.2.3 实时复制过程

实时复制:描述的是主从已经完成数据同步之后,主节点这边不断地接收到数据修改操作,就需要实时同步给从节点
从节点和主节点之间会建立TCP的长连接,然后主节点就可以将自己收到的修改数据的请求发送给从节点,从节点再根据这些请求修改内存中的数据,同时为了实时复制能够处于可用状态,还需要借助 心跳包 机制:
主节点:默认每隔10s给从节点发送一个ping命令,从节点收到返回poing
从节点:默认每隔1s给主节点发送特定的请求,就会上报当前的节点同步数据的进度(offset)

4. 主从故障处理

当前配置的主从结构还需要考虑故障处理的问题:

  • 如果挂了的是从节点,那问题不大
  • 如果挂了的是主节点,此时就需要进行处理

当前主从断开连接有两种情况:

  1. 从节点和主节点之间断开连接:比如执行slaveof no one命令,这个时候从节点就会晋升成为主节点
  2. 主节点挂了:此时不会自动将从节点晋升成为主节点,于是引入了哨兵机制的概念(下次讲)

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

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

相关文章

Github 2024-07-27开源项目日报 Top10

根据Github Trendings的统计,今日(2024-07-27统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量非开发语言项目2C++项目2C项目2TypeScript项目1JavaScript项目1Java项目1Python项目1C#项目1免费编程学习平台:freeCodeCamp.org 创建周期:33…

jQuery入门(一)

一、JQuery介绍 - jQuery 是一个 JavaScript 库。 - 所谓的库,就是一个 JS 文件,里面封装了很多预定义的函数,比如获取元素,执行隐藏、移动等,目的就 是在使用时直接调用,不 需要再重复定义,这…

iPhone 在 App Store 中推出的 PC 模拟器 UTM SE

PC 模拟器是什么?PC 模拟器是一种软件工具,它模拟不同硬件或操作系统环境,使得用户可以在一台 PC 上运行其他平台的应用程序或操作系统。通过 PC 模拟器,用户可以在 Windows 电脑上体验 Android 应用、在 Mac 电脑上运行 Windows …

Python如何获取终端尺寸?

os.get_terminal_size(),无差别获取当前终端长宽,让你为所欲为。 (笔记模板由python脚本于2024年07月27日 08:30:53创建,本篇笔记适合喜欢钻研的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Fre…

使用命名管道的通信程序, 加入了日志系统

文章目录 日志系统通信程序运行效果 日志系统 // log.hpp #pragma once #include <time.h> #include <iostream> #include <stdio.h> #include <string> #include <stdarg.h> #include <sys/types.h> #include <sys/stat.h> #inclu…

软设之数据库关系代数

数据库关系代数 基本概念 元祖行&#xff1a;水平方向上每一行为一条记录&#xff0c;这个记录对应1个实体。一般称为元祖&#xff0c;元祖行或者记录 属性列&#xff1a;垂直方向上每一列为一个属性&#xff0c;一般称为属性列&#xff0c;字段等。关系表达式中可以用列序号…

又要起飞,浏览器居然都可以本地 OCR 啦

前言 PaddleOCR&#xff0c;这是一个由百度开发的开源 OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;工具&#xff0c;它可以用于从图像中识别文本。 PaddleOCR支持多种语言的文本识别&#xff0c;并且能够处理多种场景下的图像。 现在…

【Web开发手礼】探索Web开发的魅力(十二)-Vue(2)用户动态页面

前言 主要介绍了用vue框架创建用户动态页面的具体过程&#xff0c;可以帮助学习vue框架的基本知识&#xff01;&#xff01;&#xff01;&#xff01; 用户动态页面 用户信息 用户头像 通过 Bootstrap 所提供的 .img-fluid 类让图片支持响应式布局。其原理是将 max-width: 10…

Java面试八股之Spring boot的自动配置原理

Spring boot的自动配置原理 Spring Boot 的自动配置原理是其最吸引人的特性之一&#xff0c;它大大简化了基于 Spring 框架的应用程序开发。以下是 Spring Boot 自动配置的基本原理和工作流程&#xff1a; 1. 启动类上的注解 Spring Boot 应用通常会在主类上使用 SpringBoot…

ZBrush入门使用介绍——4、笔刷选项说明

大家好&#xff0c;我是阿赵。   这次来看看ZBrush的笔刷的选项用法。 一、选择笔刷 点击笔刷&#xff0c;可以打开笔刷选择面板。 在最上面的Quick Pick&#xff0c;有最近使用过的笔刷&#xff0c;可以快速的选择。下面有很多可以选择的笔刷。但由于笔刷太多&#xff0c;…

AJAX之基础知识

目录 AJAX入门及axios使用什么是AJAX怎么用AJAX 认识URL协议域名资源路径URL查询参数 查询参数URL查询参数axios查询参数 常用请求方法axios请求配置 axios错误处理HTTP协议请求报文请求报文-错误排查响应报文HTTP响应状态码 form-serialize插件 AJAX入门及axios使用 什么是AJ…

【Python机器学习】决策树的构造——信息增益

决策树是最经常使用的数据挖掘算法。它之所以如此流行&#xff0c;一个很重要的原因就是不需要了解机器学习的知识&#xff0c;就能搞明白决策树是如何工作的。 决策树的优缺点&#xff1a; 优点&#xff1a;计算复杂度不高&#xff0c;输出结果易于理解&#xff0c;对中间值的…

RabbitMq手动ack的超简单案例+Confirm和Return机制的配置和使用

最简单的例子 先简单介绍一下这三个方法 basicAck 表示确认成功&#xff0c;使用此方法后&#xff0c;消息会被rabbitmq broker删除 basicNack 表示失败确认&#xff0c;一般在消费消息业务异常时用到此方法&#xff0c;可以将消息重新投递入队列 basicReject 拒绝消息&am…

Chainlit一个快速构建成式AI应用的Python框架,无缝集成与多平台部署

概述 Chainlit 是一个开源 Python 包&#xff0c;用于构建和部署生成式 AI 应用的开源框架。它提供了一种简单的方法来创建交互式的用户界面&#xff0c;这些界面可以与 LLM&#xff08;大型语言模型&#xff09;驱动的应用程序进行通信。Chainlit 旨在帮助开发者快速构建基于…

全网最适合入门的面向对象编程教程:25 类和对象的 Python 实现-Python 判断输入数据类型

全网最适合入门的面向对象编程教程&#xff1a;25 类和对象的 Python 实现-Python 判断输入数据类型 摘要&#xff1a; 本文主要介绍了在使用 Python 面向对象编程时&#xff0c;如何使用 type 函数、isinstance 函数和正则表达式三种方法判断用户输入数据类型&#xff0c;并对…

PWA(渐进式网页应用)方式实现TodoList桌面应用

参考&#xff1a; https://cloud.tencent.com/developer/article/2322236 todlist网页参考&#xff1a; https://blog.csdn.net/weixin_42357472/article/details/140657576 实现在线网页当成app应用&#xff1a; 一个 PWA 应用首先是一个网页, 是通过 Web 技术编写出的一个网…

如何全面提升架构设计的质量?

当我们从可扩展、高可用、高性能等角度设计出来架构的时候&#xff0c;我们如何优化架构呢&#xff1f;就需要从成本、安全、测试等角度进行优化。 如何设计更好的架构 - 步骤 成本 低成本复杂度本质 低成本手段和应用 低成本的主要应用场景 安全 安全性复杂度本质 架构安全…

大语言模型系列-Transformer:深入探索与未来展望

大家好&#xff0c;我是一名测试开发工程师&#xff0c;已经开源一套【自动化测试框架】和【测试管理平台】&#xff0c;欢迎大家联系我&#xff0c;一起【分享测试知识&#xff0c;交流测试技术】 Transformer模型自其问世以来&#xff0c;便迅速在自然语言处理领域崭露头角&a…

2024年【危险化学品生产单位安全生产管理人员】最新解析及危险化学品生产单位安全生产管理人员考试总结

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品生产单位安全生产管理人员最新解析参考答案及危险化学品生产单位安全生产管理人员考试试题解析是安全生产模拟考试一点通题库老师及危险化学品生产单位安全生产管理人员操作证已考过的学员汇总&#xff0c;…