Redis-主从复制-哨兵模式
Redis-主从复制-哨兵模式
- 一、主从复制
- 1.1 修改配置文件
- 1.2 主从状态验证
- 1.3 主从数据状态测试
- 1.4 主从模式存在的问题
- 二、哨兵模式
- 2.1 配置哨兵
- 2.2 测试
一、主从复制
Redis作为缓存读写
当项目非常大,一台Redis无法满足需要时,怎么办?
-> 增加服务器
多台服务器的问题? => 3台
- 3台服务器,每台启动一个服务
- 1台服务器,在服务器上启动3个服务(使用不同的端口)
Redis主从复制(读写分离)
- 实现读写分离,提高了Redis性能
- 容灾恢复
- 数据备份
- 水平扩容支撑高并发
主Redis端口6379
从Redis端口6389
从Redis端口6399
1.1 修改配置文件
主配置文件 :/etc/redis.conf
从服务器配置: /etc/redis6389.conf
# 开启Redis后台启动
daemonize yes
# 注释该行
bind 127.0.0.1
# 监听的端口
port 6389
# 允许外界连接
protected-mode no
# 为Redis设置密码
requirepass 12345678
# 指定当前工作目录
dir /redisdata/redis6389
# rdb配置
dbfilename dump.rdb
# 是否开启aof(自定)
appendonly no
# 日志级别
loglevel notice
# Redis日志
logfile "/redisdata/6389.log"
# pid文件位置
pidfile /var/run/redis_6389.pid
# !!指定主的密码
masterauth 12345678
# !!注册从机(告诉主,自己是个从)
replicaof 127.0.0.1 6379
从配置文件:/etc/redis6399.conf
daemonize yes
port 6399
protected-mode no
requirepass 12345678
dir /redisdata/redis6399
dbfilename dump.rdb
appendonly no
loglevel notice
logfile "/redisdata/6399.log"
pidfile /var/run/redis_6399.pid
masterauth 12345678
replicaof 127.0.0.1 6379
创建需要的目录
mkdir -p /redisdata/redis6399
mkdir -p /redisdata/redis6389
启动服务
-
先启动主
redis-server /etc/redis.conf -
再启动从
redis-server /etc/redis6399.conf
redis-server /etc/redis6389.conf -
检查服务状态
[root@db ~]# netstat -tulnp |grep redis tcp 0 0 192.168.100.154:6379 0.0.0.0:* LISTEN 20509/redi-server tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 20509/redi-server tcp 0 0 127.0.0.1:6389 0.0.0.0:* LISTEN 22128/redi-server tcp 0 0 127.0.0.1:6399 0.0.0.0:* LISTEN 22142/redi-server
1.2 主从状态验证
主节点验证
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6389,state=online,offset=306,lag=0
slave1:ip=127.0.0.1,port=6399,state=online,offset=306,lag=1
master_failover_state:no-failover
master_replid:fb1918339093b9d3e338d46c637671b4c6c08d34
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:306
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:41
repl_backlog_histlen:266
从节点验证
127.0.0.1:6389> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:4027533
slave_repl_offset:4027533
replica_full_sync_buffer_size:0
replica_full_sync_buffer_peak:0
master_current_sync_attempts:1
master_total_sync_attempts:2
master_link_up_since_seconds:55311
total_disconnect_time_sec:0
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
1.3 主从数据状态测试
主:读写
从:只读
- 向主中写数据,从中会自动同步数据
- 向从中写数据
127.0.0.1:6399> set k4 v44
(error) READONLY You can’t write against a read only replica.
- 看日志文件
/redisdata/6399.log
一些测试
-
当从Redis断开连接后,主Redis执行了写操作,再重新连接上来之后,数据是否会同步过来?
数据会同步过来 -
当主Redis Down掉,从Redis是否会变成主
从不会变成主,整个集合失去了写功能 -
从机不管何时注册,都会同步主的所有数据
!! 主流:通过配置文件配置
不通过配置文件,直接通过命令来配置从服务器
127.0.0.1:6389> slaveof 127.0.0.1 6379
OK
127.0.0.1:6389> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379# 关闭主从模式
127.0.0.1:6389> slaveof no one
OK
如果slave和master状态down,如何排查?
- master服务是否启动
- 如果不是同一台机器,检查selinux和firewall
- 检查配置masterauth,密码是否配置正确
- 查看日志
1.4 主从模式存在的问题
- 主挂了,从不会变成主
- 整个redis集群异常
- 主从数据延迟
如果万一出问题,需要手动切换
给某个从去掉主从关系
6399声明为主
关闭主从模式
127.0.0.1:6399> slaveof no one
OK
6389声明新主
127.0.0.1:6389> slaveof 127.0.0.1 6399
OK
主-从
主(6379)-从(6399)-从(6389)
总结:主从复制
主 -> 复
[root@rocky ~]# tail /redisdata/6389.log
7420:S 05 Sep 2025 11:31:39.585 * MASTER <-> REPLICA sync: receiving streamed RDB from master with EOF to disk
7420:S 05 Sep 2025 11:31:39.585 * MASTER <-> REPLICA sync: Loading DB in memory
7420:S 05 Sep 2025 11:31:39.586 * MASTER <-> REPLICA sync: Flushing old data
7420:S 05 Sep 2025 11:31:39.586 * Loading RDB produced by version 8.2.1
7420:S 05 Sep 2025 11:31:39.586 * RDB age 0 seconds
7420:S 05 Sep 2025 11:31:39.586 * RDB memory usage when created 1.10 Mb
7420:S 05 Sep 2025 11:31:39.586 * Done loading RDB, keys loaded: 6, keys expired: 0.
7420:S 05 Sep 2025 11:31:39.586 * MASTER <-> REPLICA sync: Finished with success
7420:S 05 Sep 2025 11:31:39.587 * MASTER <-> REPLICA sync: Starting to stream replication buffer into the db (0 bytes).
7420:S 05 Sep 2025 11:31:39.587 * MASTER <-> REPLICA sync: Successfully streamed replication buffer into the db (0 bytes in total)
-
slave启动,连接到master,给master发送一个sync命令
-
第一次会进行一次全量同步rdb -> flush old data -> loadding memery
-
master: 收到sync命令会在后台将当前数据保存rdb文件
-
同时收集所有修改的命令缓存起来 -> 发送slave
-
主和从之间保持心跳:repl-ping-replica-period 10
-
后期同步:增量复制
-
从机下线:下次上线的时候,会将之前未同步的数据全部同步上
offset [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1xxxxxxxxxxxx1xxxxxxxxxxxxxxxxxxx]4292 -> 找到对应的位置
二、哨兵模式
为了解决主从复制中主宕机不能自动切换的问题,Redis提供哨兵监控(用于主从监控)
哨兵:
1.检查后台主Redis是否故障
2. 如果故障了,根据投票数自动将某个从Redis转换为新主Redis
功能
- 主从监控:检查Redis运行是否正常
- 消息通知:如果发生故障,将故障转移的结果发送给客户端
- 故障转移:如果主Redis异常,将进行主从切换,将某个从Redis转换为新主Redis
- 配置中心:客户端通过连接哨兵来获取当前Redis服务的主节点地址
哨兵一般多个,奇数个
2.1 配置哨兵
1主 (6379) 2从 (6389, 6399)
3哨兵(26379, 26389, 26399) => 建议放在监控服务器或其他功能的服务器(不放在Redis服务器)
准备工作
-
配置好一主二从(所有Redis: masterauth 12345678,requirepass 12345678)
-
配置哨兵(原文件:源代码找到redis-stable/sentinel.conf)
/etc/sentinel26379.conf
# 服务监听地址,用于客户端连接
bind 0.0.0.0
# 允许外界连接
protected-mode no
# 哨兵端口
port 26379
# 开启后台哨兵
daemonize yes
# 哨兵pid文件
pidfile /var/run/redis-sentinel26379.pid
# 哨兵日志文件路径
logfile "/redisdata/sentinel26379.log"
# 工作目录
dir /redisdata
# 设置监控的主机Redis服务器(2表示最少几票才进行故障迁移)
sentinel monitor mymaster 127.0.0.1 6379 2
# 配置主机Redis的登录密码
sentinel auth-pass mymaster 12345678
/etc/sentinel26389.conf
# 服务监听地址,用于客户端连接
bind 0.0.0.0
# 允许外界连接
protected-mode no
# 哨兵端口
port 26389
# 开启后台哨兵
daemonize yes
# 哨兵pid文件
pidfile /var/run/redis-sentinel26389.pid
# 哨兵日志文件路径
logfile "/redisdata/sentinel26389.log"
# 工作目录
dir /redisdata
# 设置监控的主机Redis服务器(2表示最少几票才进行故障迁移)
sentinel monitor mymaster 127.0.0.1 6379 2
# 配置主机Redis的登录密码
sentinel auth-pass mymaster 12345678
/etc/sentinel26399.conf
# 服务监听地址,用于客户端连接
bind 0.0.0.0
# 允许外界连接
protected-mode no
# 哨兵端口
port 26399
# 开启后台哨兵
daemonize yes
# 哨兵pid文件
pidfile /var/run/redis-sentinel26399.pid
# 哨兵日志文件路径
logfile "/redisdata/sentinel26399.log"
# 工作目录
dir /redisdata
# 设置监控的主机Redis服务器(2表示最少几票才进行故障迁移)
sentinel monitor mymaster 127.0.0.1 6379 2
# 配置主机Redis的登录密码
sentinel auth-pass mymaster 12345678
启动
[root@db ~]# redis-sentinel /etc/sentinel26379.conf
[root@db ~]# ps aux |grep sen
root 22777 1.5 0.2 247048 9008 ? Ssl 15:36 0:00 redissentinel 0.0.0.0:26379 [sentinel]
root 22784 0.0 0.0 112824 988 pts/1 S+ 15:36 0:00 grep --color=auto sen
[root@db ~]# redis-server /etc/sentinel26389.conf --sentinel
[root@db ~]# redis-server /etc/sentinel26399.conf --sentinel
启动看查看两个内容
- 日志文件 /redisdata/sentinel26379.log
- 观察配置文件的变化 /etc/sentinel26379.conf
2.2 测试
- 模拟主redis down掉
redis-cli -h 127.0.0.1 -p 6379 -a 12345678 shutdown
-
观察发现,有一台从变成了主
(这次切换会瞬间断掉)127.0.0.1:6389> auth 12345678
Error: Server closed the connection -
看日志
22777:X 05 Sep 2025 15:49:22.523 # +sdown master mymaster 127.0.0.1 6379主观认为主Redis 6379宕机
22777:X 05 Sep 2025 15:49:22.572 * Sentinel new configuration saved on disk
22777:X 05 Sep 2025 15:49:22.572 # +new-epoch 1
22777:X 05 Sep 2025 15:49:22.573 * Sentinel new configuration saved on disk
22777:X 05 Sep 2025 15:49:22.573 # +vote-for-leader ed56c0fbedd81ef04a2c24b67c7951f5bdc4a959 1使用raft算法选出一个领导
22777:X 05 Sep 2025 15:49:22.586 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2客观宕机 3票发现主宕机
22777:X 05 Sep 2025 15:49:22.586 * Next failover delay: I will not start a failover before Fri Sep 5 15:55:23 2025
22777:X 05 Sep 2025 15:49:23.080 # +config-update-from sentinel ed56c0fbedd81ef04a2c24b67c7951f5bdc4a959 127.0.0.1 26389 @ mymaster 127.0.0.1 6379更新配置文件
22777:X 05 Sep 2025 15:49:23.080 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6389切换主当前主从关系
22777:X 05 Sep 2025 15:49:23.080 * +slave slave 127.0.0.1:6399 127.0.0.1 6399 @ mymaster 127.0.0.1 6389
22777:X 05 Sep 2025 15:49:23.080 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6389
22777:X 05 Sep 2025 15:49:23.082 * Sentinel new configuration saved on disk
22777:X 05 Sep 2025 15:49:53.092 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6389
当老主能正常提供服务后,继续作为从存在
哨兵模式故障切换流程
- SDown 主观下线(一个哨兵自己确认)
- 投票选leader:使用raft算法选出一个领导(故障迁移)
- ODown 客户下线(多个哨兵确认)
- 由Leader完成故障迁移
一个小问题:
- 切换有延时
- 不能保证数据零丢失
主从(主故障了不能写) -> 哨兵(实现故障迁移,有延时可能丢失数据) -> Redis集群