02 . Redis哨兵
Redis高可用概述
在
Web服务器中,高可用 是指服务器可以 正常访问 的时间,衡量的标准是在 多长时间 内可以提供正常服务(99.9%、99.99%、99.999%等等)。在Redis层面,高可用 的含义要宽泛一些,除了保证提供 正常服务(如 主从分离、快速容灾技术 等),还需要考虑 数据容量扩展、数据安全 等等。在
Redis中,实现 高可用 的技术主要包括 持久化、复制、哨兵 和 集群,下面简单说明它们的作用,以及解决了什么样的问题:持久化:持久化是 最简单的 高可用方法。它的主要作用是 数据备份,即将数据存储在 硬盘,保证数据不会因进程退出而丢失。
复制:复制是高可用
Redis的基础,哨兵 和 集群 都是在 复制基础 上实现高可用的。复制主要实现了数据的多机备份以及对于读操作的负载均衡和简单的故障恢复。缺陷是故障恢复无法自动化、写操作无法负载均衡、存储能力受到单机的限制。哨兵:在复制的基础上,哨兵实现了 自动化 的 故障恢复。缺陷是 写操作 无法 负载均衡,存储能力 受到 单机 的限制。
集群:通过集群,
Redis解决了 写操作 无法 负载均衡 以及 存储能力 受到 单机限制 的问题,实现了较为 完善 的 高可用方案。
Redis Sentinel的基本概念
Redis Sentinel是Redis高可用 的实现方案。Sentinel是一个管理多个Redis实例的工具,它可以实现对Redis的 监控、通知、自动故障转移。下面先对Redis Sentinel的 基本概念 进行简单的介绍。
基本名词说明:
| 基本名词 | 逻辑结构 | 物理结构 |
|---|---|---|
| Redis数据节点 | 主节点和从节点 | 主节点和从节点的进程 |
| 主节点(master) | Redis主数据库 | 一个独立的Redis进程 |
| 从节点(slave) | Redis从数据库 | 一个独立的Redis进程 |
| Sentinel节点 | 监控Redis数据节点 | 一个独立的Sentinel进程 |
| Sentinel节点集合 | 若干Sentinel节点的抽象组合 | 若干Sentinel节点进程 |
| Redis Sentinel | Redis高可用实现方案 | Sentinel节点集合和Redis数据节点进程 |
| 应用客户端 | 泛指一个或多个客户端 | 一个或者多个客户端进程或者线程 |
如图所示,Redis的 **主从复制模式** 和Sentinel **高可用架构** 的示意图:

Redis主从复制的问题
Redis 主从复制 可将 主节点 数据同步给 从节点,从节点此时有两个作用:
# 1. 一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。
# 2. 扩展主节点的读能力,分担主节点读压力。

**主从复制** 同时存在以下几个问题:
# 1. 一旦主节点宕机,从节点晋升成主节点,同时需要修改应用方的主节点地址,还需要命令所有 从节点去复制新的主节点,整个过程需要人工干预。
# 2. 主节点的写能力受到单机的限制。
# 3. 主节点的存储能力受到单机的限制。
# 4. 原生复制的弊端在早期的版本中也会比较突出,比如:Redis复制中断后,从节点会发起 `psync`。此时如果同步不成功,则会进行全量同步,主库执行 全量备份的同时,可能会造成毫秒或秒级的卡顿。
Redis Sentinel深入探究
Redis Sentinel的架构

Redis Sentinel的主要功能
Sentinel的主要功能包括 主节点存活检测、主从运行情况检测、自动故障转移 (failover)、主从切换。Redis的Sentinel最小配置是 一主一从。
Redis的Sentinel系统可以用来管理多个Redis服务器,该系统可以执行以下四个任务:
监控
Sentinel会不断的检查 主服务器 和 从服务器 是否正常运行。
通知
当被监控的某个
Redis服务器出现问题,Sentinel通过API脚本 向 管理员 或者其他的 应用程序 发送通知。
自动故障转移
当 主节点 不能正常工作时,
Sentinel会开始一次 自动的 故障转移操作,它会将与 失效主节点 是 主从关系 的其中一个 从节点 升级为新的 主节点,并且将其他的 从节点 指向 新的主节点。
配置提供者
在
Redis Sentinel模式下,客户端应用 在初始化时连接的是Sentinel节点集合,从中获取 主节点 的信息。
主观下线和客观下线
默认情况下,每个
Sentinel节点会以 每秒一次 的频率对Redis节点和 其它 的Sentinel节点发送PING命令,并通过节点的 回复 来判断节点是否在线。
主观下线
主观下线 适用于所有 主节点 和 从节点。如果在
down-after-milliseconds毫秒内,Sentinel没有收到 目标节点 的有效回复,则会判定 该节点 为 主观下线。
客观下线
客观下线 只适用于 主节点。如果 主节点 出现故障,
Sentinel节点会通过sentinel is-master-down-by-addr命令,向其它Sentinel节点询问对该节点的 状态判断。如果超过<quorum>个数的节点判定 主节点 不可达,则该Sentinel节点会判断 主节点 为 客观下线。
Sentinel的通信命令
Sentinel节点连接一个Redis实例的时候,会创建cmd和pub/sub两个 连接。Sentinel通过cmd连接给Redis发送命令,通过pub/sub连接到Redis实例上的其他Sentinel实例。
Sentinel与Redis主节点 和 从节点 交互的命令,主要包括:
| 命令 | 作 用 |
|---|---|
| PING | Sentinel 向 Redis 节点发送 PING 命令,检查节点的状态 |
| INFO | Sentinel 向 Redis 节点发送 INFO 命令,获取它的 从节点信息 |
| PUBLISH | Sentinel 向其监控的 Redis 节点 __sentinel__:hello 这个 channel 发布 自己的信息 及 主节点 相关的配置 |
| SUBSCRIBE | Sentinel 通过订阅 Redis 主节点 和 从节点 的 __sentinel__:hello 这个 channnel,获取正在监控相同服务的其他 Sentinel 节点 |
Sentinel与Sentinel交互的命令,主要包括:
| 命令 | 作 用 |
|---|---|
| PING | Sentinel 向其他 Sentinel 节点发送 PING 命令,检查节点的状态 |
| SENTINEL:is-master-down-by-addr | 和其他 Sentinel 协商 主节点 的状态,如果 主节点 处于 SDOWN 状态,则投票自动选出新的 主节点 |
Redis Sentinel的工作原理
每个 Sentinel 节点都需要定期执行以下任务:
- 每个
Sentinel以 每秒钟 一次的频率,向它所知的 主服务器、从服务器 以及其他Sentinel实例 发送一个PING命令。
1 . 每个Sentinel 以每秒钟一次频率,向他所知的主服务器、从服务器以及其他Sentinel实例发送一个PING命令。

2 . 如果一个 实例(
instance)距离 最后一次 有效回复PING命令的时间超过down-after-milliseconds所指定的值,那么这个实例会被Sentinel标记为 主观下线。

3 . 如果一个 主服务器 被标记为 主观下线,那么正在 监视 这个 主服务器 的所有
Sentinel节点,要以 每秒一次 的频率确认 主服务器 的确进入了 主观下线 状态。

4 . 如果一个 主服务器 被标记为 主观下线,并且有 足够数量 的
Sentinel(至少要达到 配置文件 指定的数量)在指定的 时间范围 内同意这一判断,那么这个 主服务器 被标记为 客观下线。

5 . 在一般情况下, 每个
Sentinel会以每10秒一次的频率,向它已知的所有 主服务器 和 从服务器 发送INFO命令。当一个 主服务器 被Sentinel标记为 客观下线 时,Sentinel向 下线主服务器 的所有 从服务器 发送INFO命令的频率,会从10秒一次改为 每秒一次。

6 . Sentinel
和其他Sentinel协商 主节点 的状态,如果 **主节点** 处于SDOWN` 状态,则投票自动选出新的 主节点。将剩余的 从节点 指向 新的主节点 进行 数据复制。

- 当没有足够数量的
Sentinel同意 主服务器 下线时, 主服务器 的 客观下线状态 就会被移除。当 主服务器 重新向Sentinel的PING命令返回 有效回复 时,主服务器 的 主观下线状态 就会被移除。

注意:一个有效的 PING 回复可以是:+PONG、-LOADING或者-MASTERDOWN。如果服务器返回除以上三种回复之外的其他回复,又或者在指定时间内没有回复 PING命令, 那么Sentinel 认为服务器返回的回复无效(non-valid)。
Redis Sentinel搭建
环境清单
| 节点名(角色名) | IP地址 | 端口号 | 硬件 | 网络 |
|---|---|---|---|---|
| Redis Master | 192.168.171.136 | 16379 | 2C4G | Nat,内网 |
| Redis Slave1 | 192.168.171.137 | 26379 | 2C4G | Nat,内网 |
| Redis Slave2 | 192.168.171.138 | 36379 | 2C4G | Nat,内网 |
| Redis Sentinel1 | 192.168.171.136 | 16380 | 2C4G | Nat,内网 |
| Redis Sentinel2 | 192.168.171.137 | 26380 | 2C4G | Nat,内网 |
| Redis Sentinel3 | 192.168.171.138 | 36380 | 2C4G | Nat,内网 |
注意事项
# 1. 一个稳健的 `Redis Sentinel` 集群,应该使用至少三个`Sentinel` 实例,并且保证讲这些实例放到不同的机器上,甚至不同的物理区域。
# 2. Sentinel无法保证强一致性。
# 3. 常见的客户端应用库都支持 `Sentinel`。
# 4. Sentinel需要通过不断的测试和观察,才能保证高可用。
Redis Sentinel的配置文件
# 哨兵sentinel实例运行的端口,默认26379
port 26379
# 哨兵sentinel的工作目录
dir ./
# 哨兵sentinel监控的redis主节点的
## ip:主机ip地址
## port:哨兵端口号
## master-name:可以自己命名的主节点名字(只能由字母A-z、数字0-9 、这三个字符".-_"组成。)
## quorum:当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2
# 当在Redis实例中开启了requirepass <foobared>,所有连接Redis实例的客户端都要提供密码。
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster 123456
# 指定主节点应答哨兵sentinel的最大时间间隔,超过这个时间,哨兵主观上认为主节点下线,默认30秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000
# 指定了在发生failover主备切换时,最多可以有多少个slave同时对新的master进行同步。这个数字越小,完成failover所需的时间就越长;反之,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为1,来保证每次只有一个slave,处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
# 故障转移的超时时间failover-timeout,默认三分钟,可以用在以下这些方面:
# 1. 同一个sentinel对同一个master两次failover之间的间隔时间。
# 2. 当一个slave从一个错误的master那里同步数据时开始,直到slave被纠正为从正确的master那里同步数据时结束。
# 3. 当想要取消一个正在进行的failover时所需要的时间。
# 4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来同步数据了
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
# 当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本。一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。
# 对于脚本的运行结果有以下规则:
# 1. 若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10。
# 2. 若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
# 3. 如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
# sentinel notification-script <master-name> <script-path>
sentinel notification-script mymaster /var/redis/notify.sh
# 这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentinel client-reconfig-script <master-name> <script-path>
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
安装Redis
三台机器都要安装
yum -y install gcc
wget http://download.redis.io/releases/redis-4.0.14.tar.gz
tar xvf redis-4.0.14.tar.gz -C /opt/
cd /opt/redis-4.0.14
# Redis的编译,只将命令文件编译,将会在当前目录生成bin目录
make && make install PREFIX=/usr/local/redis
cd ..
mv redis-4.0.14 /usr/local/redis
# 创建环境变量
echo 'PATH=$PATH:/usr/local/redis/src/' >> /etc/profile
source /etc/profile
# 此时在任何目录位置都可以是用redis-server等相关命令
[root@redis1 ~]# redis-
redis-benchmark redis-check-rdb redis-sentinel redis-trib.rb
redis-check-aof redis-cli redis-server
Redis-Server的配置管理
分别拷贝三份
redis.conf文件到/usr/local/redis-sentinel目录下面。三个配置文件分别对应master、slave1和slave2三个Redis节点的 启动配置。
mkdir /usr/local/redis-sentinel/
mkdir /usr/local/redis/backup
sudo cp /usr/local/redis/redis.conf /usr/local/redis-sentinel/redis-16379.conf
sudo cp /usr/local/redis/redis.conf /usr/local/redis-sentinel/redis-26379.conf
sudo cp /usr/local/redis/redis.conf /usr/local/redis-sentinel/redis-36379.conf
分别修改三份配置文件如下
主节点:redis-16379.conf
daemonize yes
pidfile /var/run/redis-16379.pid
logfile /var/log/redis-16379.log
port 16379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-16379.db
dir /usr/local/redis/backup
masterauth 123456
requirepass 123456
从节点1:redis-26379.conf
daemonize yes
pidfile /var/run/redis-26379.pid
logfile /var/log/redis-26379.log
port 26379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-26379.db
dir /usr/local/redis/backup
masterauth 123456
requirepass 123456
slaveof 192.168.171.136 16379
从节点2:redis-36379.conf
daemonize yes
pidfile /var/run/redis-36379.pid
logfile /var/log/redis/redis-36379.log
port 36379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-36379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456
slaveof 192.168.171.136 16379
注意
如果要做 自动故障转移,建议所有的
redis.conf都设置masterauth。因为 自动故障 只会重写 主从关系,即slaveof,不会自动写入masterauth。如果Redis原本没有设置密码,则可以忽略。
Redis-Server启动验证
按顺序分别启动
16379,26379和36379三个Redis节点,启动命令和启动日志如下:
Redis 的启动命令:
sudo redis-server /usr/local/redis-sentinel/redis-16379.conf
sudo redis-server /usr/local/redis-sentinel/redis-26379.conf
sudo redis-server /usr/local/redis-sentinel/redis-36379.conf
[root@redis-master ~]# redis-cli -h 127.0.0.1 -p 16379 -a 123456
Warning: Using a password with '-a' option on the command line interface may not be safe.
127.0.0.1:16379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.171.137,port=26379,state=online,offset=70,lag=1
slave1:ip=192.168.171.138,port=36379,state=online,offset=70,lag=0
master_replid:15979cfdbb2ff2a9a95ce8b2a37c4779d299dfc2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:70
查看 Redis 的启动日志:
- 节点
redis-16379
2364:M 09 May 18:26:44.327 * Starting BGSAVE for SYNC with target: disk
2364:M 09 May 18:26:44.327 * Background saving started by pid 2368
2368:C 09 May 18:26:44.328 * DB saved on disk
2368:C 09 May 18:26:44.329 * RDB: 6 MB of memory used by copy-on-write
2364:M 09 May 18:26:44.332 * Background saving terminated with success
2364:M 09 May 18:26:44.332 * Synchronization with slave 192.168.171.137:26379 succeeded
2364:M 09 May 18:27:03.280 * Slave 192.168.171.138:36379 asks for synchronization
2364:M 09 May 18:27:03.280 * Partial resynchronization not accepted: Replication ID mismatch (Slave asked for '4f408b9c0c3713dd6328d9887d48538ba322105a', my replication IDs are '15979cfdbb2ff2a9a95ce8b2a37c4779d299dfc2' and '0000000000000000000000000000000000000000')
2364:M 09 May 18:27:03.280 * Starting BGSAVE for SYNC with target: disk
2364:M 09 May 18:27:03.280 * Background saving started by pid 2369
2369:C 09 May 18:27:03.281 * DB saved on disk
2369:C 09 May 18:27:03.282 * RDB: 6 MB of memory used by copy-on-write
2364:M 09 May 18:27:03.303 * Background saving terminated with success
2364:M 09 May 18:27:03.304 * Synchronization with slave 192.168.171.138:36379 succeeded
以下两行日志日志表明,redis-16379作为Redis的主节点,redis-26379和 redis-36379作为从节点,从主节点同步数据。
2369:C 09 May 18:27:03.282 * RDB: 6 MB of memory used by copy-on-write
2364:M 09 May 18:27:03.303 * Background saving terminated with success
2364:M 09 May 18:27:03.304 * Synchronization with slave 192.168.171.138:36379 succeeded
- 节点
redis-26379
cat /var/log/redis-26379.log
2388:S 09 May 18:26:44.370 * Ready to accept connections
2388:S 09 May 18:26:44.370 * Connecting to MASTER 192.168.171.136:16379
2388:S 09 May 18:26:44.370 * MASTER <-> SLAVE sync started
2388:S 09 May 18:26:44.370 * Non blocking connect for SYNC fired the event.
2388:S 09 May 18:26:44.371 * Master replied to PING, replication can continue...
2388:S 09 May 18:26:44.371 * Trying a partial resynchronization (request 4f408b9c0c3713dd6328d9887d48538ba322105a:1).
2388:S 09 May 18:26:44.372 * Full resync from master: 15979cfdbb2ff2a9a95ce8b2a37c4779d299dfc2:0
2388:S 09 May 18:26:44.372 * Discarding previously cached master state.
2388:S 09 May 18:26:44.377 * MASTER <-> SLAVE sync: receiving 176 bytes from master
2388:S 09 May 18:26:44.377 * MASTER <-> SLAVE sync: Flushing old data
2388:S 09 May 18:26:44.377 * MASTER <-> SLAVE sync: Loading DB in memory
2388:S 09 May 18:26:44.377 * MASTER <-> SLAVE sync: Finished with success
- 节点
redis-36379
cat /var/log/redis-36379.log
5623:S 09 May 18:27:03.321 * Trying a partial resynchronization (request 4f408b9c0c3713dd6328d9887d48538ba322105a:1).
5623:S 09 May 18:27:03.322 * Full resync from master: 15979cfdbb2ff2a9a95ce8b2a37c4779d299dfc2:28
5623:S 09 May 18:27:03.322 * Discarding previously cached master state.
5623:S 09 May 18:27:03.345 * MASTER <-> SLAVE sync: receiving 176 bytes from master
5623:S 09 May 18:27:03.345 * MASTER <-> SLAVE sync: Flushing old data
5623:S 09 May 18:27:03.345 * MASTER <-> SLAVE sync: Loading DB in memory
5623:S 09 May 18:27:03.346 * MASTER <-> SLAVE sync: Finished with success
Sentinel的配置管理
分别拷贝三份
redis-sentinel.conf文件到/usr/local/redis-sentinel目录下面。三个配置文件分别对应master、slave1和slave2三个Redis节点的 哨兵配置。
sudo cp /usr/local/redis/sentinel.conf /usr/local/redis-sentinel/sentinel-16380.conf
sudo cp /usr/local/redis/sentinel.conf /usr/local/redis-sentinel/sentinel-26380.conf
sudo cp /usr/local/redis/sentinel.conf /usr/local/redis-sentinel/sentinel-36380.conf
节点1:sentinel-16380.conf
bind 0.0.0.0
port 16380
daemonize yes
dir /usr/local/redis/backup
logfile "sentinel-16380.log"
sentinel monitor master 192.168.171.136 16379 2
sentinel down-after-milliseconds master 30000
sentinel parallel-syncs master 1
sentinel failover-timeout master 180000
sentinel deny-scripts-reconfig yes
sentinel auth-pass master 123456
节点2:sentinel-26380.conf
bind 0.0.0.0
port 26380
daemonize yes
dir /usr/local/redis/backup
logfile "sentinel-26380.log"
sentinel monitor master 192.168.171.136 16379 2
sentinel down-after-milliseconds master 30000
sentinel parallel-syncs master 1
sentinel failover-timeout master 180000
sentinel deny-scripts-reconfig yes
sentinel auth-pass master 123456
节点3:sentinel-36380.conf
bind 0.0.0.0
port 36380
daemonize yes
dir /usr/local/redis/backup
logfile "sentinel-36380.log"
sentinel monitor master 192.168.171.136 16379 2
sentinel down-after-milliseconds master 30000
sentinel parallel-syncs master 1
sentinel failover-timeout master 180000
sentinel deny-scripts-reconfig yes
sentinel auth-pass master 123456
Sentinel启动验证
按顺序分别启动 16380,26380和36380三个Sentinel 节点,启动命令和启动日志如下:
# sudo redis-sentinel /usr/local/redis-sentinel/sentinel-16380.conf
# sudo redis-sentinel /usr/local/redis-sentinel/sentinel-26380.conf
# sudo redis-sentinel /usr/local/redis-sentinel/sentinel-36380.conf
# 记得挨个查看端口进程喔
[root@redis-master ~]# lsof -i:16380
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-sen 2062 root 6u IPv4 37369 0t0 TCP *:16380 (LISTEN)
[root@redis-master ~]# ps aux |grep sentinel
root 2062 0.1 0.3 145420 7712 ? Rsl 17:45 0:00 redis-sentinel 0.0.0.0:16380 [sentinel]
查看 Sentinel 的启动日志:
节点 sentinel-16380`
cat /usr/local/redis/backup/sentinel-26380.log
4586:X 09 May 22:34:43.499 # Configuration loaded
4587:X 09 May 22:34:43.501 * Running mode=sentinel, port=26380.
4587:X 09 May 22:34:43.501 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
4587:X 09 May 22:34:43.502 # Sentinel ID is 94c9b3deb09ebf98708ec5d0df56457198adbbe1
4587:X 09 May 22:34:43.502 # +monitor master master 127.0.0.1 6379 quorum 2
4587:X 09 May 22:34:43.502 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master 127.0.0.1 6379
4587:X 09 May 22:34:43.503 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master 127.0.0.1 6379
4587:X 09 May 22:34:43.504 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ master 127.0.0.1 6379
4587:X 09 May 22:37:26.881 * +sentinel sentinel 6f85655e82ba92d709f2e59b6cb4b22d91302501 127.0.0.1 26381 @ master 127.0.0.1 6379
4587:X 09 May 22:37:32.121 * +sentinel sentinel 3b2ad68e2f8f6a2e19132a1eabb95ea099eef525 127.0.0.1 26382 @ master 127.0.0.1 6379
sentinel-16380节点的 Sentinel ID 为 69d05b86a82102a8919231fd3c2d1f21ce86e000,并通过 Sentinel ID 把自身加入 sentinel 集群中
节点 sentinel-26380`
cat /usr/local/redis/backup/sentinel-26380.log
4231:X 09 May 22:25:59.504 # User requested shutdown...
4231:X 09 May 22:25:59.504 * Removing the pid file.
4231:X 09 May 22:25:59.504 # Sentinel is now ready to exit, bye bye...
4586:X 09 May 22:34:43.499 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
4586:X 09 May 22:34:43.499 # Redis version=4.0.14, bits=64, commit=00000000, modified=0, pid=4586, just started
4586:X 09 May 22:34:43.499 # Configuration loaded
4587:X 09 May 22:34:43.501 * Running mode=sentinel, port=26380.
4587:X 09 May 22:34:43.501 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
4587:X 09 May 22:34:43.502 # Sentinel ID is 94c9b3deb09ebf98708ec5d0df56457198adbbe1
4587:X 09 May 22:34:43.502 # +monitor master master 127.0.0.1 6379 quorum 2
4587:X 09 May 22:34:43.502 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master 127.0.0.1 6379
4587:X 09 May 22:34:43.503 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master 127.0.0.1 6379
4587:X 09 May 22:34:43.504 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ master 127.0.0.1 6379
4587:X 09 May 22:37:26.881 * +sentinel sentinel 6f85655e82ba92d709f2e59b6cb4b22d91302501 127.0.0.1 26381 @ master 127.0.0.1 6379
4587:X 09 May 22:37:32.121 * +sentinel sentinel 3b2ad68e2f8f6a2e19132a1eabb95ea099eef525 127.0.0.1 26382 @ master 127.0.0.1 6379
sentinel-26380 节点的 Sentinel ID 为 21e30244cda6a3d3f55200bcd904d0877574e506,并通过 Sentinel ID 把自身加入 sentinel集群中。此时 sentinel集群中已有sentinel-16380和sentinel-26380 两个节点
节点 sentinel-36380`
cat /usr/local/redis/backup/sentinel-26381.log
4719:X 09 May 22:37:24.813 # Configuration loaded
4720:X 09 May 22:37:24.815 * Running mode=sentinel, port=26381.
4720:X 09 May 22:37:24.815 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
4720:X 09 May 22:37:24.815 # Sentinel ID is 6f85655e82ba92d709f2e59b6cb4b22d91302501
4720:X 09 May 22:37:24.815 # +monitor master master 127.0.0.1 6379 quorum 2
4720:X 09 May 22:37:24.815 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ master 127.0.0.1 6379
4720:X 09 May 22:37:24.816 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ master 127.0.0.1 6379
4720:X 09 May 22:37:24.816 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ master 127.0.0.1 6379
4720:X 09 May 22:37:26.497 * +sentinel sentinel 94c9b3deb09ebf98708ec5d0df56457198adbbe1 127.0.0.1 26380 @ master 127.0.0.1 6379
4720:X 09 May 22:37:32.121 * +sentinel sentinel 3b2ad68e2f8f6a2e19132a1eabb95ea099eef525 127.0.0.1 26382 @ master 127.0.0.1 6379
sentinel-36380 节点的 Sentinel ID 为 fd166dc66425dc1d9e2670e1f17cb94fe05f5fc7,并通过 Sentinel ID 把自身加入 sentinel 集群中。此时 sentinel 集群中已有 sentinel-16380,sentinel-26380 和 sentinel-36380 三个节点
Sentinel配置刷新
- 节点1:sentinel-16380.conf
sentinel-16380.conf 文件新生成如下的配置项:
bind 0.0.0.0
port 16380
daemonize yes
dir "/usr/local/redis/backup"
logfile "sentinel-16380.log"
sentinel myid cf91bc0b7c1d9138e7d654f025b813e48cb40bfc
sentinel deny-scripts-reconfig yes
sentinel monitor master 192.168.171.136 16379 2
sentinel auth-pass master 123456
sentinel config-epoch master 0
sentinel leader-epoch master 0
# Generated by CONFIG REWRITE
sentinel known-slave master 192.168.171.138 36379
sentinel known-slave master 192.168.171.137 26379
sentinel known-sentinel master 192.168.171.138 36380 13402e25e40f318f4bf1eab432fedd7c504ee64b
sentinel known-sentinel master 192.168.171.137 26380 6c5507ed7919e5935301afe0a2c362e6f0d6bb40
sentinel current-epoch 0
可以注意到,
sentinel-16380.conf刷新写入了Redis主节点关联的所有 从节点redis-26379和redis-36379,同时写入了其余两个Sentinel节点sentinel-26380和sentinel-36380的IP地址,端口号 和Sentinel ID。
bind 0.0.0.0
port 26380
daemonize yes
dir "/usr/local/redis/backup"
logfile "sentinel-26380.log"
sentinel myid 6c5507ed7919e5935301afe0a2c362e6f0d6bb40
sentinel deny-scripts-reconfig yes
sentinel monitor master 192.168.171.136 16379 2
sentinel auth-pass master 123456
sentinel config-epoch master 0
sentinel leader-epoch master 0
# Generated by CONFIG REWRITE
sentinel known-slave master 192.168.171.137 26379
sentinel known-slave master 192.168.171.138 36379
sentinel known-sentinel master 192.168.171.136 16380 cf91bc0b7c1d9138e7d654f025b813e48cb40bfc
sentinel known-sentinel master 192.168.171.138 36380 13402e25e40f318f4bf1eab432fedd7c504ee64b
sentinel current-epoch 0
可以注意到,
sentinel-26380.conf刷新写入了Redis主节点关联的所有 从节点redis-26379和redis-36379,同时写入了其余两个Sentinel节点sentinel-36380和sentinel-16380的IP地址,端口号 和Sentinel ID。
bind 0.0.0.0
port 36380
daemonize yes
dir "/usr/local/redis/backup"
logfile "sentinel-36380.log"
sentinel myid 13402e25e40f318f4bf1eab432fedd7c504ee64b
sentinel deny-scripts-reconfig yes
sentinel monitor master 192.168.171.136 16379 2
sentinel auth-pass master 123456
sentinel config-epoch master 0
sentinel leader-epoch master 0
# Generated by CONFIG REWRITE
sentinel known-slave master 192.168.171.137 26379
sentinel known-slave master 192.168.171.138 36379
sentinel known-sentinel master 192.168.171.137 26380 6c5507ed7919e5935301afe0a2c362e6f0d6bb40
sentinel known-sentinel master 192.168.171.136 16380 cf91bc0b7c1d9138e7d654f025b813e48cb40bfc
sentinel current-epoch 0
可以注意到,
sentinel-36380.conf刷新写入了Redis主节点关联的所有 从节点redis-26379和redis-36379,同时写入了其余两个Sentinel节点sentinel-16380和sentinel-26380的IP地址,端口号 和Sentinel ID。
Sentinel时客户端命令
检查其他 Sentinel节点的状态,返回PONG 为正常。
PING sentinel
显示被监控的所有主节点以及它们的状态
SENTINEL masters
显示指定主节点 的信息和状态
SENTINEL master master
显示指定主节点的所有从节点以及它们的状态
SENTINEL slaves <master_name>
返回指定 主节点 的 IP 地址和 端口。如果正在进行 failover 或者 failover 已经完成,将会显示被提升为 主节点 的 从节点 的 IP 地址和 端口。
SENTINEL get-master-addr-by-name <master_name>
重置名字匹配该正则表达式的所有的主节点的状态信息,清除它之前的状态信息,以及从节点的信息。
SENTINEL reset <pattern>
强制当前 Sentinel节点执行failover,并且不需要得到其他 Sentinel节点的同意。但是failover后会将最新的配置发送给其他Sentinel 节点。
SENTINEL failover <master_name>
验证Sentinel状态
127.0.0.1:16380> INFO sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=master,status=ok,address=192.168.171.136:16379,slaves=2,sentinels=3
Redis Sentinel故障切换与恢复
我们尝试关闭6379这台实例主节点
redis-cli -h 127.0.0.1 -p 16379 -a 123456 # 连接到Redis主机
127.0.0.1:6379> shutdown # 终止Redis服务
# 有时候服务并没有宕机,可以直接kill掉,记得连接一下确认宕机没
接下来稍等3-5s,我们去登录一下哨兵,看一下主节点有没有迁移
[root@redis-slave1 redis-sentinel]# redis-cli -h 127.0.0.1 -p 26380 -a 123456
127.0.0.1:26380> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=master,status=ok,address=192.168.171.137:26379,slaves=2,sentinels=3
# 我们可以看到主节点已经换成192.168.171.137这一台节点了,之前是136节点
或者查看 Redis主从集群的主节点信息。可以发现redis-26379 晋升为新的主节点。
redis-cli -h 127.0.0.1 -p 26380 -a 123456
127.0.0.1:26380> SENTINEL masters
1) 1) "name"
2) "master"
3) "ip"
4) "192.168.171.137"
5) "port"
6) "26379"
7) "runid"
8) "2d20ec05ba7c099ab2bcae4ee0a1bc2c441f9d77"
9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "483"
19) "last-ping-reply"
20) "483"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "7239"
25) "role-reported"
26) "master"
27) "role-reported-time"
28) "78176"
29) "config-epoch"
30) "1"
31) "num-slaves"
32) "2"
33) "num-other-sentinels"
34) "2"
35) "quorum"
36) "2"
37) "failover-timeout"
38) "180000"
39) "parallel-syncs"
40) "1"
Redis Sentinel日志跟踪
查看任意 Sentinel 节点的日志如下:
1592:X 10 May 12:03:31.061 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1592:X 10 May 12:03:31.062 # Sentinel ID is 6c5507ed7919e5935301afe0a2c362e6f0d6bb40
1592:X 10 May 12:03:31.062 # +monitor master master 192.168.171.136 16379 quorum 2
1592:X 10 May 12:03:31.063 * +slave slave 192.168.171.137:26379 192.168.171.137 26379 @ master 192.168.171.136 16379
1592:X 10 May 12:03:31.064 * +slave slave 192.168.171.138:36379 192.168.171.138 36379 @ master 192.168.171.136 16379
1592:X 10 May 12:03:32.413 * +sentinel sentinel cf91bc0b7c1d9138e7d654f025b813e48cb40bfc 192.168.171.136 16380 @ master 192.168.171.136 16379
1592:X 10 May 12:04:02.703 * +sentinel sentinel 13402e25e40f318f4bf1eab432fedd7c504ee64b 192.168.171.138 36380 @ master 192.168.171.136 16379
1592:X 10 May 12:09:42.035 # +sdown sentinel cf91bc0b7c1d9138e7d654f025b813e48cb40bfc 192.168.171.136 16380 @ master 192.168.171.136 16379
1592:X 10 May 12:11:52.177 # +sdown master master 192.168.171.136 16379
1592:X 10 May 12:11:52.257 # +new-epoch 1
1592:X 10 May 12:11:52.258 # +vote-for-leader 13402e25e40f318f4bf1eab432fedd7c504ee64b 1
1592:X 10 May 12:11:53.275 # +odown master master 192.168.171.136 16379 #quorum 2/2
1592:X 10 May 12:11:53.275 # Next failover delay: I will not start a failover before Sun May 10 12:17:52 2020
1592:X 10 May 12:11:53.476 # +config-update-from sentinel 13402e25e40f318f4bf1eab432fedd7c504ee64b 192.168.171.138 36380 @ master 192.168.171.136 16379
1592:X 10 May 12:11:53.476 # +switch-master master 192.168.171.136 16379 192.168.171.137 26379
1592:X 10 May 12:11:53.476 * +slave slave 192.168.171.138:36379 192.168.171.138 36379 @ master 192.168.171.137 26379
1592:X 10 May 12:11:53.476 * +slave slave 192.168.171.136:16379 192.168.171.136 16379 @ master 192.168.171.137 26379
1592:X 10 May 12:12:23.504 # +sdown slave 192.168.171.136:16379 192.168.171.136 16379 @ master 192.168.171.137 26379
Redis的配置文件
分别查看三个 redis 节点的配置文件,发生 主从切换 时 redis.conf 的配置会自动发生刷新。
节点 redis-16379
[root@redis-master redis-sentinel]# cat redis-16379.conf
daemonize yes
pidfile /var/run/redis-16379.pid
logfile /var/log/redis-16379.log
port 16379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-16379.db
dir /usr/local/redis/backup
masterauth 123456
requirepass 123456
- 节点 redis-26379
[root@redis-slave1 redis-sentinel]# cat redis-26379.conf
daemonize yes
pidfile "/var/run/redis-26379.pid"
logfile "/var/log/redis-26379.log"
port 26379
bind 0.0.0.0
timeout 300
databases 16
dbfilename "dump-26379.db"
dir "/usr/local/redis/backup"
masterauth "123456"
requirepass "123456"
- 节点 redis-36379
[root@redis-slave2 redis-sentinel]# cat redis-36379.conf
daemonize yes
pidfile "/var/run/redis-36379.pid"
logfile "/var/log/redis-36379.log"
port 36379
bind 0.0.0.0
timeout 300
databases 16
dbfilename "dump-36379.db"
dir "/usr/local/redis/backup"
masterauth "123456"
requirepass "123456"
slaveof 192.168.171.137 26379
分析:
redis-26379节点slaveof配置被移除,晋升为 主节点。redis-16379节点处于 宕机状态。redis-36379的slaveof配置更新为127.0.0.1 redis-26379,成为redis-26379的 从节点。
重启节点 redis-16379。待正常启动后,再次查看它的 redis.conf 文件,配置如下:
[root@redis-master redis-sentinel]# cat redis-16379.conf
daemonize yes
pidfile "/var/run/redis-16379.pid"
logfile "/var/log/redis-16379.log"
port 16379
bind 0.0.0.0
timeout 300
databases 16
dbfilename "dump-16379.db"
dir "/usr/local/redis/backup"
masterauth "123456"
requirepass "123456"
# Generated by CONFIG REWRITE
slaveof 192.168.171.137 26379
节点 redis-16379 的配置文件新增一行 slaveof 配置属性,指向 redis-26379,即成为 新的主节点 的 从节点。
本文首先对 Redis 实现高可用的几种模式做出了阐述,指出了 Redis 主从复制 的不足之处,进一步引入了 Redis Sentinel 哨兵模式 的相关概念,深入说明了 Redis Sentinel 的 具体功能,基本原理,高可用搭建 和 自动故障切换 验证等。
当然,Redis Sentinel 仅仅解决了 高可用 的问题,对于 主节点 单点写入和单节点无法扩容等问题,还需要引入 Redis Cluster 集群模式 予以解决。
02 . Redis哨兵的更多相关文章
- redis单点、redis主从、redis哨兵sentinel,redis集群cluster配置搭建与使用
目录 redis单点.redis主从.redis哨兵 sentinel,redis集群cluster配置搭建与使用 1 .redis 安装及配置 1.1 redis 单点 1.1.2 在命令窗口操作r ...
- Redis 哨兵模式实现主从故障互切换
200 ? "200px" : this.width)!important;} --> 介绍 Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 S ...
- redis哨兵配置
redis哨兵配置主从 redis哨兵的启动和redis实例的启动没有关系.所以可以在任何机器上启动redis哨兵.至少要保证有两个哨兵在运行,要不然宕机后哨兵会找不到主节点. 配置步骤: 1.在 ...
- redis哨兵配置主从
redis哨兵的启动和redis实例的启动没有关系.所以可以在任何机器上启动redis哨兵.至少要保证有两个哨兵在运行,要不然宕机后哨兵会找不到主节点. 配置步骤: 1.在redis的配置文件中添加鉴 ...
- Redis哨兵
Redis Sentinel Redis哨兵为Redis提供高可用.这就意味着你用哨兵可以创建一个Redis部署,在没有人为干预的情况下抵抗某些失败.(PS:自动故障转移) Redis哨兵还提供其他的 ...
- redis哨兵架构的基础知识及部署和管理
一.前言 1.哨兵的介绍 sentinal,中文名是哨兵 哨兵是redis集群架构中非常重要的一个组件,主要功能如下 ()集群监控,负责监控redis master和slave进程是否正常工作 ()消 ...
- Redis 哨兵
作用 Redis Sentinel,即Redis哨兵,在Redis 2.8版本开始引入. 主要提供了配置提供者,通知,哨兵的监控和自动故障转移功能.哨兵的核心功能是主节点的自动故障转移. 下面是Red ...
- SpringBoot整合redis哨兵主从服务
前提环境: 主从配置 http://www.cnblogs.com/zwcry/p/9046207.html 哨兵配置 https://www.cnblogs.com/zwcry/p/9134721. ...
- redis 哨兵模式 Connection refused
spring整合redis哨兵,修改了bind ,protected 任然连接拒绝,是因为哨兵的mastername 和spring里面的名称不一致..导致拒绝了...... 哨兵模式配置文件 属性 ...
随机推荐
- Jenkins如何进行权限管理
一.安装插件 插件名:Role-based Authorization Strategy 二.配置授权策略 三.创建用户 四.添加并配置权限 4.1.添加Global Role 普通角色拥有全局只读权 ...
- Java——Spring常用jar包功能详解
很多小伙伴包括我自己,在使用spring的时候导入了一堆jar包,但是并不明白每个jar的用途,使用spring的不同功能时也不知该导入哪个jar包,今天记录一下spring各个jar包的含义,供大家 ...
- SpringBoot系列(十四)集成邮件发送服务及邮件发送的几种方式
往期推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配置文件详解 SpringBoot系列(四)web静 ...
- 错误:Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use.
Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use. The ...
- MySQL基础总结(二)
数据表的完整性约束条件 AUTO_INCREMENT (自增长) 注意事项: 1.一个表中只能有一个自增长字段 2.必须配合主键使用 方法1: 方法2: 方法3: 指定自增长初始值的方法: 修改自增长 ...
- search(12)- elastic4s-聚合=桶+度量
这篇我们介绍一下ES的聚合功能(aggregation).聚合是把索引数据可视化处理成可读有用数据的主要工具.聚合由bucket桶和metrics度量两部分组成. 所谓bucket就是SQL的GROU ...
- Code Review 常见的5个错误模式
原作者:Trisha Gee Code Review 的时候,每个人都会关心最佳实践,但最坏的实践有时可能会更有启示意义. Code Review是研发团队必不可少的,但并不总是正确的.这篇文章指出了 ...
- 第一行Kotlin系列(二)Intent隐式显式跳转及向下传值
1.Intent显式跳转页面 val button5 = findViewById<Button>(R.id.mButton5) button5.setOnClickListener { ...
- CF#358 D. Alyona and Strings DP
D. Alyona and Strings 题意 给出两个字符串s,t,让找出最长的k个在s,t不相交的公共子串. 思路 看了好几个题解才搞懂. 代码中有注释 代码 #include<bits/ ...
- [hdu5351]找规律,大整数模板
题意:f(1)="a",f(2)="b",f(i)=f(i-1)+f(i-2),"+"表示连接符.给定n,m,求f(n)的前m个字符的“ne ...