Redis技术探索「高可用架构模式」哨兵(sentinel)模式实现主从故障互切换模式详解

Posted 洛神灬殇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis技术探索「高可用架构模式」哨兵(sentinel)模式实现主从故障互切换模式详解相关的知识,希望对你有一定的参考价值。

哨兵(sentinel)模式实现主从故障互切换模式详解

Redis的多种模式

Redis的架构运行模式:单机模式、主从模式、哨兵模式、集群模式等。

Redis单机模式

只有一个Redis,启动起来,业务调用即可,单机在很多场景也是有使用的,例如在一个并非必须保证高可用的情况下。

Redis单机模式的优点

  • 部署简单
  • 成本低,没有备用节点,不需要其他的开支。
  • 高性能,单机不需要同步数据,数据天然一致性。

Redis单机模式的缺点

  • 可靠性保证不是很好,单节点有宕机的风险。
  • 单机高性能受限于CPU的处理能力,Redis是单线程的。
  • 单机模式选择需要根据自己的业务场景去选择,如果需要很高的性能、可靠性,单机就不太合适了。

Redis主从复制

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。
前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。

主从模式配置很简单,只需要在从节点配置主节点的ip和端口号即可。

旧版本配置

slaveof <masterip> <masterport># 例如# slaveof 192.168.1.214 6379

新版本配置

replicaof <masterip> <masterport># 例如# replicaof 192.168.1.214 6379

查看主节点信息

启动主从节点的所有服务,查看日志即可以看到主从节点之间的服务连接。

从上面很容易就想到一个问题,既然主从复制,意味着master和slave的数据都是一样的,有数据冗余问题。

在程序设计上,为了高可用性和高性能,是允许有冗余存在的。这点希望大家在设计系统的时候要考虑进去,不用为公司节省这一点资源。

对于追求极致用户体验的产品,是绝对不允许有宕机存在的。

主从模式在很多系统设计时都会考虑,一个master挂在多个slave节点,当master服务宕机,会选举产生一个新的master节点,从而保证服务的高可用性。

主从模式的优点

一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。扩展主节点的读能力,分担主节点读压力。

高可用基石:除了上述作用以外,主从复制还是哨兵模式和集群模式能够实施的基础,因此说主从复制是Redis高可用的基石。也有相应的缺点,比如我刚提到的数据冗余问题:

主从复制的弊端

  • 一旦主节点宕机,从节点 晋升成 主节点,同时需要修改 应用方 的 主节点地址,还需要命令所有 从节点 去 复制 新的主节点,整个过程需要人工干预。
  • 主节点 的 写能力 受到 单机的限制。
  • 主节点 的 存储能力 受到 单机的限制。

Redis哨兵模式

为了解决主从复制的诸多弊端,Redis出现了哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

分析哨兵结构组成

哨兵节点由两部分组成,哨兵节点和数据节点:

  • 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
  • 数据节点:主节点和从节点都是数据节点。

访问redis集群的数据都是通过哨兵集群的,哨兵监控整个redis集群。

一旦发现redis集群出现了问题,比如刚刚说的主节点挂了,从节点会顶上来。但是主节点地址变了,这时候应用服务无感知,也不用更改访问地址,因为哨兵才是和应用服务做交互的。

哨兵模式的主从切换

主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。

Redis哨兵模式的原理

  • Redis Sentinel是一个分布式系统, 在一个架构中运行多个Sentinel进程,这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。
  • Redis Sentinel 衍生出一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis 服务器, 你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动 Redis Sentinel 。

  1. 每个Sentinel以 每秒钟 一次的频率,向它所有的主服务器、从服务器以及其他Sentinel实例 发送一个PING 命令。

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

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

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

常规情况下

  • 在一般情况下, 每个 Sentinel 会以每10秒一次的频率,向它已知的所有主服务器和从服务器 发送 INFO 命令。

  • 当一个 主服务器被 Sentinel标记为 客观下线 时,Sentinel向下线主服务器的所有从服务器 发送 INFO 命令的频率,会从10秒一次改为每秒一次。

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

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

故障切换(failover)的过程

  • 假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。
  • 当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。
  • master节点切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主服务器,这个过程称为客观下线。
  • 这样对于客户端而言,一切都是透明的,当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

Redis-Sentinel的作用

Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:

  • 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。(通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
  • 提醒(Notification):当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • 自动故障迁移(Automatic failover): 当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。
主:6379   ,sentinel:26379

从:6380   ,sentinel:26380

从:6381   ,sentinel:26381

Redis的多哨兵运行模式

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

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

Redis 哨兵模式的配置

当主宕机了从接替主成为新的主,宕机的主启动后自动变成了从,其实它和mysql的双主模式是一样的互为主从;redis哨兵需要用到redis-sentinel程序和sentinel.conf配置文件。

Redis主节点服务配置

vim redis.conf
查看配置信息
daemonize yes
pidfile /usr/local/redis/6379/redis_6379.pid
port 6379
tcp-backlog 128
timeout 0
tcp-keepalive 0
loglevel notice
logfile ""
databases 16
save 900 1    ###save
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb   ###dbfile
dir "/usr/local/redis/6379"
masterauth "123456"
requirepass "123456"
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
重点配置
跨网络访问
bind 0.0.0.0
设置密码
requirepass "123456"

Redis从服务器配置

配置Redis服务器,从服务器比主服务器多一个slaveof/replicaof的配置和密码。

指定主服务器
replicaof/slaveof 192.168.11.128 6379

注意:有关replicaof/slaveof的配置只是配置从服务器,主服务器不需要配置

主服务器密码
masterauth 123456
禁止保护模式
protected-mode no

配置监听的主服务器,

sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,192.168.11.128代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。

sentinel monitor mymaster 192.168.11.128 6379 2

sentinel author-pass定义服务的密码

  • sentinel auth-pass
sentinel auth-pass mymaster 123456

mymaster是服务名称,123456是Redis服务器密码

临时配置执行方式

可以登入哨兵(两台哨兵都需要登入执行),添加主从监控信息

redis-cli -p 6000
sentinel monitor mymaster 192.168.137.40 6379 2
sentinel set mymaster down-after-milliseconds 5000
sentinel set mymaster failover-timeout 15000
sentinel set mymaster auth-pass 123456
查看配置哨兵信息
vim sentinel.conf
port 6000
dir "/usr/local/redis/sentinel"
# 守护进程模式
daemonize yes
protected-mode no
logfile "/usr/local/sentinel/sentinel.log"
知识点汇总
  1. 应用程序连接到哨兵端口,通过指定不同的master名称连接到具体的主副本。

  2. 哨兵配置文件中只需要配置主从复制中的主副本ip和端口即可,当主从进行切换时哨兵会自动修改哨兵配置文件中的主副本ip为新在主副本ip。

  3. 一个哨兵配置文件中可以同时配置监控多个主从复制。

  4. 单个哨兵就可以用来进行主从故障监控,但是如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换(单点问题);这个2代表投票数,当2个sentinel认为一个master已经不可用了以后,将会触发failover,才能真正认为该master已经不可用了。(sentinel集群中各个sentinel也有互相通信,通过gossip协议);所以合理的配置应该是同时启动多个哨兵进程,并且最好是在不同的服务器中启动。

mymaster的需要在整个网络环境都是唯一的,哨兵之间会自动通过mastername去建立关联关系只要网络环境是相通的。

使得Redis服务器可以跨网络访问

启动Redis服务器进程

./redis-server ../redis.conf

启动哨兵进程

./redis-sentinel ../sentinel.conf

哨兵模式的总结

Sentinel解决了故障转移,在高可用方面又上升了一个台阶,当然Sentinel还有其他功能。比如,主节点存活检测、主从运行情况检测、主从切换。Redis的Sentinel最小配置是 一主一从。

Java中使用哨兵模式

public class TestSentinels 
    @SuppressWarnings("resource")
    @Test
    public void testSentinel() 
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(10);
        jedisPoolConfig.setMaxIdle(5);
        jedisPoolConfig.setMinIdle(5);
        // 哨兵信息
        Set<String> sentinels = new HashSet<>(Arrays.asList("192.168.11.128:26379",
                "192.168.11.129:26379","192.168.11.130:26379"));
        // 创建连接池
        JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels,jedisPoolConfig,"123456");
        // 获取客户端
        Jedis jedis = pool.getResource();
        // 执行两个命令
        jedis.set("mykey", "myvalue");
        String value = jedis.get("mykey");
        System.out.println(value);
    

配置项参数类型作用
port整数启动哨兵进程端口
dir文件夹目录哨兵进程服务临时文件夹,默认为/tmp,要保证有可写入的权限
sentinel down-after-milliseconds<服务名称><毫秒数(整数)>指定哨兵在监控Redis服务时,当Redis服务在一个默认毫秒数内都无法回答时,单个哨兵认为的主观下线时间,默认为30000(30秒)
sentinel parallel-syncs<服务名称><服务器数(整数)>指定可以有多少个Redis服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求越高
sentinel failover-timeout<服务名称><毫秒数(整数)>指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟
sentinel notification-script<服务名称><脚本路径>指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,比较常用
sentinel down-after-milliseconds
  • 配置项只是一个哨兵在超过规定时间依旧没有得到响应后,会自己认为主机不可用。对于其他哨兵而言,并不是这样认为。

  • 哨兵会记录这个消息,当拥有认为主观下线的哨兵达到sentinel monitor所配置的数量时,就会发起一次投票,进行failover,此时哨兵会重写Redis的哨兵配置文件,以适应新场景的需要。

参考资料

https://blog.csdn.net/yaooch/article/details/80167571

https://www.cnblogs.com/kerwinC/p/6069864.html

https://www.cnblogs.com/chenmh/p/5578376.html

https://baijiahao.baidu.com/s?id=1675905732497463340&wfr=spider&for=pc

下期预告


以上是关于Redis技术探索「高可用架构模式」哨兵(sentinel)模式实现主从故障互切换模式详解的主要内容,如果未能解决你的问题,请参考以下文章

Redis高可用架构之哨兵模式 - Sentinel

Redis高可用集群方案(主从复制,哨兵模式,Redis集群)

高可用集群架构——redis的主从复制与哨兵模式,cluster

三分钟带你入门redis高可用架构之哨兵模式,一文轻松搞定

RedisRedis高可用之Sentinel哨兵模式详解(Redis专栏启动)

Redis架构第三天:哨兵模式理论+实践总结