Redis主从复制

分布式系统的单点问题

1.可用性问题,如果这个机器挂了,意味着服务就中断了

2.性能/支持的并发量也是比较有限的

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

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

Redis的部署方式

在分布式系统中,使用多个服务器部署redis的方式

1.主从模式

2.主从+哨兵模式

3.集群模式

1.主从模式

在redis的若干个节点中,有的是"主"节点,有的是"从"节点。

从节点的数据随主节点的变化而变化,从节点的数据与主节点保持一致

在redis主从模式中,从节点上的数据,不允许修改,只允许读取

主从模式,主要是针对"读操作"进行并发量&可用性的提高,而写操作还是依赖与主节点,并且主节点不能搞多个

如果从节点挂了并没有什么影响,如果主节点挂了,还是有一定影响的

配置Redis主从结构

配置Redis主从结构,首先需要启动多个redis服务

使用一台服务器配置多个redis服务,需要运行多个redis-server进程

本来redis默认的端口号是6379,运行多个redis进程就需要修改redis的端口号

如何执行redis-server的端口号?

1.可以在启动程序的时候,通过命令行来指定端口号,--port选项

2.也可以直接在配置文件中,来设定端口

此处搞一个主节点,两个从节点,采用修改配置文件的方式

首先使用cp命令复制两份配置文件

然后修改端口号port为6380,和6381,并且确认daemonize 为yes

使用redis-server ./slave1.conf (配置文件的路径)启动服务

当前这三个节点并没有构成主从结构,下面进行主从结构的配置

采用第一种方式,在redis配置文件的最下面加上

修改配置文件以后,需要重启服务才能生效

使用redis-server命令启动的服务,使用kill -9 进程 的方式关闭

使用service redis-server start这种方式启动,就必须使用service redis-server stop这个命令停止,使用kill会触发redis的保护进程

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

使用info replication命令查看当前redis服务的主从结构

断开主从结构

在客户端执行 slaveof no one 就可以断开连接

原有的数据不会进行删除,但是后续如果主节点针对数据进行了修改,从节点就无法感受到了

与其他节点建立连接

slaveof host post 认其他节点为主节点

这里的slaveof都是临时性的,重新启动redis服务器还是会按照配置文件的主从结构

传输延迟

主节点与从节点间通过网络来传输(TCP)

TCP内部支持了nagle算法(默认开启的)针对小的tcp数据报,进行合并,减少了包的个数

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

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

repl-disable-tcp-nodelay 这个选项可以用于主从通信过程中,关闭tcp的nagle算法~~

从节点更快速的和主节点进行同步

拓扑结构

一主一从结构

拓扑结构:若干个节点之间,按照啥样的方式来进行组织连接

如果写数据请求过多,主节点压力就会过大

可以通过关闭主节点AOF来降低主节点的压力

但是,这种方法一旦主节点挂了,不能让它自动重启(如果重启,主节点上的数据就会没了,主从复制,从节点上的数据也会跟着没了)

改进办法,主节点挂了之后,需要让主节点从从节点这里获取AOF的文件之后再重启

一主多从结构

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

树形主从结构

主节点就不需要那么高的网络带宽了

一旦数据进行了修改,同步的延迟是要比刚才更长的

主从复制原理

redis提供psync命令,完成数据同步的过程

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

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

psync replicationid offset

replication id 是主节点启动的时候就会生成,从节点晋升成主节点的时候,也会生成(同一个节点重启后replication id也是不相同的)

从节点与主节点建立复制关系之后,就会从主节点这边获取replicationid

info replicationid获取当前的replicationid

replid就是replicationid

replid2一般用不上,从节点与主节点建立连接之后,从节点会记录主节点的replicationid,如果发生网络抖动,从节点与主节点断开连接,自己成为主节点,会生成自己的replicationid,但从节点会用replid2保存原来主节点replicationid,以便根据replid2重新回到原来主节点的怀抱

replicationid和offset共同描述了一个数据集合,如果两台机器,如果applicationid和offset都一样就可以认为这两台机器的redis数据也一样

offset偏移量

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

主节点的偏移量:主节点上对于收到的修改操作的命令,这些命令都会占用几个字节,主节点讲这些字节进行累加

从节点的偏移量:描述了数据同步的进度

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

psync数据复制

psync这里可以进行全量复制也可以获取一部分数据

主要看offset的进度

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

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

获取所有数据最稳妥,但是最为低效,如果从节点之前已经从主节点这里复制过一部分数据了,就只需要把新的之前没复制过的数据传过来即可,但是并不是从节点想复制部分就复制部分,主节点会自行判断方不方便给,如果不方便给,就只能进行全量复制

全量复制

1)从节点发送psync命令给主节点进行数据同步,由于是第一次进行复制,从节点没有主节点的运行ID和复制偏移量,所以发送psync ? -1.

2)主节点根据命令,解析出要进行全量复制,回复+FULLRESYNC响应

3)从节点接受主节点的运行信息进行保存

4)主节点执行bgsave进行RDB文件的持久化(rdb是二进制文件比较节省空间,不能使用已有的rdb文件,而是必须重新生成一下,已有的和当前最新的数据存在较大差异)

5)主节点发送RDB文件给从节点,从节点保存RDB数据到本地硬盘

6)主节点从生成RDB到接收完成期间执行的写命令, 写入缓冲区中,等从节点保存完RDB文件后,主节点再将缓冲区内的数据补发给从节点,补发的数据仍然按照rdb的二进制格式追加写到收到的rdb文件中,保持主从的一致性

7)从节点清空自身原有的旧数据

8)从节点加载RDB文件得到与主节点一致的数据

9)如果从节点加载RDB完成之后,并且开启了AOF的持久化功能,它会进行bgrewrite操作,得到最近的AOF文件

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

主节点生成的rdb二进制文件,不是直接保存到文件中了,而是直接进行网络传输(省去了一系列的读写硬盘的操作)

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

即使引入了无硬盘模式,仍然整个操作是重量级的,比较耗时,网络传输是没法省的

部分复制

如果在全量复制的时候出现网络抖动,主节点这边最近修改的数据可能无法及时同步过来了,从节点也可能因为感受不到主节点自己成为主节点了。

网络抖动一般是暂时的,过一会就恢复,此时从节点就可以和主节点重新建立联系

当从节点和主节点重新建立连接之后,就需要进行数据的同步

psync带有具体的replid和offset的值

主节点就会根据psync的值进行判定,是全量复制还是部分复制

1)当主从节点之间出现网络中断的时,如果超过repl-timeout时间,主节点会认为从节点故障并中断复制连接。

2)主从连接中断期间主节点依然响应命令,但这些复制命令都因网络中断无法同步给从节点,所以暂时将这些命令滞留在复制积压缓冲区中。

3)当主从节点网络恢复后,从节点再次连上主节点。

4)从节点将之前保存的replicationid和复制偏移量作为psync的参数发送给主节点,请求进行部分复制。

5)主节点接到psync请求后,进行必要的验证,随后根据offset去复制积压缓冲区查找合适的数据,并响应+CONTINUE给从节点。

6)主节点将需要从节点同步的数据发给从节点,最终完成一致性。

info replication命令可以查看消息缓冲区的参数

消息缓冲区就是内存中的简单队列,会记录最近一段时间修改的数据,总量有限,随着时间的推移,就会把之前的旧数据逐渐删掉

对于从节点重连之后发送的psync命令,主节点会根据replicationid判断这个从节点以前是不是与自己相连,然后判断从节点发送的offset是否在消息缓冲区之内,如果在消息缓冲区之内,就进行部分复制,如果不在,就只能进行全量复制了。

实时复制

主从节点建立复制连接以后,主节点会将自己收到的修改操作,通过tcp长连接的方式,源源不断的传输给从节点,从节点就会根据这些请求来同时修改自身的数据,从而保证主从节点的数据一致性

这里的tcp长连接通过心跳包的方式来维护连接状态(应用层自己实现的心跳包机制,而不是TCP自带的)

1)主节点默认每隔10秒对从节点发送ping命令,从节点响应pong,(默认通信延迟超过repl-timeout)配置的值(默认60秒),则判定从节点下线,断开复制客户端的连接。

2)从节点默认每隔1秒向主节点发送replconfack{offset}命令,给主节点上报自身的复制偏移量

相关推荐
Porunarufu2 小时前
JAVA·顺序逻辑控制
java·开发语言
穿背心的程序猿2 小时前
推荐一款集成AI功能的数据库管理工具
数据库
1710orange3 小时前
java设计模式:适配器模式
java·设计模式·适配器模式
柱子jason3 小时前
使用IOT-Tree消息流【标签读写】功能详细说明
数据库·物联网·时序数据库·influxdb·iot-tree
RainbowSea3 小时前
9. Spring AI 当中对应 MCP 的操作
java·spring·ai编程
RainbowSea3 小时前
10. Spring AI + RAG
java·spring·ai编程
寻星探路4 小时前
Java EE初阶启程记05---线程安全
java·开发语言·java-ee
Moshow郑锴4 小时前
Java 中配置 Selenium UI 自动化测试 并生成 Cucumber 报告
java·selenium·测试工具
nlog3n4 小时前
分布式短链接系统设计方案
java·分布式