前言
在上篇文章中,我们深入学习了 Redis 的两种不同的持久化方式,Redis 服务器通过持久化,把 Redis 内存持久化到硬盘中,当 Redis 宕机后,可以对 RDB 或 AOF 文件恢复内存中的数据。
但是如果这台服务器的主机坏了,那么这些数据就丢失了吗?
下面,我们来学习下主从复制机制,它可以将主机的数据复制到多台服务器上,从而保证了数据的安全性。
-
那么 Redis 的主从复制它具体都有哪些功能呢?
-
如何配置的主从集群呢?
-
它的底层是如何实现的呢?
这篇文章将帮你搞定这些问题。
一、主从复制概述
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点 (master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。 Master以写为主,Slave 以读为主。
默认情况下,每台Redis服务器都是主节点; 且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
主从复制一般结构可以如下:
- 主从复制的作用主要包括:
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用(集群)基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复 制是Redis高可用的基础。
- 一般来说,要将Redis运用于工程项目中,只使用一台Redis是万万不能的,原因如下:
- 1、从结构上,单个Redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大。
- 2、从容量上,单个Redis服务器内容容量有限,就算一台Redis服务器内容容量为256G,也不能将所有内存用作Redis存储内存。一般来说,单台Redis最大使用内存不应该超过20G
二、主从搭建
拟定三台服务器:
服务器 | 角色 |
---|---|
192.168.81.101 | master |
192.168.81.102 | slave |
192.168.81.103 | slave |
redis 的版本为 6.0.8
2.1 节点配置
redis 的 master 节点和 slave 节点的配置有几点要素:
- 如果是没有密码,则无需配置密码
- 如果是有密码登录,则需要三台 redis 的登录密码一致,然后在从节点配置 主节点的密码。
本次三台服务器均存在密码,因此配置如下:
master 节点:
bind 0.0.0.0
requirepass redis@admin2021 # 登录 redis 的密码
daemonize yes # 后台运行
protected-mode no # 保护模式关闭
从节点配置:
bind 0.0.0.0
requirepass redis@admin2021 # 登录 redis 的密码
daemonize yes # 后台运行
protected-mode no # 保护模式关闭
replicaof 192.168.81.101 6379 # 连接主节点ip 端口
masterauth redis@admin2021 # 配置主节点的密码
分别启动 redis ,通过 info replication 命令查看当前集群情况,发现目前已经配置完好。
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.51.102,port=6379,state=online,offset=458,lag=1
slave1:ip=192.168.51.103,port=6379,state=online,offset=472,lag=0
master_replid:3d0b1a1d07922824b5b29d3f2387aa61d6a32bc1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:472
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:472
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.51.101
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:486
master_link_down_since_seconds:41
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:3d0b1a1d07922824b5b29d3f2387aa61d6a32bc1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:486
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:472
127.0.0.1:6379> set k1 v1
(error) READONLY You can't write against a read only replica.
2.2 集群测试
在从节点上写入数据,默认从节点无法写入
127.0.0.1:6379> set k1 v1
(error) READONLY You can't write against a read only replica.
127.0.0.1:6379> get k1
(nil)
在主节点上写入数据,然后在从节点上查数据,可以。
-
master:
127.0.0.1:6379> set k1 v1 OK
-
slave
127.0.0.1:6379> get k1 "v1"
以上,一主二从集群搭建完毕。
三、主从复制理论
搭建完主从集群,我们来多了解下主从复制的理论内容
3.1 CAP 原理
CAP 理论是分布式存储的理论基石,三个字母是三个单词的缩写
- C : Consistent ,一致性
- A : Availablity,可用性
- P : Partition tolerance ,分区容忍性
分布式系统的节点往往都是分布在不同的机器进行网络隔离的,意味着随时都具备网络断开的风险,一旦断开就被称为 网络分区。
在网络分区时,两个分布式节点无法进行通信,对其中的一个节点进行的修改操作将无法同步到另外一个节点上,所以数据的一致性将无法满足。
除非牺牲可用性,在网络断开的时候不再提供修改数据的服务,直到网络恢复才恢复。
总结:CAP 理论就是当网络分区的时候,一致性和可用性不可兼得。
因此,Redis 的高可以用是必须具备的,所以我们牺牲了 redis 的数据一致性,改为最终一致性,即时主从网络断开,等恢复后,从节点会努力的追赶主节点的数据直到最终保持一致。
3.2 全量复制
Redis 全量复制一般发生在 Slave 初始化阶段,这时 Slave 需要将 Master 上的所有数据都复制一份。具体的步骤如下:
- 1、从服务器连接主服务器,发送 PSYNC 命令 给 master 请求复制数据
- 2、主服务器接收到 PSYNC 命令后,开始在后台进行数据持久化,通过 bgsave 生成最新的 RDB 快照文件,持久化期间,master 会继续接收客户端的请求,会把这些可能修改数据集的请求缓存在内存中
- 3、当持久化进行完毕之后,master 会把这份 RDB 文件数据集发送给 Slave
- 4、slave 会把接收到的数据进行持久化生成 RDB,然后再加载到内存中
- 5、master 再将之前缓存在内存中的命令发送给 slave
- 6、当 master 与 slave 之间的连接由于某些原因而断开时 ,slave 能够自动重连 master
- 7、如果 master 收到了多个 slave 并发连接请求,它只会进行一次持久化,而不是一个连接一次,再把这份持久化的数据发送给多个并发连接的 slave
通过全量复制的过程可以看出,全量复制是非常重型的操作:
- 1、主节点通过 bgsave 命令 fork 子进程进行 RDB 持久化,该过程是非常消耗 CPU、内存、硬盘 IO 的
- 2、主节点通过网络将 RDB 文件发送给从节点,对主从节点的带宽都会带来消耗
- 3、从节点清空老数据,载入新 RDB 文件的过程是阻塞的,无法响应客户端的命令。
3.3 部分复制
之所以要加入部分复制,是因为全量复制会产生很多问题,比如像上面的时间开销大、无法隔离等问题, Redis 希望能够在 master 出现抖动(相当于断开连接)的时候,可以有一些机制将复制的损失降低到最低
部分复制主要是Redis针对全量复制的过高开销做出的一种优化措施,使用psync{runId}{offset}命令实现。 当从节点(slave) 正在复制主节点(master) 时, 如果出现网络闪断或者命令丢失等异常情况时, 从节点会向主节点要求补发丢失的命令数据, 如果主节点的复制积压缓冲区内存在这部分数据则直接发送给从节点, 这样就可以保持主从节点复制的一致性。 补发的这部分数据一般远远小于全量数据, 所以开销很小。
实现原理:
当master和slave断开连接时,master会将期间所做的操作记录到复制缓存区当中(可以看成是一个队列,其大小默认1M)。待slave重连后,slave会向master发送psync命令并传入offset和runId,这时候,如果master发现slave传输的偏移量的值,在缓存区队列范围中,就会将从offset开始到队列结束的数据传给slave,从而达到同步,降低了使用全量复制的开销。
3.4 主从复制的优缺点
3.4.1 优点
- 1、master 能自动将数据同步到 slave,可以进行读写分离,分担 master 的读压力
- 2、master、slave 之间的同步是以非阻塞的方式进行的,同步期间,客户端仍然可以提交查询或更新请求
3.4.2 缺点
- 1、不具备自动容错与恢复功能
- 2、master 宕机,如果宕机前数据没有同步完,则切换 IP 后会存在数据不一致的问题
- 3、难以支持在线扩容
四、总结
本文介绍了 Redis 一主而从的集群搭建,然后讲解了下主从复制理论,主从复制的搭建还是比较简单的,但是它的理论还真的不是那么容易理解的,这边也只是浅尝辄止了,目前了解这些就够了,不必深挖下去,如果后续有深入理解了,再更文探究i。
我是潇雷,欢迎阅读!