zoukankan      html  css  js  c++  java
  • Redis 学习笔记(篇十):Sentinel

    Sentinel(哨兵)是 Redis 的高可用解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
    服务器与 Sentinel 系统的关系如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

    当 serverl 的下线时长超过用户设定的下线时长上限时,Sentinel 系统就会对 serverl 执行故障转移操作:

    • 首先, Sentinel 系统会挑选 serverl 属下的其中一个从服务器,并将这个被选中的从服务器升级为新的主服务器。
    • 之后, sentinel 系统会向 serverl 属下的所有从服务器发送新的复制指令,让它们成为新的主服务器的从服务器,当所有从服务器都开始复制新的主服务器时,故障转移操作执行完毕。故障转移过程如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):
      《Redis设计与实现第二版》
    • 另外, sentinel 还会继续监视已下线的 serverl,并在它重新上线时,将它设置为新的主服务器的从服务器。如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):
      《Redis设计与实现第二版》

    启动并初始化 Sentinel

    启动 Sentinel 的命令如下:

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

    当一个 Sentinel 启动时,他需要执行以下步骤:

    1. 初始化服务器。
      因为 Sentinel 本质上只是一个运行在特殊模式下的 Redis 服务器,所以需要初始化一个普通的 Redis 服务器。

    2. 将普通 Redis 服务器使用的代码替换成 Sentinel 专用代码。
      将一部分普通 Redis 服务器使用的代码替换成 Sentinel 专用代码。比如,端口、命令表等。

    3. 初始化 Sentinel 状态。

    4. 根据给定的配置文件,初始化 Sentinel 的监视主服务器列表。

    5. 创建连向主服务器的网络连接。

    Sentinel 会创建两个连向主服务器的异步网络连接(Sentinel 将成为主服务器的客户端,可以向主服务器发送命令,并从命令回复中获取相关信息。),如下:

    • 命令连接:这个连接专门向主服务器发送命令,并接受命令回复。
    • 订阅连接:这个连接专门用于订阅主服务器的 __sentinel__:hello 频道

    获取主服务器的信息

    Sentinel 默认会以每十秒一次的频率,通过命令连接向被监视的主服务器发送 INFO 命令,并通过分析 INFO 命令的回复来获取当前主服务器和从服务器的的信息。如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

    Sentinel 通过解析主服务器返回的信息,可以获取以下两方面的信息:

    • 关于主服务器本身的信息。
    • 主服务器属下所有从服务器的信息,比如:ip、port。

    获取从服务器的信息

    当 Sentinel 发现主服务器有新的从服务器时,Sentinel 除了会为这个新的从服务器创建相应的实例结构之外,Sentinel 还会创建连接到从服务器的命令和订阅连接。如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

    创建连接之后,Sentinel 会默认每十秒一次的频率通过命令连接向从服务器发送 INFO 命令,并获得如下信息:从服务器的运行 ID、主服务器的 IP:port、主从服务器的连接状态、从服务器的优先级、从服务器的复制偏移量等。

    向主服务器和从服务器发送和接收信息

    在默认情况下, Sentinel 会以每两秒一次的频率,通过命令连接向所有被监视的主从服务器发送如下格式的命令:

    PUBLISH \_\_sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port><m_epoch>"
    

    这条命令向服务器的 __sentinel__:hello 频道发送了一条消息,信息内容的参数如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

    当 Sentinel 与一个主服务器或者从服务器建立订阅连接后, Sentinel 就会通过订阅连接,向服务器发送一下命令:

    SUBSCRIBE __sentinel__:hello
    

    表示 Sentinel 对 __sentinel__:hello 频道的订阅会一直持续到 Sentinel 与服务器的连接断开为止。
    也就是说: 对于每个与 Sentinel 连接的服务器, Sentinel 既通过命令连接向服务器的 __sentinel__:hello 频道发送消息,又通过订阅连接从服务器的 __sentinel__:hello 频道接收消息,如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

    检测主观下线状态

    在默认情况下,Sentinel 会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他Sentinel)发送 PING 命令,并通过实例返回的 PING 命令回复来判断该实例是否在线。如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

    实例对 PING 命令的回复可以分为以下两种情况:

    • 有效回复:实例返回 +PONG、-LOADING、-MASTERDOWN 三种回复中的一种。
    • 无效回复:其他回复。

    如果一个实例在 down-after-milliseconds 毫秒(配置文件中的值)内,连续向 Sentinel 返回无效回复,那么该 Sentinel 便认为这个实例已经进入主观下线状态。

    注意:对于监视同一个服务器的多个 Sentinel 来说,这些 Sentinel 所设置的 down-after-milliseconds 的值也可能不同。因此,当一个 Sentinel 将主服务器判断为主观下线时,其他 Sentinel 可能仍然会认为主服务器处于在线状态。

    检测客观下线状态

    当 Sentinel 将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会向同样监视这一主服务器的其他 Sentinel 进行询问,看它们是否也认为主服务器已经进入了下线状态(可以是主观下线或者客观下线)。当 Sentinel 从其他 Sentinel 那里接收到足够数量的已下线判断之后, Sentinel 就会将从服务器判定为客观下线,并对主服务器执行故障转移操作。

    客观下线状态的判断条件如下:
    当认为主服务器已经进入下线专题的 Sentinel 的数量,超过 Sentinel 配置中设置的 quorum 参数的值,那么该 Sentinel 就会认为主服务器已经进入客观下线状态。

    注意:不同 Sentinel 判断客观下线的条件可能不同:对于监视同一个主服务器的多个 Sentinel 来说,他们讲主服务器判断为客观下线的条件可能也不同,当一个 Sentinel 将主服务器判断为客观下线时,其他 Sentinel 可能并不是那么认为的。

    选举领头 Sentinel

    当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个 Sentinel 会进行协商,选举出一个领头 Sentinel,并由领头 Sentinel 对下线主服务器执行故障转移操作。

    故障转移

    在选举产生出领头 Sentinel 之后,领头 Sentinel 将对已下线的主服务器执行故障转移操作,该操作包含以下三个步骤:

    1. 在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为主服务器。
    2. 让已下线主服务器属下的所有从服务器改为复制新的主服务器。
    3. 将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器。

    选出新的主服务器

    故障转移的第一步就是在已下线的主服务器属下的所有从服务器中,挑选出一个状态良好、数据完整的从服务器,然后向这个从服务器发送 SLAVEOF no one 命令,将这个从服务器转换为主服务器。如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

    修改从服务器的复制目标

    当新的主服务器出现之后,领头 Sentinel 下一步要做的就是,让已下线的主服务器属下的所有从服务器去复制新的主服务器(向从服务器发送 SLAVEOF 命令)。如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

    此时各个服务器以及领头 Sentinel 如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

    将旧的主服务器变为从服务器

    故障转移操作最后要做的就是,当将已下线的主服务器从新上线时设置为新的主服务器的从服务器。如下图所示(出自《Redis设计与实现第二版》第十六章:Sentinel):

    《Redis设计与实现第二版》

  • 相关阅读:
    POJ 3278 Catch That Cow(BFS)
    POJ 2488 A Knight's Journey(DFS)
    POJ 2386 Lake Counting(DFS)
    迷宫问题(BFS)
    两点(DFS)
    POJ 1001 Exponentiation(大数运算)
    Java IO流01-总叙
    hdu 2065 "红色病毒"问题(快速幂求模)
    POJ 2251 Dungeon Master(BFS)
    POJ 1321 棋盘问题(DFS)
  • 原文地址:https://www.cnblogs.com/wind-snow/p/11474871.html
Copyright © 2011-2022 走看看