3. 主从复制
3.1 引入
分布式系统中,如果某个服务只有一个节点(即只有一个物理服务器,部署该程序),就涉及到了 "单点问题"
- 可用性问题:该节点挂了,服务就完全没了
- 性能/支持的并发量有限。
为此,往往要有多台服务器来部署程序,构成一个集群,让这个集群来给整个分布式系统提高服务。
将 redis 部署到多台服务器上,有以下几种部署方式:
- 主从结构
- 主从 + 哨兵
- 集群模式
本文就是针对 主从 方式 进行讲述的文章。
主从模式:即在若干个 redis 节点中,分为 主节点 和 从节点两种; 主节点可进行读写操作,从节点只能进行读操作,不能修改数据;且从节点的数据从主节点中复制而来,随主节点中数据的变化而变化。一般情况下,主节点只有一个,因为如果有多个的话,出现了数据不同,那应该听谁的?
主从模式,主要是针对 "读操作" 并发量,可用性的提高。主从节点数据相同,从哪个都能读,并发量就上去了;如果是节点挂了,从其它节点读的效果一样,不会像单个节点时直接无法提供服务。若主节点挂了,虽然有影响------不能写数据了,但还能读,这样可用性就大大提高了。
3.2 配置 redis 主从结构
由于只有一台云服务器,所以这里的多个 redis-server 就运行在同一个云服务器上了。本次为 一个主节点,两个从节点。
3.2.1 配置方法
redis 中我们通过 slaveof 来完成主从结构的配置( 注:{ } 不用写上去) 。
- 直接在启动后通过
slaveof {主节点 host} {主节点 port}进行配置。 - 在启动时,通过加上
bash
-slaveof {主节点 host} {主节点 port}
进行配置
- 在配置文件中添加
slaveof {主节点 host} {主节点 port},启动 reids 生效。
此外,由于默认端口为 6379,所以两个新的从节点的端口,就不能用 6379了,可以在 配置文件中改动,也可以在 redis-server 命令启动时使用 -p 命令指定。
3.2.2 conf 文件拷贝 及 配置
这里拷贝两份 redis.conf 文件,用作从节点的配置文件,进行启动。
bash
mkdir slave1
mkdir slave2
先造两个文件,分别存储两个从节点的配置文件。
通过 cp 命令,拷贝过来(接下来,只展示一个的操作,另一个除端口不同外,其余操作相同)

进行编辑:
更改端口(本次主节点用 6379 端口,从节点用 6380,6381 端口)

添加 slaveof 127.0.0.1 6379 ,这里是添加到了 配置文件的最后,想添加到哪里都可以。

之后,通过 redis-server slave.conf 就可以启动,该子节点了。另一个节点同理。
注:如果修改配置文件前,服务已经启动了,那么修改完成后,要记得重启服务
3.3 有关信息,字段讲解
通过 nestat -anp | grep redis-server 命令,可以看到如下几行信息。

同色圈里的是一组(主节点和从节点),这里面的 ip + 端口,表示的是从节点和主节点之间的 tcp 连接。因为是部署在同一台机器上的所以两边的信息都能看到,即一组。如果是正常在不同主机上,只能看到一组中的其中一行。
主从节点间通过 TCP 交互,TCP 内部支持了 nagle 算法(默认开启的)
开启了,就会增加tcp 传输延迟,节省带宽;
关了,就会减少tcp 传输延迟,增加带宽;
在配置文件
repl_disable_tcp_nodelay选项,进行配置是否关闭该算法。
在主节点上执行
bash
info replication
命令,观察到如下信息:

- role:表明该节点是主节点还是从节点,主为 master,从为 slave
- connected_slaves: 从节点个数
- slave:从节点的信息,如 ip ,port,offset(复制偏移量),lag(从节点相对主节点的延迟,即从节点的复制偏移量与主节点的当前数据位置之间的差值)
- master_replid: 主节点的身份标识,从节点中的 master_replid 保存的即为 主节点的 master_replid。
- master_replid2:一般用不上,当主节点挂了,从节点中推选了新的头节点,这个 replid2 就是保存前一个主节点的 replid 的,以便后面恢复。
- master_repl_offset:主节点的数据量
- second_repl_offset:从节点的复制量
- repl_×××:这四个是积压缓冲区的相关信息,是部分同步 机制的支撑。
3.4 效果展示
当前 主从节点 已经有了相同的数据(启动的时候,就复制了)


改变 主节点中的数据,观察到从节点数据发生相同变化


尝试用 从节点操作数据,观察到程序出现错误

从节点通过 slaveof no one 命令断开现有的主从关系,已有数据不会丢失,此处是通过命令断开连接,并不影响配置文件,再次启动时还是按配置文件的内容进行。

解除从属关系后,还可以让该节点从属剩下的那个从节点,但是从节点并不会因为有了从节点而化身主节点,它依旧不能写。
3.5 拓扑结构
即 节点间的组织方式。

写数据太多,会给主节点造成一定压力。可以关闭主节点的 AOF,只在从节点上开启 AOF。 但是这存在缺陷,如果主节点挂了,他没有 AOF 文件,重启了会丢数据,进一步同步后,从节点上的数据就被删了。
改进方法:主节点挂了,让主节点从从节点处获取 AOF 文件。

这种结构,主节点数据变化后,要将改变的数据同步给所有从节点,但是随着从节点数量的增多,传的次数就多了,虽然同步延时短,但对网卡带宽要求就高了。

这种让从节点再有从节点的结构,对网卡带宽要求低了,但同步延时要不前一种长。
3.6 安全性
对于重要数据节点,主节点通过设置 requirepass 参数进行密码校验,所有客户端访问必须使用 auth 命令校验。
主从节点间的复制连接是通过一个特殊标识的客户端来完成,因此从节点的 masterauth 参数 配置应与 主节点密码一致,这样从节点从能连接到主节点并发起复制流程
3.7 复制流程

- 保存主节点信息:保存主节点 ip ,端口
- 主从建立连接:TCP 的连接(三次握手)
- 发送 ping 命令:验证主节点是否能正常工作
- 权限校验:redis 主节点开启了密码则进行
- 同步数据集 & 命令持续复制:复制数据的操作
tcp 三次握手是系统层面,验证通信双方是否都能正常读写数据
ping 命令则应用程序层面,是否正常