zoukankan      html  css  js  c++  java
  • redis主从 哨兵

    entinel是redis高可用的解决方案,sentinel系统(N个sentinel实例,N >= 1)可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。

        1. sentinel初始化

            可以使用命令

            redis-sentinel /path/to/sentinel.conf

            或者

            redis-server /path/to/sentinel.conf --sentinel

            来启动sentinel

            sentinel启动时,需要经过一下几个步骤

            a. 初始化服务

                sentinel本质上是一个特殊的redis服务,所以初始化的时候跟redis服务初始化差不多,不过有几点不一样;首先sentinel不会载入RDB或者AOF文件,因为sentinel根本不使用数据库,其次,sentinel不能使用数据库键值对方面的命令,例如set、del、flushdb等等,同时,sentinel也不能使用事务、脚本、RDB或者AOF持久化命令,最后,复制命令,发布与订阅命令,文件事件处理器,时间事件处理器等只能在sentinel内部使用。

            b. 将普通redis代码转成sentinel专用代码

                将redis服务的代码转成sentinel的专用代码,例如sentinel的command与redis的command命令表就不一样(redis很多命令,sentinel不需要)

            c. 初始化sentinel状态

                主要是初始化sentinelState结构,sentinelState里面保存了sentinel的所有功能和状态,sentinelState结构如下

                105923_5SvJ_172871.png

           

            d. 根据指定的配置文件,初始化sentinel监视的主服务器列表

                其实就是初始化sentinelState中的masters属性,masters字典中记录了所有被监视的主服务器信息,其中键是服务器名字,值是服务对应的sentinelRedisInstance结构,主要有实例名字,运行id,实例地址,客观下线票数,主管下线的最大无响应时间等等

         111246_1Ta4_172871.png

    111352_SnFS_172871.png

            sentinelState中masters字典的大致结构如下:

            111820_F1kX_172871.png

            e. sentinel创建与masters(所有master)之间的网络连接

            创建与被监视的master的网络连接后,sentinel成为该master的客户端,它会向master发送命令,并从master的响应中获取master的信息。对于每个被监视的master,sentinel会向其创建两个异步的网络连接

            命令连接,这个连接专门用于向master发送命令,并接收命令回复

            订阅连接,专门订阅master服务的 sentinel:hello频道

        

        2. 获取master信息

            sentinel以每10秒一次的频率向master发送info命令,通过info的回复来分析master信息,master的回复主要包含了两部分信息,一部分是master自身的信息,一部分是master所有的slave(从)的信息,所以sentinel可以自动发现master的从服务。sentinel从master哪儿获取到的master自身信息以及master所有的从信息,将会更新到sentinel的sentinelState中及masters(sentinelRedisInstance结构)中的slaves字典中

                121448_Zvl7_172871.png

        3. 获取从服务器信息

            当sentinel发现master有新的从服务时,不但为从服务创建相信的实例结构,而且还会创建连接到该从服务的命令连接和订阅连接,创建命令连接后,sentinel会10秒每次的向从服务发送info命令,并从回复信息中提取从服务ID、从服务角色、从服务所属的主服务的ip及端口、主从服务的连接状态、从服务的优先级、从服务的复制偏移量等信息;创建或者更新到从服务的sentinelRedisInstance结构。

        4. 向被监视服务器发送询问命令

            sentinel会以每两秒一次的频率向所有的被监视服务器(master和从服务)发送询问命令,命令格式如下

            publish ___sentinel___:hello s_ip s_port s_runid s_epoch m_name m_ip m_port m_epoch

            各个参数的解析如下

            s_ip:sentinel的ip

            s_port:sentinel的端口

            s_runid:sentinel云心id

            s_epoch:sentinel当前的配置纪元

            m_name:主服务器名字

            m_ip:主服务器ip

            m_port:主服务器端口

            m_epoch:主服务器纪元

        5. 接收被监视服务器的频道信息

            sentinel与被监视的服务之间,一方面,sentinel通过命令链接发送信息到频道,另一方面,通过订阅连接从频道中接收信息。

            对于同一服务的多个sentinel,一个sentinel发送的信息,会被其他sentinel收到,用于更新对该sentinel以及被监视服务的认知,用于更新sentinelRedisInstance的sentinels字典信息(请看sentinelRedisInstance的数据结构)及master信息。

    160016_KGV5_172871.png

    161340_As1R_172871.png

    当sentinel通过频道发现新的sentinel时,不但会更新上图的sentinel字典,同时会与新的sentinel建立命令连接(不会建立订阅连接,没啥可订阅的,因为sentinel与master及从建立订阅连接,是用来发现新的sentinel,而sentinel之间是已知的,所以不需要订阅连接),最终,监视同一个服务的多个sentinel会互联形成一个网络。

        6. 主观下线

            首先解析一下什么叫主观下线,所谓主观下线,就是单个sentinel认为某个服务下线(有可能是接收不到订阅,之间的网络不通等等原因)。

            sentinel会以每秒一次的频率向所有与其建立了命令连接的实例(master,从服务,其他sentinel)发ping命令,通过判断ping回复是有效回复,还是无效回复来判断实例时候在线(对该sentinel来说是“主观在线”)。

            sentinel配置文件中的down-after-milliseconds设置了判断主观下线的时间长度,如果实例在down-after-milliseconds毫秒内,返回的都是无效回复,那么sentinel回认为该实例已(主观)下线,修改其flags状态为SRI_S_DOWN。如果多个sentinel监视一个服务,有可能存在多个sentinel的down-after-milliseconds配置不同,这个在实际生产中要注意。

        7. 客观下线

            当sentinel监视的某个服务主观下线后,sentinel会询问其它监视该服务的sentinel,看它们是否也认为该服务主观下线,接收到足够数量(这个值可以配置)的sentinel判断为主观下线,既任务该服务客观下线,并对其做故障转移操作。

            sentinel通过发送 SENTINEL is-master-down-by-addr ip port current_epoch runid,(ip:主观下线的服务id,port:主观下线的服务端口,current_epoch:sentinel的纪元,runid:*表示检测服务下线状态,如果是sentinel 运行id,表示用来选举领头sentinel)来询问其它sentinel是否同意服务下线。

            一个sentinel接收另一个sentinel发来的is-master-down-by-addr后,提取参数,根据ip和端口,检测该服务时候在该sentinel主观下线,并且回复is-master-down-by-addr,回复包含三个参数:down_state(1表示已下线,0表示未下线),leader_runid(领头sentinal id),leader_epoch(领头sentinel纪元)。

            sentinel接收到回复后,根据配置设置的下线最小数量,达到这个值,既认为该服务客观下线

        8. 选举领头sentinel

            一个redis服务被判断为客观下线时,多个监视该服务的sentinel协商,选举一个领头sentinel,对该redis服务进行古战转移操作。选举领头sentinel遵循以下规则:

            所有的sentinel都有公平被选举成领头的资格

            所有的sentinel都有且只有一次将某个sentinel选举成领头的机会(在一轮选举中),一旦选举某个sentinel为领头,不能更改

            sentinel设置领头sentinel是先到先得,一旦当前sentinel设置了领头sentinel,以后要求设置sentinel为领头请求都会被拒绝

            每个发现服务客观下线的sentinel,都会要求其他sentinel将自己设置成领头

            当一个sentinel(源sentinel)向另一个sentinel(目sentinel)发送is-master-down-by-addr ip port current_epoch runid命令的时候,runid参数不是*,而是sentinel运行id,就表示源sentinel要求目标sentinel选举其为领头

            源sentinel会检查目标sentinel对其要求设置成领头的回复,如果回复的leader_runid和leader_epoch为源sentinel,表示目标sentinel同意将源sentinel设置成领头

            如果某个sentinel被半数以上的sentinel设置成领头,那么该sentinel既为领头

            如果在限定时间内,没有选举出领头sentinel,暂定一段时间,再选举

        9. 故障转移

            故障转移分为三个主要步骤

            a. 从下线的主服务的所有从服务里面挑选一个从服务,将其转成主服务

                 sentinel状态数据结构中保存了主服务的所有从服务信息,领头sentinel按照如下的规则从从服务列表中挑选出新的主服务

                删除列表中处于下线状态的从服务

                删除最近5秒没有回复过领头sentinel info信息的从服务

                删除与已下线的主服务断开连接时间超过 down-after-milliseconds*10毫秒的从服务,这样就能保留从的数据比较新(没有过早的与主断开连接)

                领头sentinel从剩下的从列表中选择优先级高的,如果优先级一样,选择偏移量最大的(偏移量大说明复制的数据比较新),如果偏移量一样,选择运行id最小的从服务

            b. 已下线主服务的所有从服务改为复制新的主服务

                挑选出新的主服务之后,领头sentinel 向原主服务的从服务发送 slaveof 新主服务 的命令,复制新master

            c. 将已下线的主服务设置成新的主服务的从服务,当其回复正常时,复制新的主服务,变成新的主服务的从服务

                同理,当已下线的服务重新上线时,sentinel会向其发送slaveof命令,让其成为新主的从

  • 相关阅读:
    【C++】资源管理
    【Shell脚本】逐行处理文本文件
    【算法题】rand5()产生rand7()
    【Shell脚本】字符串处理
    Apple iOS产品硬件参数. 不及格的程序员
    与iPhone的差距! 不及格的程序员
    iPhone游戏 Mr.Karoshi"过劳死"通关. 不及格的程序员
    XCode V4 发布了, 苹果的却是个变态. 不及格的程序员
    何时readonly 字段不是 readonly 的?结果出呼你想象!!! 不及格的程序员
    object file format unrecognized, invalid, or unsuitable Command 不及格的程序员
  • 原文地址:https://www.cnblogs.com/qiumingcheng/p/6164886.html
Copyright © 2011-2022 走看看