Redis-主从复制

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

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

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

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

在分布式系统中,希望有多个服务器来部署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.启动服务器

Redis主从复制是一种常用的数据复制和高可用性方案,它通过将一个Redis实例(主节点)的数据复制到其他Redis实例(从节点)来实现数据的备份和读写分离。下面是Redis配置主从复制的步骤: 1. 配置主节点: - 打开主节点的配置文件redis.conf。 - 将配置项`bind`设置为主节点的IP地址。 - 将配置项`port`设置为主节点的端口号。 - 将配置项`daemonize`设置为yes,表示以守护进程方式运行。 - 将配置项`logfile`设置为日志文件路径。 - 将配置项`dir`设置为持久化文件的存储路径。 - 将配置项`appendonly`设置为yes,开启AOF持久化方式(可选)。 - 保存并关闭配置文件。 2. 启动主节点: - 打开终端,进入Redis安装目录。 - 执行命令`redis-server redis.conf`启动主节点。 3. 配置从节点: - 复制主节点的配置文件redis.conf到从节点。 - 打开从节点的配置文件redis.conf。 - 将配置项`bind`设置为从节点的IP地址。 - 将配置项`port`设置为从节点的端口号。 - 将配置项`daemonize`设置为yes,表示以守护进程方式运行。 - 将配置项`logfile`设置为日志文件路径。 - 将配置项`dir`设置为持久化文件的存储路径。 - 将配置项`appendonly`设置为yes,开启AOF持久化方式(可选)。 - 将配置项`replicaof`设置为主节点的IP地址和端口号,格式为`replicaof <masterip> <masterport>`。 - 保存并关闭配置文件。 4. 启动从节点: - 打开终端,进入Redis安装目录。 - 执行命令`redis-server redis.conf`启动从节点。 至此,Redis主从复制配置完成。主节点会将数据同步到从节点,从节点可以处理读请求,提高系统的读取性能和可用性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值