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

主从复制的配置要点:
(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
```
优点
哨兵集群,基于主从复制模式,所有的主从配置优点,它全有
主从可以切换,故障可以转移,系统的可用性就会更好
哨兵模式就是主从模式的升级,手动到自动,更加健壮!