redis学习笔记9-哨兵

1. redis高可用原来

1.1. 主从模式的问题

    当主节点出现故障时,需要手动进行切换。

    手动切换步骤:

    1)手动将一个从节点晋升为主节点

    2)修改应用方的主节点地址

    3)通过命令的方式让他从节点去复制新的主节点

    4)老的主节点上线后,通过命令的方式让它去复制新的主节点

1.2 高可用方案-redis哨兵模式

    当主节点出现故障时,Redis Sentinel能自动完成故障发现和故障转移,并通知应用方,从而实现真正的高可用。建议使用2.8及以上版本。

 

Redis Sentinel模式是一个分布式架构,它包含若干个Sentinel节点和Redis数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他Sentinel节点进行“协商”,当大多数Sentinel节点都认为主节点不可达时,它们会选举出一个Sentinel节点来完成自动故障转移的工作,同时会将这个变化实时通知给Redis应用方。

    具体步骤:

    1)主节点出现故障,此时从节点与主节点失去连接,主从复制失败。

    2)每个Sentinel节点通过定期监控发现主节点出现了故障。

    3)多个Sentinel节点对主节点的故障达成一致,选举出某个Sentinel节点作为领导者负责故障转移。

    4)Sentinel领导者节点执行了故障转移,整个过程包括竞升某个从节点为主节点、其他从节点指向新的主节点进行同步,通知客户端新的主节点是谁,如果旧的主节点上线后,会被当成一个从节点指向新的主节点进行数据同步。

    注意:哨兵节点需要多个,建议至少3个,因为哨兵节点本身也需要高可用。

2. 安装和部署

2.1 部署Redis主从数据节点

    1 启动主节点

#主节点配置redis-6379.conf如下:
port 6379  
daemonize yes  
logfile "6379.log"
dbfilename "dump-6379.rdb"  
dir "/opt/soft/redis/data/" 
#启动主节点
redis-server redis-6379.conf
#验证是否启动起来
$ redis-cli -h 127.0.0.1 -p 6379 ping
PONG

    2. 启动从节点

#从节点配置 2个从节点  配置文件名分别为redis-6380.conf  redis-6381.conf
port 6380  
daemonize yes  
logfile "6380.log"  
dbfilename "dump-6380.rdb"  
dir "/opt/soft/redis/data/" 
slaveof 127.0.0.1 6379
#启动从节点
redis-server redis-6380.conf
redis-server redis-6381.conf
#验证
$ redis-cli -h 127.0.0.1 -p 6380 ping
PONG
$ redis-cli -h 127.0.0.1 -p 6381 ping
PONG

    3.确认主从关系

#从主节点角度查询
$ redis-cli -h 127.0.0.1 -p 6379 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=281,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=281,lag=0
.................
#从节点角度查询
$ redis-cli -h 127.0.0.1 -p 6380 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up

    2.2 部署Sentinel节点

1. 配置Sentinel节点

#配置文件 redis-sentinel-26379.conf redis-sentinel-26380.conf redis-sentinel-26381.conf 几个文件中需要修改下端口
port 26379  #Sentinel节点的默认端口是26379
daemonize yes  
logfile "26379.log"  
dir /opt/soft/redis/data  
sentinel monitor mymaster 127.0.0.1 6379 2  #mymaster是主节点的别名 主节点IP和端口  2代表判断主节点失败至少需要2个Sentinel节点同意
sentinel down-after-milliseconds mymaster 30000  #每个Sentinel节点定期发送ping命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过了30000(单位为毫秒)没有回应,则认为节点不可到达,将被判断为主管下线。
sentinel parallel-syncs mymaster 1  #在故障转移之后,每次向新的主节点发起复制操作的从节点个数 
sentinel failover-timeout mymaster 180000  #故障转移超时时间 
#启动 redis-sentinel 
redis-sentinel redis-sentinel-26379.conf #也可以使用redis-server redis-sentinel-26379.conf --sentinel
redis-sentinel redis-sentinel-26380.conf
redis-sentinel redis-sentinel-26381.conf
#验证 sentinel
$ redis-cli -h 127.0.0.1 -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3

    注意:

    1)生产环境中建议Redis Sentinel的所有节点和redis主从节点一样应该分布在不同的物理机上。

    2)Redis Sentinel中的数据节点和普通的Redis数据节点在配置上没有任何区别,只不过是添加了一些Sentinel节点对它们进行监控。

    3)sentinel的配置中不需要配置从节点和其他sentinel节点,sentinel会通过主节点发现对应的从节点和其他sentinel节点。

    当sentinel启动完成后,sentinel的配置文件将会发生变化,如下所示:

port 26379
daemonize yes
logfile "26379.log"
dir "/opt/soft/redis/data"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
# 发现两个 slave 节点
sentinel known-slave mymaster 127.0.0.1 6380
sentinel known-slave mymaster 127.0.0.1 6381
# 发现两个 sentinel 节点
sentinel known-sentinel mymaster 127.0.0.1 26380 282a70ff56c36ed56e8f7ee6ada74124140d6f53
sentinel known-sentinel mymaster 127.0.0.1 26381 f714470d30a61a8e39ae031192f1feae7eb5b2be
sentinel current-epoch 0

    2.3 监控多个主节点

只需要在sentinel的配置文件中配置多个主节点即可,如下所示:

sentinel monitor master1 10.10.10.1 6379 2 
sentinel down-after-milliseconds master1 60000 
sentinel failover-timeout master1 180000 
sentinel parallel-syncs master1 1
sentinel monitor master2 10.16.20.2 6380 2 
sentinel down-after-milliseconds master2 10000 
sentinel failover-timeout master2 180000 
sentinel parallel-syncs master2 1

    2.4 调整配置(不建议用)

    和普通的Redis数据节点一样,Sentinel节点也支持动态地设置参数,命令为:sentinel set <param> <value>,因为sentinel set命令只对当前Sentinel节点有效,而建议所有Sentinel节点的配置尽可能一致,这样在故障发现和转移时比较容易达成一致,因此不要用这个指令进行动态配置参数。

    2.5 sentinel使用建议

    1)Sentinel节点不应该部署在一台物理“机器”上。

    2)部署至少三个且奇数个的Sentinel节点。

    3)只有一套Sentinel,还是每个主节点配置一套Sentinel?如果Sentinel节点集合监控的是同一个业务的多个主节点集合,那么使用一套、否则一般建议采用每个主节点一套。

3. sentinel的API

    1. sentinel masters:展示所有被监控的主节点状态以及相关的统计信息

    2.sentinel master<master name> :展示指定<master name>的主节点状态以及相关的统计信息

    3.sentinel slaves<master name>:展示指定<master name>的从节点状态以及相关的统计信息

    4.sentinel sentinels<master name>:展示指定<master name>的Sentinel节点集合(不包含当前Sentinel节点)

    5.sentinel get-master-addr-by-name<master name>:返回指定<master name>主节点的IP地址和端口

    6.sentinel failover<master name>:对指定<master name>主节点进行强制故障转移(没有和其他Sentinel节点“协商”),当故障转移完成后,其他Sentinel节点按照故障转移的结果更新自身配置,这个命令在Redis Sentinel的日常运维中非常有用

    7.sentinel is-master-down-by-addr:Sentinel节点之间用来交换对主节点是否下线的判断,根据参数的不同,还可以作为Sentinel领导者选举的通信方式

4. 客户端连接

    4.1 redis sentinel 客户端实现原理:

    1)遍历Sentinel节点集合获取一个可用的Sentinel节点,可以从任意一个Sentinel节点获取主节点信息

    2)通过sentinel get-master-addr-by-name master-name这个API来获取对应主节点的相关信息

    3)验证当前获取的“主节点”是真正的主节点,这样做的目的是为了防止故障转移期间主节点的变化

    4)保持和Sentinel节点集合的“联系”,时刻获取关于主节点的相关“信息”

    4.2 Java操作Redis Sentinel

    Jedis针对Redis Sentinel给出了一个JedisSentinelPool,很显然这个连接池保存的连接还是针对主节点的。Jedis给出很多构造方法,其中最全的如下所示:

#注意:JedisSentinelPool和JedisPool一样,尽可能全局只有一个
public JedisSentinelPool(String masterName, Set<String> sentinels,
    final GenericObjectPoolConfig poolConfig, final int connectionTimeout, 
    final int soTimeout,
    final String password, final int database, 
    final String clientName)
#和JedisPool非常类似,我们在使用JedisSentinelPool时也要尽可能按照common-pool的标准模式进行代码的书写,如下所示:
Jedis jedis = null;
try {
    jedis = jedisSentinelPool.getResource();
    // jedis command
} catch (Exception e) {
    logger.error(e.getMessage(), e);
} finally {
    if (jedis != null)
        jedis.close(); #注意,用完后要及时归还到池中	
}

构造JedisSentinelPool步骤:

    1)遍历Sentinel节点集合,找到一个可用的Sentinel节点

    2)用可用的Sentinel节点,执行sentinelGetMasterAddrByName(masterName),找到对应主节点信息。jedis.sentinelGetMasterAddrByName(masterName);

    3)JedisSentinelPool中没有发现对主节点角色验证的代码,这是因为get-master-addr-by-name master-name这个API本身就会自动获取真正的主节点

    4)为每一个Sentinel节点单独启动一个线程,利用Redis的发布订阅功能,每个线程订阅Sentinel节点上切换master的相关频道+switch-master。

    注意:

    从节点一般有2个作用,主节点故障转移,扩展主节点的读能力,尤其是在读多写少的场景非常适用。目前JedisSentinelPool没有实现读写分离,如果需要读写分离,需要自己实现。

5.Redis Sentinel实现原理

    5.1 三个定时监控任务

    1)每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构。

        作用:

         通过向主节点执行info命令,获取从节点的信息,这也是为什么Sentinel节点不需要显式配置监控从节点。

        当有新的从节点加入时都可以立刻感知出来。

        节点不可达或者故障转移后,可以通过info命令实时更新节点拓扑信息。

    2)每隔2秒,每个Sentinel节点会向Redis数据节点的__sentinel__:hello频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息,同时每个Sentinel节点也会订阅该频道,来了解其他Sentinel节点以及它们对主节点的判断

        作用:

        发现新的Sentinel节点。

        Sentinel节点之间交换主节点的状态,作为后面客观下线以及领导者选举的依据。

    3)每隔1秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达。

    5.2 主观下线和客观下线

    1. 主观下线

    Sentinel节点会每隔1秒对主节点、从节点、其他Sentinel节点发送ping命令做心跳检测,当这些节点超过down-after-milliseconds没有进行有效回复,Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线。

    2. 客观下线

    当Sentinel主观下线的节点是主节点时,该Sentinel节点会通过sentinel is-master-down-by-addr命令向其他Sentinel节点询问对主节点的判断,当超过<quorum>个数的Sentinel节点都认为主节点有问题,这时该Sentinel节点会做出客观下线的决定。

    5.3 领导者Sentinel节点选举

    当Sentinel节点对于主节点已经做了客观下线后,所有的sentinel节点会做一个领导者选举的工作,选出一个Sentinel节点作为领导者进行故障转移。领导者选举的原理:

    1)每个在线的Sentinel节点都有资格成为领导者,当它确认主节点主观下线时候,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令,要求将自己设置为领导者。

    2)收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的sentinelis-master-down-by-addr命令,将同意该请求,否则拒绝。

    3)如果该Sentinel节点发现自己的票数已经大于等于max(quorum,num(sentinels)/2+1),那么它将成为领导者。

    5.4 故障转移

    1)在从节点列表中选出一个节点作为新的主节点,选择方法如下:

        a)过滤:“不健康”(主观下线、断线)、5秒内没有回复过Sentinel节点ping响应、与主节点失联超过down-after-milliseconds*10秒。

        b)选择从节点优先级最高的从节点列表,如果存在则返回,不存在则继续。

        c)选择复制偏移量最大的从节点(复制的最完整),如果存在则返回,不存在则继续。

        d)选择runid最小的从节点。

    2)Sentinel领导者节点会对第一步选出来的从节点执行slaveof no one命令让其成为主节点。

    3)Sentinel领导者节点会向剩余的从节点发送命令,让它们成为新主节点的从节点,并进行数据的复制。

    4)Sentinel节点集合会将原来的主节点更新为从节点,并保持着对其关注,当其恢复后命令它去复制新的主节点。

    注意:redis哨兵模式能解决redis高可用问题,但在执行故障转移时,会中断客户端请求,整个故障转移时间为:

    主观下线时间(down-after-milliseconds)+客观下线时间+选举时间+故障转移时间,除了主观下线时间外,其他步骤的时间很短,可忽略不计。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值