目录

Redis-哨兵模式详解实现高可用与自动故障转移

Redis 哨兵模式详解:实现高可用与自动故障转移


引言

在现代分布式系统中, 高可用性 是一个至关重要的需求。Redis 作为一个高性能的内存数据库,提供了 哨兵模式(Sentinel Mode) ,用于实现 Redis 的高可用性和自动故障转移。通过哨兵模式,Redis 可以在主节点故障时自动将从节点提升为新的主节点,从而保证系统的持续运行。


1. 什么是 Redis 哨兵模式?

1.1 定义

Redis 哨兵模式是一种高可用性解决方案,通过部署多个哨兵节点来监控 Redis 主从节点的状态,并在主节点故障时自动进行故障转移。

1.2 核心概念

  • 主节点(Master) :负责处理写操作,并将数据同步到从节点。
  • 从节点(Slave) :复制主节点的数据,并提供读操作。
  • 哨兵节点(Sentinel) :监控 Redis 节点的状态,并在主节点故障时进行故障转移。

2. Redis 哨兵模式的工作原理

主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。Redis从2.8开始正式提供了Sentinel(哨兵)架构来解决这个问题。 谋朝篡位的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。 哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独 立运行。其原理是 哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例

2.1 监控

哨兵节点会定期向 Redis 主从节点发送心跳检测,以监控它们的状态。

2.2 故障检测

如果哨兵节点检测到主节点不可用,它会通知其他哨兵节点进行确认。

2.3 故障转移

当多数哨兵节点确认主节点故障后,哨兵节点会选举一个从节点作为新的主节点,并更新其他从节点的配置。

2.4 通知

哨兵节点会通知客户端新的主节点地址,客户端可以重新连接到新的主节点。

https://i-blog.csdnimg.cn/direct/5ac6717945f54fc29f2dcace84af9f92.png

这里的哨兵有两个作用:

1.通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。

2.当哨兵监测到master宕机,会自动将slave切换成master,然后通过 发布订阅模式 通知其他的从服务器,修改配置文件,让它们切换主机。

然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。 各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

https://i-blog.csdnimg.cn/direct/2ab45cff6de54918af11c80feb373383.png

假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认 为主服务器不可用,这个现象成为 主观下线 。当后面的哨兵也检测到主服务器不可用,并且数量达到一 定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover[故障转移]操作。 切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为 客观下线。

3. Redis 哨兵模式的配置方法

3.1 配置文件

每个哨兵节点需要一个配置文件,通常命名为 sentinel.conf 。以下是一个简单的哨兵配置文件示例:

sentinel.conf

port 26379

sentinel monitor mymaster 127.0.0.1 6379 2

sentinel down-after-milliseconds mymaster 5000

sentinel failover-timeout mymaster 10000

sentinel parallel-syncs mymaster 1

  • port :哨兵节点的端口号。
  • sentinel monitor :监控的主节点名称、IP 地址、端口号和法定人数。
  • sentinel down-after-milliseconds :主节点不可用的超时时间。
  • sentinel failover-timeout :故障转移的超时时间。
  • sentinel parallel-syncs :故障转移时并行同步的从节点数量。

3.2 启动哨兵节点

启动哨兵节点的命令如下:

redis-sentinel /path/to/sentinel.conf


4. Redis 哨兵模式的使用场景

4.1 高可用性

通过哨兵模式,Redis 可以在主节点故障时自动进行故障转移,从而保证系统的高可用性。

4.2 自动故障转移

哨兵模式可以自动检测主节点故障并进行故障转移,减少人工干预。

4.3 读写分离

通过哨兵模式,可以将读操作分发到从节点,从而分担主节点的负载。


5. Redis 哨兵模式的优缺点

5.1 优点

  • 高可用性 :通过自动故障转移实现高可用性。
  • 自动故障检测 :自动检测主节点故障并进行故障转移。
  • 读写分离 :支持读写分离,分担主节点的负载。

5.2 缺点

  • 配置复杂 :哨兵模式的配置相对复杂,需要部署多个哨兵节点。
  • 数据丢失 :在主节点故障时,可能会丢失部分未同步的数据。
  • 性能开销 :哨兵节点会定期监控 Redis 节点的状态,增加一定的性能开销。

6. Redis 哨兵模式的实际应用示例

6.1 配置 Redis 主从复制

首先,配置 Redis 主从复制。假设我们有一个主节点和两个从节点:

主节点配置
# redis-master.conf
port 6379
从节点配置
# redis-slave1.conf
port 6380
replicaof 127.0.0.1 6379

# redis-slave2.conf
port 6381
replicaof 127.0.0.1 6379

启动主节点和从节点:

redis-server /path/to/redis-master.conf
redis-server /path/to/redis-slave1.conf
redis-server /path/to/redis-slave2.conf

6.2 配置哨兵节点

接下来,配置三个哨兵节点:

哨兵节点 1 配置
# sentinel1.conf
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1
哨兵节点 2 配置
# sentinel2.conf
port 26380
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1
哨兵节点 3 配置
# sentinel3.conf
port 26381
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

启动哨兵节点:

redis-sentinel /path/to/sentinel1.conf
redis-sentinel /path/to/sentinel2.conf
redis-sentinel /path/to/sentinel3.conf

6.3 模拟故障转移

手动停止主节点,观察哨兵节点是否能够自动进行故障转移:

redis-cli -p 6379 shutdown

查看哨兵日志,确认故障转移过程:

tail -f /path/to/sentinel1.log

问题:如果之前的master 重启回来,会不会双master 冲突?

之前的回来只能做小弟了


7. Redis 哨兵模式的常见问题

7.1 哨兵节点数量

哨兵节点的数量应为奇数,以确保在故障检测和故障转移时能够达成多数共识。

7.2 数据丢失

在主节点故障时,可能会丢失部分未同步的数据。可以通过配置 min-slaves-to-writemin-slaves-max-lag 参数来减少数据丢失的风险。

7.3 客户端重连

客户端需要支持哨兵模式,能够在主节点故障时重新连接到新的主节点。


8. Redis 哨兵模式的替代方案

虽然 Redis 哨兵模式功能强大,但在某些场景下可能需要更高级的功能或更简单的解决方案。以下是一些常见的替代方案:

  • Redis Cluster :提供分布式存储和自动分片功能,适合大规模数据存储场景。
  • Twemproxy :一个轻量级的代理工具,用于实现 Redis 的高可用性和负载均衡。

哨兵配置说明

 # Example sentinel.conf
 # 哨兵sentinel实例运行的端口 默认26379
 port 26379
 # 哨兵sentinel的工作目录
dir /tmp
 # 哨兵sentinel监控的redis主节点的 ip port 
# master-name  可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。
# 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 连接主从的密码 注意必须为主从设置一样的验证密码
# sentinel auth-pass <master-name> <password>
 sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
 # 指定多少毫秒之后 主节点没有应答哨兵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
 # SCRIPTS EXECUTION
 #配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮
件通知相关人员。
#对于脚本的运行结果有以下规则:
#若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
 #若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
#如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
#一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执
行。
#通知型脚本:当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等
等),将会去调用这个脚本,这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常
运行的信息。调用该脚本时,将传给脚本两个参数,一个是事件的类型,一个是事件的描述。如果
sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执
行的,否则sentinel无法正常启动成功。
#通知脚本
# sentinel notification-script <master-name> <script-path>
 sentinel notification-script mymaster /var/redis/notify.sh
 # 客户端重新配置主节点参数脚本
# 当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master
地址已经发生改变的信息。
# 以下参数将会在调用脚本时传给脚本:
 # <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
 # 目前<state>总是“failover”,
 # <role>是“leader”或者“observer”中的一个。 
# 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的
slave)通信的
# 这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentinel client-reconfig-script <master-name> <script-path>
 sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

9. 总结

Redis 哨兵模式是一种高效、可靠的高可用性解决方案,适用于需要自动故障转移和读写分离的场景。