一、什么是Redis主从复制

1、主从复制的架构:

Redis Replication是一种 master-slave 模式的复制机制,这种机制使得 slave 节点可以成为与 master 节点完全相同的副本,可以采用一主多从或者级联结构。架构如下:

![v2-5f69e95146ecdabdb331d0333cd5bcf8_1440w](https://zmzycc.top/upload/2023/03/v2-5f69e95146ecdabdb331d0333cd5bcf8_1440w.webp)

主从复制的配置要点:

(1)配从库不配主,从库配置:slaveof 主库IP 主库端口

(2)查看redis的配置信息:info replication

2、Redis为什么需要主从复制?

使用Redis主从复制的原因主要是单台Redis节点存在以下的局限性:

(1)Redis虽然读写的速度都很快,单节点的Redis能够支撑QPS大概在5w左右,如果上千万的用户访问,Redis就承载不了,成为了高并发的瓶颈。

(2)单节点的Redis不能保证高可用,当Redis因为某些原因意外宕机时,会导致缓存不可用

(3)CPU的利用率上,单台Redis实例只能利用单个核心,这单个核心在面临海量数据的存取和管理工作时压力会非常大。

3、主从复制的好处:

(1)数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

(2)故障恢复:如果master宕掉了,使用哨兵模式,可以提升一个 slave 作为新的 master,进而实现故障转移,实现高可用

(3)负载均衡:可以轻易地实现横向扩展,实现读写分离,一个 master 用于写,多个 slave 用于分摊读的压力,从而实现高并发;

4、主从复制的缺点:

由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave服务器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重

环境和版本

准备三台Linux服务器centos7系统

|hostname|ip地址|备注|

|-------|-------|-------|

|k8s-master|192.168.0.135|master节点|

|k8s-nade1|192.168.0.136|slave1|

|k8s-nade2|192.168.0.137|slave2|

三台都安装[redis5.0安装步骤](https://zmzycc.top/archives/redis-yuan-ma-an-zhuang)

修改两台从服务器的redis.conf,添加如下配置

vim /path/redis.conf

replicaof 192.168.0.135 6379 #主要是这句,其他的参数可自己优化,以下是我的配置文件,仅供参考

```

#修改redis.conf

bind 192.168.XX.XX #绑定本机ip地址

port 6739 # 绑定端口号

daemonize yes #用来指定redis是否要用守护进程的方式启动,默认为no

logfile /var/log/redis_6379.log #redis日志文件

pidfile /var/run/redis_6379.pid#当Redis以守护进程方式运行时,即使该项没有配置,Redis也会默认把pid写入/var/run/redis.pid文件;而当Redis不是以守护进程凡是运行时,若该项没有配置,则redis不会创建pid文件。创建pid文件是尝试性的动作,即使创建写入失败,redis依然可以启动运行

replicaof 192.168.0.135 6379 #配置文件中设置主节点的方法,redis主从复制这个地方只配置从库,不用配置主库!注意:主库不需要这个配置

requirepass 123456 #本地redis密码

masterauth 123456 #主节点redis密码 注意:主节点也要配置,后边哨兵容灾切换用到

```

为了后边的哨兵配置,切记一定要把主节点和从节点的密码设置为一样的, 因为sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同

分别重启启动3台redis服务,redis服务启动完毕之后,执行info replication命令查看当前主从配置

从节点:

```

redis-cli -p 6379 -h 192.168.0.136

127.0.0.1:6379> info replication

# Replication

role:slave # 当前角色是从机

master_host:192.168.0.135 #主机信息

master_port:6379

master_link_status:down

master_last_io_seconds_ago:-1

master_sync_in_progress:0

slave_repl_offset:1

master_link_down_since_seconds:1680008069

slave_priority:100

slave_read_only:1

connected_slaves:0

master_replid:647e9fe3835d560f53d19587a1cc1a1fc6315ea1

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:0

second_repl_offset:-1

repl_backlog_active:0

repl_backlog_size:1048576

repl_backlog_first_byte_offset:0

repl_backlog_histlen:0

```

主节点:

```

redis-cli -p 6379 -h 192.168.0.135

127.0.0.1:6379> info replication

# Replication

role:master

connected_slaves:2 #主节点下有两个从机

slave0:ip=192.168.0.138,port=6379,state=online,offset=1764,lag=1 #从机的ip和端口

slave1:ip=192.168.0.136,port=6379,state=online,offset=1764,lag=0

master_replid:e1f0b8dab7c5154b951dbb67c76233ed27db0e76

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:1764

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:1764

```

测试主从:

1、主节点

```

192.168.0.135:6379> set a 2

OK

```

2、从节点

```

192.168.0.136:6379> keys *

"a"

192.168.0.136:6379> get a

"2"

```

注意:

1、主机可以写,从机不能写,只能读。主机中的所有数据都会保存到从机中去。

2、主机断开连接,从机依旧连接到主机的,但是没有写操作,这个时候,主机如果回来了,从机依旧可以直接获取到主机写的信息!

3、如果是使用命令行,来配置的主从,这个时候如果重启了,就会变回主机!只要变为从机,立马就会从主机中获取值!

哨兵(Sentinel)模式

上文中介绍了Redis主从复制模式下的集群策略,当Master宕机后,不会从Slave节点中选举出Master,所以该集群丧失了写的能力,我们只能人工去将Slave节点晋升为Master节点,同时要通知应用方更新Master节点的IP地址,对于这种故障处理的方式在现在的环境下通常是不可接受的。所以从Redis2.8开始,Redis正式提供了哨兵模式的架构(故障转移),来解决这个问题。

哨兵模式的工作特点:

哨兵模式是建立在主从模式的基础上,当Master节点宕机之后,哨兵会从Slave节点中选择一个节点作为Master,并修改它们的配置文件,使其他的Slave指向新的Master。

当原先宕机的Master节点重新启动时,他将不再是Master,而是作为新Master的一个Slave节点存在。

哨兵节点是一个特殊的Redis节点(不存储数据),本质上也是一个进程,所以也有挂掉的可能,所以哨兵也存在集群模式。

哨兵模式工作原理:

每隔10秒,每个哨兵节点会向Master和Slave节点发送info命令获取最新的拓扑结构。

每隔1秒,每个哨兵节点会向Master和Slave节点还有其它哨兵节点发送ping命令做心跳检测,看看是否存在不可达的节点。

主观下线,如果某个哨兵向一个节点发出的心跳检测没有得到响应,那么该哨兵认为该节点已经下线。

客观下线,当哨兵主观下线的节点是主节点时,哨兵会向其他的哨兵询问对主节点的判断,当下线判断超过一定个数时,那么哨兵会认为主节点确实已经下线,那么会对主节点进行客观下线的判定。

故障转移,当Master节点客观下线时,哨兵会从Slave节点中选择一个节点作为Master节点,选择规则是选择与主节点复制相似度最高的节点,选择完成后会将其余的Slave节点指向新的Master节点,并监控原来的Master节点,当它回复后作为新Master节点的Slave存在,并且同步新Master节点的数据。

选举领导者哨兵节点:当主节点被判断客观下线以后,各个哨兵节点会进行协商,选举出一个领导者哨兵节点,并由该领导者节点对其进行故障转移操作。

当使用sentinel模式的时候,客户端不用直接连接Redis,而是连接哨兵的ip和port,由哨兵来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,哨兵就会感知并将新的master节点提供给使用者。

搭建哨兵

在每台服务器上部署一个哨兵,配置方式如下:

#在redis安装目录下使用vi命令创建哨兵配置文件

vi sentinel.conf

sentinel.conf内容:

```

#端口默认为26379。

port 26379

#关闭保护模式,可以外部访问。

protected-mode no

#设置为后台启动。

daemonize yes

#日志文件。

logfile ./sentinel.log

#指定服务器IP地址和端口,并且指定当有2台哨兵认为主机挂了,则对主机进行容灾切换。 注意:三台哨兵这里的ip配置均为主节点ip 和端口

sentinel monitor mymaster 192.168.0.135 6379 2

#当在Redis实例中开启了requirepass,这里就需要提供密码。

sentinel auth-pass mymaster 123456

#这里设置了主机多少秒无响应,则认为挂了。

sentinel down-after-milliseconds mymaster 3000

#主备切换时,最多有多少个slave同时对新的master进行同步,这里设置为默认的snetinel parallel-syncs mymaster 1

#故障转移的超时时间,这里设置为三分钟。

sentinel failover-timeout mymaster 180000

```

分别启动三台服务器上的哨兵

```

redis-sentinel /path/sentinel.conf

```

```

[root@localhost bin]# redis-cli -p 26379

#查看哨兵信息

127.0.0.1:26379> info sentinel

# Sentinel

sentinel_masters:1

sentinel_tilt:0

sentinel_running_scripts:0

sentinel_scripts_queue_length:0

sentinel_simulate_failure_flags:0

#哨兵已经监听到主节点IP端口和运行状态,并且有2个从节点,3个哨兵。

master0:name=mymaster,status=ok,address=192.168.0.135:6379,slaves=2,sentinels=3

```

redis容灾切换

1.通过模拟主节点宕机,来查看哨兵的作用:

```

#连接redis客户端

[root@localhost bin]# redis-cli -p 6379 -h 192.168.0.135

#验证密码

192.168.0.135:6379> auth 123456

OK

#关闭redis服务

192.168.10.6:6379> shutdown

#退出客户端

not connected> exit

```

2.关闭主节点之后,我们去查看哨兵日志:

```

[root@localhost bin]# cat sentinel.log

19673:X 28 Mar 2023 09:43:51.871 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo

19673:X 28 Mar 2023 09:43:51.871 # Redis version=5.0.0, bits=64, commit=00000000, modified=0, pid=19673, just started

19673:X 28 Mar 2023 09:43:51.871 # Configuration loaded

19674:X 28 Mar 2023 09:43:51.873 * Increased maximum number of open files to 10032 (it was originally set to 1024).

19674:X 28 Mar 2023 09:43:51.873 * Running mode=sentinel, port=26379.

19674:X 28 Mar 2023 09:43:51.873 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

19674:X 28 Mar 2023 09:43:51.880 # Sentinel ID is 0ec78f7f0f620fecf35c16f8c610f836c025423e

19674:X 28 Mar 2023 09:43:51.880 # +monitor master mymaster 192.168.0.135 6379 quorum 2

19674:X 28 Mar 2023 09:43:51.881 * +slave slave 192.168.0.136:6379 192.168.0.136 6379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:43:51.884 * +slave slave 192.168.0.138:6379 192.168.0.138 6379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:43:52.454 * +sentinel sentinel 46028d7042592c08f2f7fe6258dffb21f235a5e4 192.168.0.138 26379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:44:20.658 * +sentinel sentinel bf5e7792ea1fb03ba60554d30db17324105127cf 192.168.0.136 26379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:40.877 # +sdown master mymaster 192.168.0.135 6379 #这里发现主节点宕机

19674:X 28 Mar 2023 09:48:40.954 # +odown master mymaster 192.168.0.135 6379 #quorum 2/2

19674:X 28 Mar 2023 09:48:40.954 # +new-epoch 1

19674:X 28 Mar 2023 09:48:40.954 # +try-failover master mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:40.957 # +vote-for-leader 0ec78f7f0f620fecf35c16f8c610f836c025423e 1

19674:X 28 Mar 2023 09:48:40.960 # 46028d7042592c08f2f7fe6258dffb21f235a5e4 voted for 0ec78f7f0f620fecf35c16f8c610f836c025423e 1

19674:X 28 Mar 2023 09:48:40.977 # bf5e7792ea1fb03ba60554d30db17324105127cf voted for 0ec78f7f0f620fecf35c16f8c610f836c025423e 1

19674:X 28 Mar 2023 09:48:41.019 # +elected-leader master mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:41.019 # +failover-state-select-slave master mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:41.078 # +selected-slave slave 192.168.0.136:6379 192.168.0.136 6379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:41.078 * +failover-state-send-slaveof-noone slave 192.168.0.136:6379 192.168.0.136 6379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:41.130 * +failover-state-wait-promotion slave 192.168.0.136:6379 192.168.0.136 6379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:42.006 # +promoted-slave slave 192.168.0.136:6379 192.168.0.136 6379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:42.006 # +failover-state-reconf-slaves master mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:42.068 * +slave-reconf-sent slave 192.168.0.138:6379 192.168.0.138 6379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:43.046 * +slave-reconf-inprog slave 192.168.0.138:6379 192.168.0.138 6379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:43.046 * +slave-reconf-done slave 192.168.0.138:6379 192.168.0.138 6379 @ mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:43.099 # -odown master mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:43.099 # +failover-end master mymaster 192.168.0.135 6379

19674:X 28 Mar 2023 09:48:43.099 # +switch-master mymaster 192.168.0.135 6379 192.168.0.136 6379 #通过投票选举0.136为新的主节点

19674:X 28 Mar 2023 09:48:43.099 * +slave slave 192.168.0.138:6379 192.168.0.138 6379 @ mymaster 192.168.0.136 6379

19674:X 28 Mar 2023 09:48:43.099 * +slave slave 192.168.0.135:6379 192.168.0.135 6379 @ mymaster 192.168.0.136 6379

19674:X 28 Mar 2023 09:48:46.158 # +sdown slave 192.168.0.135:6379 192.168.0.135 6379 @ mymaster 192.168.0.136 6379

```

下面我们去0.136下查看哨兵主从切换是否成功

```

[root@k8s-node1 bin]# ./redis-cli

127.0.0.1:6379> auth 123456

OK

127.0.0.1:6379> info replication

# Replication

role:master #变成主节点了

connected_slaves:1 # 下面的从机个数为1

slave0:ip=192.168.0.138,port=6379,state=online,offset=145590,lag=1

master_replid:0349c3a7470f13008e0490332bec54460601211d

master_replid2:cc2776c34e0b277cb020f35d413c43218189fe88

master_repl_offset:145731

second_repl_offset:61324

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:145731

```

重新连接挂掉的主节点

```

redis-server /path/redis.conf

[root@localhost bin]# ./redis-cli

127.0.0.1:6379> auth 123456

OK

127.0.0.1:6379> info replication

# Replication

role:slave #主节点连接回来之后自动变成了从节点,并且成功连上了主机

master_host:192.168.0.136 #主机ip

master_port:6379

master_link_status:down

master_last_io_seconds_ago:-1

master_sync_in_progress:0

slave_repl_offset:1

master_link_down_since_seconds:1680011860

slave_priority:100

slave_read_only:1

connected_slaves:0

master_replid:8e9192423814c17b6af5eb885e23642b40ed65c0

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:0

second_repl_offset:-1

repl_backlog_active:0

repl_backlog_size:1048576

repl_backlog_first_byte_offset:0

repl_backlog_histlen:0

```

再去主节点确认一下

```

127.0.0.1:6379> info replication

# Replication

role:master

connected_slaves:2 #两个从节点

slave0:ip=192.168.0.138,port=6379,state=online,offset=256815,lag=0

slave1:ip=192.168.0.135,port=6379,state=online,offset=256815,lag=0

master_replid:0349c3a7470f13008e0490332bec54460601211d

master_replid2:cc2776c34e0b277cb020f35d413c43218189fe88

master_repl_offset:256815

second_repl_offset:61324

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:256815

```

优点

哨兵集群,基于主从复制模式,所有的主从配置优点,它全有

主从可以切换,故障可以转移,系统的可用性就会更好

哨兵模式就是主从模式的升级,手动到自动,更加健壮!