Sentinel(redis 哨兵)

Sentinel (哨兵,实现 redis 的主从宕机情况下的角色切换)

哨兵其实是一个独立的服务他会有自己的进程 Sentinel 进程是用于监控 redis 集群中 Master 主服务器工作的状态,在Master主服务器发生故障的时候,可以实现 Master 和 Slave 服务器的切换,保证系统的高可用,其已经被集成在 redis2.6+ 的版本中,Redis 的哨兵模式到了2.8 版本之后就稳定了下来。一般在生产环境也建议使用Redis的2.8版本的以后版本。哨兵(Sentinel) 是一个分布式系统,可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossip protocols)来接收关于Master 主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。

每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定配置时间(可配置的)内未得到回应这个时间可以修改,则暂时认为对方已掉线,也就是所谓的”主观认为宕机” ,主观是每个成员都具有的独自的而且可能相同也可能不同的意识,英文名称:Subjective Down, 简称SDOWN。

有主观宕机,肯定就有客观宕机。当 “哨兵群” 中的多数 Sentinel 进程在对 Master 主服务器做出 SDOWN 的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的 Master Server 下线判断,这种方式就是“客观宕机”,客观是不依赖于某种意识而已经实际存在的一切事物,英文名称是:Objectively Down, 简称 ODOWN 。通过一定的 vote 算法,从剩下的 slave 从服务器节点中,选一台提升为 Master 服务器节点,然后自动修改相关配置配置文件以避免 redis 服务重启之后配置丢失,并开启故障转移(failover)。

Sentinel 机制可以解决master和slave角色的切换问题。

4.2.2 在 Redis 主从节点上实现哨兵机制

跑集群一般是基数的主机总数。一般是3、5、7等等。如果10.0.0.7 这个master主机宕机了。就会从下面的 10.0.0.17 和 10.0.0.27 主机上选举一个新的 master。假如这时候将10.0.0.17 这个主机选举成了新的 master 而10.0.0.27 这个主机就会自动将 master 节点指定为了 10.0.0.27 这个主机。我们之所以要使用三个主机是为了实现master主节点宕机之后的高可用。哨兵实现的前提是一主两从的结构要先配置好。然后我们再在这个主从结构上配置哨兵。哨兵可以是独立的机器也可以和他们这三个主从主机一起混用。

4.2.2.1 配置 redis 主从结构

需要手动先指定某一台Redis服务器为master,然后将其他slave服务器使用命令配置为master服务器的slave,哨兵 的前提是已经手动实现了一个redis master-slave的运行环境。

将 B7 和 C7 主机的 master 主节点指向 A7 ,先配置好 redis 主从结构

4.2.2.1.1 将 B7 主机的 master 指向 A7

1、修改配置文件

[10:18:30 root@b7 ~]#vim /apps/redis/etc/redis.conf 

replicaof 10.0.0.7 6379     # 需要同步的 master 节点 ip 和 6379 端口
masterauth 12345            # master 节点的 redis 登录密码

2、重启 redis 使其生效

[10:22:03 root@b7 ~]#systemctl restart redis

3、登录 redis 终端,通过info replication命令查看已经实现主从同步

[10:22:10 root@b7 ~]#redis-cli -a 12345
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.7        # 指定了 master ip
master_port:6379            # 指定了 master 的 redis 服务端口
4.2.2.1.2 将 C7 主机的 master 指向 A7

1、修改 redis 配置文件

[10:22:23 root@C7 ~]#vim /apps/redis/etc/redis.conf 

replicaof 10.0.0.7 6379     # 需要同步的 master 节点 ip 和 6379 端口
masterauth 12345            # master 节点的 redis 登录密码

2、重启 redis 使其生效

[10:24:18 root@C7 ~]#systemctl restart redis

3、登录 redis 终端,通过info replication命令查看已经实现主从同步

[10:24:23 root@C7 ~]#redis-cli  -a 12345
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.7        # 指定了 master ip
master_port:6379            # 指定了 master 的 redis 服务端口

4.2.2.2 配置哨兵

4.2.2.2.1 在 A7 服务器上配置哨兵

配置好了 redis 的主从之后我们将配置哨兵。在 redis 的解压目录下就有一个 sentinel.conf(哨兵的配置文件)

# 进入到 redis 解压目录
[10:19:02 root@a7 ~]#cd /usr/local/src/redis-6.0.8/

# 通过 ll 查看
[10:28:02 root@a7 redis-6.0.8]#ll
total 284
-rw-rw-r--  1 root root 96706 Sep 10 19:09 00-RELEASENOTES
-rw-rw-r--  1 root root    51 Sep 10 19:09 BUGS
-rw-rw-r--  1 root root  2381 Sep 10 19:09 CONTRIBUTING
-rw-rw-r--  1 root root  1487 Sep 10 19:09 COPYING
drwxrwxr-x  6 root root   192 Sep 23 20:03 deps
-rwxrwxrwx  1 root root    92 Sep 23 20:50 dump.rdb
-rw-rw-r--  1 root root    11 Sep 10 19:09 INSTALL
-rw-rw-r--  1 root root   151 Sep 10 19:09 Makefile
-rw-rw-r--  1 root root  6888 Sep 10 19:09 MANIFESTO
-rw-rw-r--  1 root root 20987 Sep 10 19:09 README.md
-rw-rw-r--  1 root root 84642 Sep 10 19:09 redis.conf
-rwxrwxr-x  1 root root   275 Sep 10 19:09 runtest
-rwxrwxr-x  1 root root   280 Sep 10 19:09 runtest-cluster
-rwxrwxr-x  1 root root   761 Sep 10 19:09 runtest-moduleapi
-rwxrwxr-x  1 root root   281 Sep 10 19:09 runtest-sentinel
-rw-rw-r--  1 root root 10743 Sep 10 19:09 sentinel.conf        # 这是哨兵的配置文件
drwxrwxr-x  3 root root  8192 Sep 23 20:13 src
drwxrwxr-x 11 root root   182 Sep 10 19:09 tests
-rw-rw-r--  1 root root  3055 Sep 10 19:09 TLS.md
drwxrwxr-x  9 root root  4096 Sep 10 19:09 utils

1、将哨兵配置文件拷贝到 redis 的配置文件目录下/apps/redis/etc/

[10:28:07 root@a7 redis-6.0.8]#cp sentinel.conf /apps/redis/etc/

2、修改 A7 主机上的哨兵配置文件,这些参数我这里都是通过自己手动添加

[10:29:47 root@a7 redis-6.0.8]#vim /apps/redis/etc/sentinel.conf 
bind 0.0.0.0                                    # 所有 ip 皆可监听
port 26379                                      # 哨兵监听端口
daemonize yes                                   # 开启后台运行
pidfile "redis-sentinel.pid"
logfile "sentinel_26379.log"                    #日志文件名
dir "/apps/redis/logs"                          #日志文件路径
sentinel monitor mymaster 10.0.0.7 6379 2   #法定人数限制(quorum),即有几个slave认为。一旦哨兵认为我们的所有redis集群主机只有两台的话我们就进行master down了就进行故障转移(这个地址写master主机的ip)
sentinel auth-pass mymaster 12345               #(写master主机的redis密码)
sentinel down-after-milliseconds mymaster 30000 #3000毫秒(SDOWN)主观下线的时间
sentinel parallel-syncs mymaster 1              #发生故障转移时候同时向新master同步数据的slave数量,数字越小总同步时间越长(这个是当master宕机了之后我们进行一个一个的去同步数据,这是降低master的同步压力)
sentinel failover-timeout mymaster 180000       #所有slaves指向新的master所需的超时时间
sentinel deny-scripts-reconfig yes              #禁止修改脚本这个在特定场景上才会用上,一般会改为yes
4.2.2.2.2 将 A7 节点哨兵配置文件分发至后端 redis slave 节点

拷贝到后端两台从节点主机上之后,我们要到后端的从节点主机上去进行验证是否有相同的目录,如过没有我们还需要是手动创建

再将这个哨兵配置文件分别拷贝到后端的两个 redis 从节点主机上,并且放到和 redis 配置文件一个路径下面

# 拷贝至 10.0.0.17 节点
[10:41:05 root@a7 redis-6.0.8]#scp /apps/redis/etc/sentinel.conf 10.0.0.17:/apps/redis/etc/sentinel.conf

# 拷贝至 10.0.0.27 节点
[10:41:32 root@a7 redis-6.0.8]#scp /apps/redis/etc/sentinel.conf 10.0.0.27:/apps/redis/etc/sentinel.conf
4.2.2.2.3 启动哨兵

使用redis-sentinel 后面跟sentinel.cof 哨兵的配置文件将哨兵服务启动起来,而且所有的redis主从服务器上都要快速启动哨兵服务,不然会超时导致启动失败

1、在 A7 节点上启动哨兵

# 启动哨兵
[10:41:37 root@a7 redis-6.0.8]#/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf

# 通过 ss 查看 26379 端口已开启
[10:44:51 root@a7 redis-6.0.8]#ss -ntl | grep 26379
LISTEN     0      511          *:26379                    *:*

2、在 B7 节点上启动哨兵

# 启动哨兵
[10:43:47 root@b7 ~]#/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf

# 哨兵监听端口已开启
[10:43:48 root@b7 ~]#ss -ntl | grep 26379
LISTEN     0      128          *:26379                    *:*

3、在 C7 节点上启动哨兵

# 启动哨兵
[10:22:19 root@C7 ~]#/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf

# 哨兵监听端口开启
[10:43:51 root@C7 ~]#ss -ntl | grep 26379
LISTEN     0      128          *:26379                    *:*

4.2.2.3 验证哨兵是否正常运行

端口起来之后我们查看哨兵的日志里面是否记录了哨兵的启动过程观察是否监控了后端两台从服务器二台 slave 的 ip

1、我们在 A7 也就是 redis master 节点上查看

这个 + 表示我们后端的 slave 从节点以启动。如果是 redis 服务宕机了就会出现 - 符号

[10:45:00 root@a7 redis-6.0.8]#cat /apps/redis/logs/sentinel_26379.log 
2550:X 12 Oct 2020 10:43:43.767 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2550:X 12 Oct 2020 10:43:43.767 # Redis version=6.0.8, bits=64, commit=00000000, modified=0, pid=2550, just started
2550:X 12 Oct 2020 10:43:43.767 # Configuration loaded
2550:X 12 Oct 2020 10:43:43.768 * Running mode=sentinel, port=26379.
2550:X 12 Oct 2020 10:43:43.769 # Sentinel ID is d1fed79c4f3e8a51d60b763fb9b36a3bef165a4b
2550:X 12 Oct 2020 10:43:43.770 # +monitor master mymaster 10.0.0.7 6379 quorum 2
2550:X 12 Oct 2020 10:43:43.771 * +slave slave 10.0.0.17:6379 10.0.0.17 6379 @ mymaster 10.0.0.7 6379
2550:X 12 Oct 2020 10:43:43.772 * +slave slave 10.0.0.27:6379 10.0.0.27 6379 @ mymaster 10.0.0.7 6379
2550:X 12 Oct 2020 10:43:50.567 * +sentinel sentinel 95db09f161fcfa223b9973c1e6cc122c7ac9497a 10.0.0.17 26379 @ mymaster 10.0.0.7 6379
2550:X 12 Oct 2020 10:43:54.105 * +sentinel sentinel 6d64e9828df6e2f3252f91c5d38c52b83d4453f4 10.0.0.27 26379 @ mymaster 10.0.0.7 6379

2、也可用在 master 的服务器上通过 redis-cli -p 26379 指定访问哨兵的 redis 服务,然后在输入 info Sentinel 查看哨兵信息

# 登录 redis 哨兵终端
[10:48:38 root@a7 redis-6.0.8]#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
master0:name=mymaster,status=ok,address=10.0.0.7:6379,slaves=2,sentinels=3

4.2.2.4 通过测试哨兵是否能够进行选举新的 master 服务

测试阶段

1、哨兵是否发现master宕机了

2、哨兵是否能够从剩下的两个slave服务当中选举出一个新的master

3、还剩一个slave的主机是否能够将master指定为新的主节点

4.2.2.4.1 将 A7 节点 redis 宕机

1、先通过 tail 命令监控哨兵日志

[11:41:01 root@a7 ~]#tail -f /apps/redis/logs/sentinel_26379.log 

2、将A7主机的 redis 服务停了观察 A7 主机的哨兵日志.

[11:41:22 root@a7 redis-6.0.8]#systemctl stop redis

3、通过哨兵日志我们可以看到

4、到 C7 主机上链接 redis 服务通过输入 info Replication 可以看到现在他就是 master 节点,并且从节点是我们的 10.0.0.17 主机

127.0.0.1:6379> exit
[11:45:13 root@C7 ~]#redis-cli  -a 12345
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.17,port=6379,state=online,offset=54243,lag=1
master_replid:7df0381ffc4336fd3c1db54ce6748fea721f9733
master_replid2:c1a1f4896304a7b7453efa8fd6be8864cd1b2ca3
master_repl_offset:54509
second_repl_offset:15086
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:141
repl_backlog_histlen:54369

从而实现了哨兵的监控以及自动找去 master 节点

4.2.2.4.2 故障转移后的哨兵配置文件

故障转移后redis.conf中的replicaof行的master IP会被修改,sentinel.conf中的sentinel monitor IP会被修改。

4.2.2.5 添加新的 redis 主机到哨兵集群中

假如这时候A7主机的redis服务器已经修改好,但是不能直接启动因为 A7 主机已经是 master 节点服务了,所以直接启就会出错发生冲突。所以启动之前要将 A7 主机的配置文件 slaveof 改为当前被选举出来的 master 节点ip。然后再将 masterauth 的密码指定为 C7 的密码,所以我们的三个redis服务链接密码一定要相同。因为一旦发生了主从身份切换之后,我们其他链接redis服务的应用就 会使用以前的密码进行链接如果密码不一样的话就会连接不上A7主机上的reids服务。

1、修改 A7 主机配置文件,指定 master 节点和 密码

[11:41:26 root@a7 redis-6.0.8]#vim /apps/redis/etc/redis.conf 

# 指定新选举出来的 C7 主机 ip 端口为 master
replicaof 10.0.0.27 6379
masterauth 12345

2、重启 redis

[11:49:02 root@a7 redis-6.0.8]#systemctl restart redis

3、链接到reids服务中通过INFO Replication 查看现在状态已经是 slave 主机节点为 C7

[11:49:11 root@a7 redis-6.0.8]#redis-cli -a 12345
127.0.0.1:6379> INFO replication
# Replication
role:slave                          # 身份为 slave
master_host:10.0.0.27               # master 节点已经指定为了 C7 主机
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:126012
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:7df0381ffc4336fd3c1db54ce6748fea721f9733
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:126012
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:100734
repl_backlog_histlen:25279
4.2.2.5.1 观察 C7 主机的哨兵日志

然后再通过观察 C7 主机的哨兵日志,就会发现已经将A7主机添加到了主从服务中

[11:40:11 root@C7 ~]#cat /apps/redis/logs/sentinel_26379.log 

而且 B7 主机上 redis 的主从配置已经改为了 C7 ip

点赞