Redis-主从复制

news/2024/12/21 20:25:52/

分布式系统,涉及到一个非常关键的问题:单点问题

如果某个服务器程序,只有一个节点,就会出现:

  • 可用性问题(这个服务器挂了,服务中断)
  • 性能/支持的并发量有限

引入分布式系统,主要也是为了解决上述的单点问题

在分布式系统中,希望有多个服务器来部署redis服务,从而构成一个redis集群,此时就可以让这个集群给整个分布式系统中其它的服务,提供更稳定/高效的数据存储功能

下面有三种redis的部署方式:

主从模式  主从+哨兵  集群模式

此处来讲解主从模式

1. 配置

参与复制的Redis实例划分为主节点(master)和从节点(slave)。每个从结点只能有⼀个主节点, ⽽⼀个主节点可以同时具有多个从结点。

复制的数据流是单向的,只能由主节点到从节点,改变主节点的内容,同步到从节点

从节点的数据时刻和主节点保持一致,因此其它的客户端从从节点这里读取数据,和从主节点这里读取数据,没有区别

从节点数据只能读取,不允许修改

之前只是单个redis服务器节点,此时这个机器挂了,整个redis就挂了,引入主从结构,就不太可能一锅端了

主从模式,主要如果主节点挂了,无法写数据,只能读,从节点挂了,无影响

主从模式针对"读操作"进行并发量,可用性提高

那可以引入多个主节点嘛?

不可以,一山不容二虎,谁听谁呢

建立复制

此时在一个云服务器主机上,运行多个redis-server进程

让新启动的redis-server使用其它端口

1.在配置⽂件中设定端口

2. 在redis-server 启动时,通过命令行指定端口 --port选项

下面一个主节点,两个从节点:

按c进行修改,ctrl+c进行退出修改界面,:wq保存退出 

表示可以按照后台方式进行运行

当前这几个节点并没有构成主从结构,下面需要进一步配置:

1.在配置⽂件中加⼊slaveof{masterHost}{masterPort}随Redis启动⽣效。

2. 在redis-server 启动命令时加⼊--slaveof{masterHost}{masterPort}⽣效。

3. 直接使⽤redis命令:slaveof{masterHost}{masterPort}⽣效

修改之后,重新启动,生效

这种停止redis-server的方式,kii之后,redis-server进程能够自动启动

而如果使用service redis-server start这种方式启动,必须使用service redis-server stop停止

从节点启动之后就会和主节点建立tcp连接.主节点相当于服务器,从节点相当于客户端 

此时主节点这里的数据进行修改,从节点能立即感知到:

 

从节点无法写: 

 

主从节点复制过程

1)查看主节点复制状态信息: 

主节点会收到源源不断的修改数据请求,从节点就需要从主节点这里同步这些修改请求

从节点和主节点之间的数据同步,不是瞬间完成的

offset:相当于同步数据的进度

lag:表示延迟,网络有可能延迟情况

master_replid:主节点的身份标识,从节点会记录

repl:积压缓冲区,支持部分同步机制的实现

2)查看从节点复制状态信息:

断开复制

slaveof no one命令

从节点断开主从关系后,就不属于其它节点了,但里面已有的数据不会抛弃

此时让6380作为6381的从节点:

此时,6381看起来是个主节点,但实际上仍然是从节点,不能修改数据 

虽然刚才通过slaveof命令修改了主从结构,但是此处的修改是临时性的,重新启动redis服务器,仍然会按照最初在配置文件中设置的内容建立主从关系

安全性

对于数据⽐较重要的节点,主节点会通过设置requirepass参数进⾏密码验证,需要配置从节点的masterauth参数与主节点密码保持⼀致,这样从节点才可以正确地连接到主节点并发起复制流程

只读

从节点不允许修改

传输延迟

主从节点之间通过网络传输(tcp)

TCP内部支持nagle算法(默认开启):

开启,就会增加传输延迟,节省网络带宽

关闭,就会减少传输延迟,增加网络带宽

2. 拓扑

一主一从

如果写数据请求太多,此时会给主节点造成压力

可以通过关闭主节点的AOF,只在从节点开启AOF

但是,这种设定方式,会有一个严重的缺陷:主节点一旦挂了,不能让他自动重启(如果自动重启,没有AOF文件,就会丢失数据,进一步的主从同步,会把从节点的数据也删了) 

改进:主节点挂了后,让主节点从从节点获取AOF文件,再启动

一主多从

主节点上的数据发生改变,就会把改变的数据同时同步给所有的从节点,网络延时小

随着从节点个数的增加,同步一条数据,需要传输多次

改进:

树状主从

此时,主节点就不需要那么高的网卡带宽了

但是一旦数据修改了,同步的延时更长 

3. 原理

主从节点建⽴复制流程图

 

数据同步psync 

redis提供了psync命名,完成数据同步的过程,分为:全量复制和部分复制

  • 全量复制:⼀般⽤于初次复制场景,Redis早期⽀持的复制功能只有全量复制,它会把主节点全部数据⼀次性发送给从节点,当数据量较⼤时,会对主从节点和⽹络造成很⼤的开销。
  • 部分复制:⽤于处理在主从复制中因⽹络闪断等原因造成的数据丢失场景,当从节点再次连上主节点后,如果条件允许,主节点会补发数据给从节点。因为补发的数据远⼩于全量数据,可以有效避免全量复制的过⾼开销

不需要手动执行,redis服务器会在建立好主从同步关系之后,自动执行

从节点负责执行psync,从节点从主节点这边拉取数据

语法:

psync replicationid offset

①replicationid/replid (复制id)

是主节点启动时生成的

即使是同一个主节点,每次重启生成的replicationid都是不同的

从节点晋升为主节点,也会生成

主从关系建立时,从节点就会从主节点这边获取到replicationid

一般情况下,replid2用不上

举个例子:

有一个主节点A,从节点B

在A和B通信过程中出现了网络抖动

B就可能认为A挂了

B就会自己成为主节点,给自己生成一个repid,此时B也会记得之前旧的replid,即replid2

后续网络稳定了,B还可以根据replid2重新恢复之前的状态

②offset(偏移量)

主节点和从节点都会维护整个偏移量(整数)

主节点的偏移量:主节点会收到很多修改操作的命令,每个命令都要占据几个字节,主节点会把这些命令,每个命令的字节数进行累加

从节点的偏移量:描述了现在从节点这里的数据同步到哪里了

如果从节点的偏移量和主节点一样,就赶上"直播"了

从节点每秒上报自身的复制偏移量给主节点

总结:

replicationid和offset共同描述了一个"数据集合",

如果两个机器的这两个变量都一样,就可以认为这两个redis机器上存储的数据完全一样

psync运行流程 

psync可以从主节点获取全量数据,还是获取一部分,主要看offset这里的进度

offset=-1,就是获取全量数据

offset写具体的正整数,则是从当前偏移量位置来进行获取

获取所有数据,是最稳妥的,但是比较低效,如果从节点之前以及把主节点这里复制过一部分数据了,就只需要把没复制的数据搞来就可

当然,不是从节点索要哪部分,主节点就一定给哪部分,主节点会自行判定,看当前是否方便给部分数据,不方便就给全量

全量复制

什么时候全量复制

1.首次和主节点进行数据同步

2.主节点不方便进行部分复制


全量复制的流程

流程描述:

  1. 从节点发送psync命令给主节点进⾏数据同步,由于是第⼀次进⾏复制,从节点没有主节点的运⾏ID和复制偏移量,所以发送psync?-1。
  2. 主节点根据命令,解析出要进⾏全量复制,回复+FULLRESYNC响应。
  3. 从节点接收主节点的运⾏信息进⾏保存。
  4. 主节点执⾏bgsave进⾏RDB⽂件的持久化。
  5. 从节点发送RDB⽂件给从节点,从节点保存RDB数据到本地硬盘。
  6. 主节点将从⽣成RDB到接收完成期间执⾏的写命令,写⼊缓冲区中,等从节点保存完RDB⽂件 后,主节点再将缓冲区内的数据补发给从节点,补发的数据仍然按照rdb的⼆进制格式追加写⼊到收 到的rdb⽂件中.保持主从⼀致性。
  7. 从节点清空⾃⾝原有旧数据。
  8. 从节点加载RDB⽂件得到与主节点⼀致的数据。
  9. 如果从节点加载RDB完成之后,并且开启了AOF持久化功能,它会进⾏bgrewrite操作,得到最近的AOF⽂件。 

注意:

  • 在主节点生成rdb文件和传输rdb文件的过程中,还会继续收到很多新的修改操作.新修改的数据,也必须同步给从节点,当从节点收完了主节点发来的rdb之后,主节点就会把这些新修改的操作发送给从节点
  • 如果从节点,已经开启了AOF,在上述的加载数据过程中,从节点就会产生很多的AOF日志,由于当前收到的是大批量的数据,此时产生的AOF日志,整体来说会存在一定的冗余信息,因此要针对AOF日志进行整理

全量复制的无硬盘模式

主节点,进行全量复制的时候,也支持"无硬盘模式":

就是主节点生成的rdb的二进制数据,不直接保存在文件中,而是直接进行网络传输,省下了一系列读硬盘和写硬盘的操作

从节点也是先把收到的rdb数据,写入硬盘中,然后再加载,现在就可以省略这个过程,直接把收到的数据进行加载了

 即使引入了无硬盘模式,整个操作仍然比较耗时,网络传输是不能省的,相比于网络传输,读写硬盘是小事

runid和replid

在一个redis服务器上,两者是都存在的,但是不一样

主节点:

info replication:

info server:

从节点:

run_id是每个节点都不相同的

replid则是具有主从关系的节点,是相同的

官方文档上,明确说了此处使用replicationid


部分复制

什么时候部分复制

从节点之前已经从主节点复制过数据,因为网络抖动或者从节点重启了,从节点需要重新同步数据,看看能不能只同步一部分(大部分数据一致)

但网络抖动,一般都是暂时的,恢复后就可以重新建立联系,此时就需要进行数据的同步

部分复制的流程

psync带有具体的replid和offset

主节点就要根据psync的参数进行判定进行什么复制

流程: 

  1. 当主从节点之间出现⽹络中断时,如果超过repl-timeout时间,主节点会认为从节点故障并终端复制连接。
  2. 主从连接中断期间主节点依然响应命令,但这些复制命令都因⽹络中断⽆法及时发送给从节点,所 以暂时将这些命令滞留在复制积压缓冲区中。
  3. 当主从节点⽹络恢复后,从节点再次连上主节点。
  4. 从节点将之前保存的replicationId和复制偏移量作为psync的参数发送给主节点,请求进⾏部分复制。
  5. 主节点接到psync请求后,进⾏必要的验证。随后根据offset去复制积压缓冲区查找合适的数据, 并响应+CONTINUE给从节点。
  6. 主节点将需要从节点同步的数据发送给从节点,最终完成⼀致性。

积压缓冲区:

是一个内存中的简单队列,会记录最近一段时间修改的数据,总量有限,随着时间的推移,就会把之前的旧数据删除

主节点看这个进度是否在当前的积压缓冲区之内,如果在,就可以进行部分复制,把最近这段时间的数据复制过去即可

如果已经超出积压缓冲区的范围,就得全量复制了


实时复制

主从节点在建⽴复制连接后,主节点会把⾃⼰收到的修改操作,通过tcp⻓连接的⽅式,源源不断的传 输给从节点.从节点就会根据这些请求来同时修改⾃⾝的数据.从⽽保持和主节点数据的⼀致性.

这样的⻓连接,需要通过⼼跳包的⽅式来维护连接状态

心跳包机制

主节点:默认,每隔10s给从节点发送一个ping命令,从节点收到就返回pong

从节点:默认,每隔1s就给主节点发起一个特定的请求,就会上报当前从节点复制数据的进度offset

如果主节点发现从节点通信延迟超过repl-timeout配置的值(默认60秒),则判定从节点下线,断 开复制客⼾端连接。从节点恢复连接后,⼼跳机制继续进⾏


 

从节点晋升为主节点的问题

从节点和主节点断开的情况:

1.slave no one 这个时候,可以晋升

2.主节点挂了 这个时候,从节点不会晋升,必须通过人工干预的方式恢复主节点,脱离掌控

可以通过service redis-server stop模拟一下(简,后续再修改):

1.停止之前的redis服务器

2.删除之前工作目录下,已经生成的AOF文件,或者也可以通过chown命令修改AOF文件所属的用户

3.给从节点创建出新的目录,作为从节点的工作目录,并且修改从节点的配置文件,设定为新的目录为工作目录

4.启动服务器


http://www.ppmy.cn/news/1534060.html

相关文章

【JAVA开源】基于Vue和SpringBoot的校园资料分享平台

本文项目编号 T 059 ,文末自助获取源码 \color{red}{T059,文末自助获取源码} T059,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

游戏如何对抗改包

游戏改包是指通过逆向分析手段及修改工具,来篡改游戏包内正常的设定和规则的行为,游戏包被篡改后,会被植入/剔除模块进行重打包。 本期图文我们将通过实际案例分析游戏改包的原理,并分享游戏如何应对改包问题。 安卓平台常见的改…

django创建一个新的应用

使用 python manage.py startapp myapp 命令可以在你的 Django 项目中创建一个新的应用,名为 myapp。应用是 Django 项目的组成部分,可以帮助你组织代码和功能。执行该命令后,会在你的项目目录下创建一个名为 myapp 的文件夹,包含…

【AIGC】内容创作——AI文字、图像、音频和视频的创作流程

我的主页:2的n次方_ 近年来,生成式人工智能(AIGC,Artificial Intelligence Generated Content)技术迅速发展,彻底改变了内容创作的各个领域。无论是文字、图像、音频,还是视频,A…

JSON字符串转换成Java集合对象

在Java中,将JSON字符串转换成Java集合对象通常涉及到使用JSON处理库,如Jackson或Google的Gson。以下是使用这两个库的示例: 使用Jackson 添加Jackson依赖:如果你使用Maven,可以在pom.xml文件中添加以下依赖&#xff1…

数据结构双向链表和循环链表

目录 一、循环链表二、双向链表三、循环双向链表 一、循环链表 循环链表就是首尾相接的的链表,就是尾节点的指针域指向头节点使整个链表形成一个循环,这就弥补了以前单链表无法在后面某个节点找到前面的节点,可以从任意一个节点找到目标节点…

【API安全】crAPI靶场全解

目录 BOLA Vulnerabilities Challenge 1 - Access details of another user’s vehicle Challenge 2 - Access mechanic reports of other users Broken User Authentication Challenge 3 - Reset the password of a different user Excessive Data Exposure Challenge …

Ps:将画板导出到 PDF

菜单:文件/导出/将画板导出到 PDF Export/Artboards to PDF 将画板导出到 PDF Artboards to PDF命令用于将 Photoshop 的画板导出为 PDF 文件,提供了多种导出选项,可以控制文件的压缩、是否嵌入颜色配置文件、文件命名以及页面顺序等。它适用…