zoukankan      html  css  js  c++  java
  • Redis哨兵(高可用)搭建

    一、redis高可用--sentinel哨兵

    1.sentinel介绍

    Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,
    Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。
    
    #必须在redis主从已经做好的前提下
    

    2.sentinel的构造

    Sentinel 是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作。
    

    3.sentinel的功能

    1.监控(Monitoring):
    Sentinel会不断地检查你的主服务器和从服务器是否运作正常。
    
    2.提醒(Notification):
    当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。
    
    3.自动故障迁移(Automatic failover):
    当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,
    并让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器。
    

    4.sentinel的具体工作

    1.Sentinel通过用户给定的配置文件来发现主服务器
    2.Sentinel会与被监视的主服务器创建两个网络连接:
        命令连接用于向主服务器发送命令。
        订阅连接用于订阅指定的频道,从而发现监视同一主服务器的其他Sentinel。
    3.Sentinel通过向主服务器发送INFO命令来自动获得所有从服务器的地址。
    4.发现其他sentinel
    	Sentinel 会通过命令连接向被监视的主从服务器发送 “HELLO” 信息,该消息包含 Sentinel 的 IP、端口号、ID 等内容,以此来向其他 
    Sentinel 宣告自己的存在。与此同时Sentinel 会通过订阅连接接收其他 Sentinel 的“HELLO” 信息,以此来发现监视同一个主服务器的其他 Sentinel 。
    5.多个Sentinel之间只会互相创建命令连接,用于进行通信。因为已经有主从服务器作为发送和接收HELLO信息的中介,所以Sentinel之间不会创建订阅连接。
    6.检测实例的状态:
    	Sentinel使用PING命令来检测实例的状态:如果实例在指定的时间内没有返回回复,或者返回错误的回复,那么该实例会被 Sentinel 判断为下线。
    	Redis的Sentinel中关于下线(down)有两个不同的概念:
    	1)主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。
    	2)客观下线(Objectively Down,简称 ODOWN)指的是多个Sentinel实例在对同一个服务器做出SDOWN判断,
    并且通过SENTINEL is-master-down-by-addr命令互相交流之后,得出的服务器下线判断。(一个 Sentinel可以通过向另一个Sentinel发送SENTINEL is-master-down-by-addr命令来询问对方是否认为给定的服务器已下线。)
    

    5.故障转移流程

    一次故障转移操作由以下步骤组成:
    1.发现主服务器已经进入客观下线状态。
    2.基于Raft leader election协议,进行投票选举(也就是在多个sentinel中选出一个领头羊)
    3.如果当选失败,那么在设定的故障迁移超时时间的两倍之后,重新尝试当选。如果当选成功,那么执行以下步骤。
    	1)选出一个从服务器,并将它升级为主服务器。
    	2)向被选中的从服务器发送 SLAVEOF NO ONE 命令,让它转变为主服务器。
    	3)通过发布与订阅功能,将更新后的配置传播给所有其他Sentinel,其他Sentinel对它们自己的配置进行更新。
    	4)向已下线主服务器的从服务器发送SLAVEOF命令,让它们去复制新的主服务器。
    	5)当所有从服务器都已经开始复制新的主服务器时, leader Sentinel 终止这次故障迁移操作。
    

    6.sentinel选择主库的规则

    1.在失效主服务器属下的从服务器当中,那些被标记为主观下线、已断线、或者最后一次回复PING命令的时间大于五秒钟的从服务器都会被淘汰。
    2.在失效主服务器属下的从服务器当中,那些与失效主服务器连接断开的时长超过down-after选项指定的时长十倍的从服务器都会被淘汰。
    3.在经历了以上两轮淘汰之后剩下来的从服务器中,我们选出复制偏移量(replication offset)最大的那个从服务器作为新的主服务器;如果复制偏移量不可用,
    或者从服务器的复制偏移量相同,那么带有最大运行ID的那个从服务器成为新的主服务器。
    
    # 总结:
    · 当主宕机,一般会在活着的从中选举新主,选举一般按偏移量(也就是数据量)和id来决定谁是新主,如果想要优先谁为新主,只需在对应配置文件中修改id值大于其他从服务器即可。
    

    7.sentinel特性

    1.Sentinel自动故障迁移使用Raft算法来选举领头(leader)Sentinel ,从而确保在一个给定的周期(epoch)里,只有一个领头产生。
    2.这表示在同一个周期中,不会有两个 Sentinel 同时被选中为领头,并且各个 Sentinel 在同一个节点中只会对一个领头进行投票。
    3.更高的配置节点总是优于较低的节点,因此每个 Sentinel 都会主动使用更新的节点来代替自己的配置。
    
    #简单来说,我们可以将Sentinel配置看作是一个带有版本号的状态。一个状态会以最后写入者胜出(last-write-wins)的方式(也即是,最新的配置总是胜出)传播至所有其他Sentinel。
    

    二、sentinel实战

    1.环境准备

    角色 主机 IP 端口
    主库 db01 172.16.1.51 6379
    从库 db02 172.16.1.52 6379
    从库 db03 172.16.1.53 6379

    2.准备主从状态

    #主库查看
    172.16.1.51:6379> info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=172.16.1.52,port=6379,state=online,offset=4229,lag=1
    slave1:ip=172.16.1.53,port=6379,state=online,offset=4229,lag=1
    master_repl_offset:4229
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:2
    repl_backlog_histlen:4228
    

    3.配置sentinel哨兵

    #创建目录(随便创建)
    [root@db01 ~]# mkdir /service/redis/26379
    
    #编辑sentinel配置文件
    [root@db01 ~]# vim /service/redis/26379/sentinel.conf
    port 26379									        # 指定sentinel端口
    daemonize yes										# 指定为后台启动
    pidfile /service/redis/26379/sentinel.pid			                        # pid文件路径
    logfile /service/redis/26379/sentinel.log			                        # 日志文件路径
    dir /service/redis/26379							        # 工作目录
    bind 172.16.1.51 127.0.0.1						                # 监听端口
    sentinel monitor mymaster 172.16.1.52 6379  1                                           # 指定主服务器地址和端口,1为sentinel数量,需为服务器数量的n/2+1,
    但这里只有一台服务器做测试,所以直接写1即可
    sentinel down-after-milliseconds mymaster 5000			                        # 当主服务器5秒中内没有回复,则认为主库宕机
    sentinel failover-timeout mymaster 180000				                # 故障转移时,检测从库是否在线时间,如果在180秒内从库没有回应,则表示从库宕机,不参与新主的选举
    sentinel parallel-syncs mymaster 1						        # 当故障转移后,每次同时向新主同时发起复制操作节点个数,如果这个值较大,
    虽然一般不会阻塞主节点,但是会给网络和磁盘IO带来开销。
    

    4.启动sentinel

    # 这是启动后的文件,不用按照这里面的操作,但是当启动后sentinel会自动将里面的格式改变
    [root@db01 ~]# redis-sentinel /service/redis/26379/sentinel.conf
    
    #启动之后配置文件会发生改变
    [root@db01 ~]# vim /service/redis/26379/sentinel.conf
    port 26379
    daemonize yes
    pidfile "/service/redis/26379/sentinel.pid"
    logfile "/service/redis/26379/sentinel.log"
    dir "/service/redis/26379"
    bind 172.16.1.51 127.0.0.1
    sentinel myid 7d430385a1269307819e5300ecf09dfbf92b46f5
    sentinel monitor mymaster 172.16.1.51 6379 1
    sentinel down-after-milliseconds mymaster 5000
    sentinel config-epoch mymaster 0
    # Generated by CONFIG REWRITE
    sentinel leader-epoch mymaster 0
    sentinel known-slave mymaster 172.16.1.51 6379
    sentinel known-slave mymaster 172.16.1.53 6379
    sentinel current-epoch 0
    

    5.停止sentinel

    [root@db01 ~]# redis-cli -p 26379 shutdown
    

    6.测试sentinel

    #关闭主库的redis
    [root@db02 ~]# redis-cli shutdown
    
    #查看其它从库主从状态
    172.16.1.51:6379> info replication
    # Replication
    role:master
    connected_slaves:1
    slave0:ip=172.16.1.53,port=6379,state=online,offset=586,lag=1
    master_repl_offset:723
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:2
    repl_backlog_histlen:722
    

    7.恢复故障节点

    #修复故障节点
    [root@db02 ~]# redis-server /service/redis/6379/redis.conf 
    
    #查看主库状态
    172.16.1.51:6379> info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=172.16.1.53,port=6379,state=online,offset=5077,lag=1
    slave1:ip=172.16.1.52,port=6379,state=online,offset=5077,lag=1
    master_repl_offset:5077
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:2
    repl_backlog_histlen:5076
    

    8.sentinel管理命令(不常用)

    #连接sentinel管理端口
    [root@db01 ~]# redis-cli -p 26379
    
    #检测状态,返回PONG
    127.0.0.1:26379> ping
    PONG
    
    #列出所有被监视的主服务器
    127.0.0.1:26380> SENTINEL masters
    
    #列出所有被监视的从服务器
    127.0.0.1:26380> SENTINEL slaves mymaster
    
    #返回给定名字的主服务器的IP地址和端口号
    127.0.0.1:26380> SENTINEL get-master-addr-by-name mymaster
    1) "172.16.1.51"
    2) "6379
    
    #重置所有名字和给定模式
    127.0.0.1:26380> SENTINEL reset mymaster
    
    #当主服务器失效时,在不询问其他Sentinel意见的情况下,强制开始一次自动故障迁移。
    127.0.0.1:26380> SENTINEL failover mymaster
    

    9.设置权重,指定主库的优先级

    #查看db02的权重
    172.16.1.52:6379> CONFIG GET slave-priority
    1) "slave-priority"
    2) "100"
    
    #修改db02的权重值为0
    172.16.1.52:6379> CONFIG set slave-priority 0
    OK
    
    172.16.1.52:6379> CONFIG GET slave-priority
    1) "slave-priority"
    2) "0"
    
    #权重值越低越不会优先切换为主库
    
    #强制开始一次自动故障迁移
    127.0.0.1:26380> SENTINEL failover mymaster
    
    #再次查看,主库为db03
    172.16.1.53:6379> info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=172.16.1.52,port=6379,state=online,offset=71377,lag=0
    slave1:ip=172.16.1.51,port=6379,state=online,offset=71377,lag=0
    master_repl_offset:71514
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:70496
    repl_backlog_histlen:1019
    

    10.注意:

    # sentinel配置多个
    · sentinel功能和mha的manager功能差不多,但sentinel可以配置单个也可以配置多个,如果需要配置多个,则在配置文件中有两处不同:
    ① bind 172.16.1.51 127.0.0.1						      # 监听端口,必须为自己服务器ip
    ② sentinel monitor mymaster 172.16.1.52 6379  1			              # 这里的1,需要根据sentine数量修改
    
  • 相关阅读:
    n-1位数
    关于VC预定义常量_WIN32,WIN32,_WIN64
    python中的闭包
    TCP粘包, UDP丢包, nagle算法
    C++中 explicit的用法
    为什么mysql索引要使用B+树,而不是B树,红黑树
    屏障和屏障属性
    带有超时的读写锁
    pthread_mutex_timedlock
    段错误以及调试方式
  • 原文地址:https://www.cnblogs.com/tcy1/p/13447472.html
Copyright © 2011-2022 走看看