标签:name 状态 概念 数据集 class hello 自己 步骤 版本号
Redis的Sentinel系统用于管理多个Redis服务器(instance), 该系统执行以下三个任务:
Redis Sentinel 是一个分布式系统, 可以在一个架构中运行多个Sentinel进程(progress),这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。
Redis Sentinel释实际上是一个运行在特殊模式下的Redis服务器,可以在启动一个普通Redis服务器时通过给定 --sentinel 选项来启动Redis Sentinel。
对于 redis-sentinel程序, 可以用以下命令来启动Sentinel系统:
redis-sentinel /path/to/sentinel.conf
对于 redis-server 程序, 可以用以下命令来启动一个运行在Sentinel模式下的Redis服务器:
redis-server /path/to/sentinel.conf --sentinel
两种方法都可以启动一个Sentinel实例。 启动Sentinel实例必须指定相应的配置文件, 系统会使用配置文件来保存Sentinel的当前状态, 并在Sentinel重启时通过载入配置文件来进行状态还原。如果启动Sentinel时没有指定相应的配置文件, 或者指定的配置文件不可写(not writable), 那么Sentinel会拒绝启动。
Redis源码中包含了一个名为 sentinel.conf 的文件, 这个文件是一个带有详细注释的Sentinel配置文件示例。运行一个 Sentinel 所需的最少配置如下所示:
sentinel monitor mymaster 127.0.0.1 6379 2 sentinel down-after-milliseconds mymaster 60000 sentinel failover-timeout mymaster 180000 sentinel parallel-syncs mymaster 1 sentinel monitor resque 192.168.1.3 6380 4 sentinel down-after-milliseconds resque 10000 sentinel failover-timeout resque 180000 sentinel parallel-syncs resque 5
第一行配置指示Sentinel去监视一个名为mymaster的主服务器,这个主服务器的IP地址为 127.0.0.1 ,端口号为 6379 ,而将这个主服务器判断为失效至少需要2个Sentinel同意 (只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行)。不过要注意, 无论你设置要多少个Sentinel同意才能判断一个服务器失效, 一个Sentinel都需要获得系统中多数Sentinel的支持,才能发起一次自动故障迁移,并预留一个给定的配置纪元 (configuration Epoch ,一个配置纪元就是一个新主服务器配置的版本号)。换句话说, 在只有少数Sentinel进程正常运作的情况下, Sentinel 是不能执行自动故障迁移的。其他选项的基本格式如下:
sentinel <选项的名字> <主服务器的名字> <选项的值>
各个选项的功能如下:down-after-milliseconds 选项指定了Sentinel认为服务器已经断线所需的毫秒数。如果服务器在给定的毫秒数之内, 没有返回Sentinel发送的PING命令的回复, 或者返回一个错误, 那么Sentinel将这个服务器标记为主观下线。不过只有一个Sentinel将服务器标记为主观下线并不一定会引起服务器的自动故障迁移:只有在足够数量的 Sentinel都将一个服务器标记为主观下线之后, 服务器才会被标记为客观下线, 这时自动故障迁移才会执行。将服务器标记为客观下线所需的 Sentinel数量由对主服务器的配置决定。
parallel-syncs选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长。如果从服务器被设置为允许使用过期数据集(参见对 redis.conf 文件中对 slave-serve-stale-data 选项的说明), 那么你可能不希望所有从服务器都在同一时间向新的主服务器发送同步请求, 因为尽管复制过程的绝大部分步骤都不会阻塞从服务器, 但从服务器在载入主服务器发来的RDB文件时, 仍然会造成从服务器在一段时间内不能处理命令请求: 如果全部从服务器一起对新的主服务器进行同步, 那么就可能会造成所有从服务器在短时间内全部不可用的情况出现。你可以通过将这个值设为1来保证每次只有一个从服务器处于不能处理命令请求的状态。
前面说过, Redis的Sentinel中关于下线有两个不同的概念:
如果一个服务器没有在master-down-after-milliseconds选项所指定的时间内, 对向它发送PING命令的Sentinel返回一个有效回复(valid reply), 那么Sentinel就会将这个服务器标记为主观下线。服务器对PING命令的有效回复可以是以下三种回复的其中一种:
如果服务器返回除以上三种回复之外的其他回复,又或者在指定时间内没有回复PING命令, 那么Sentinel认为服务器返回的回复无效(non-valid)。注意, 一个服务器必须在master-down-after-milliseconds毫秒内, 一直返回无效回复才会被Sentinel标记为主观下线。举个例子, 如果master-down-after-milliseconds选项的值为30000毫秒(30 秒),那么只要服务器能在每 29 秒之内返回至少一次有效回复, 这个服务器就仍然会被认为是处于正常状态的。
从主观下线状态切换到客观下线状态并没有使用严格的法定人数算法(strong quorum algorithm),而是使用了流言协议:如果Sentinel在给定的时间范围内,从其他Sentinel那里接收到了足够数量的主服务器下线报告, 那么Sentinel就会将主服务器的状从主观下线改变为客观下线。 如果之后其他Sentinel不再报告主服务器已下线, 那么客观下线状态就会被移除。客观下线条件只适用于主服务器:对于任何其他类型的Redis实例, Sentinel在将它们判断为下线前不需要进行协商, 所以从服务器或者其他Sentinel永远不会达到客观下线条件。只要一个Sentinel发现某个主服务器进入了客观下线状态, 这个Sentinel就可能会被其他Sentinel推选出, 并对失效的主服务器执行自动故障迁移操作。
一个 Sentinel 可以与其他多个 Sentinel进行连接, 各个Sentinel之间可以互相检查对方的可用性, 并进行信息交换。你无须为运行的每个 Sentinel 分别设置其他 Sentinel 的地址, 因为 Sentinel 可以通过发布与订阅功能来自动发现正在监视相同主服务器的其他 Sentinel , 这一功能是通过向频道 __sentinel__:hello 发送信息来实现的。与此类似, 你也不必手动列出主服务器属下的所有从服务器, 因为 Sentinel 可以通过询问主服务器来获得所有从服务器的信息。
在默认情况下,Sentinel 使用 TCP 端口 26379 (普通 Redis 服务器使用的是 6379 )。Sentinel 接受 Redis 协议格式的命令请求, 所以你可以使用 redis-cli 或者任何其他 Redis 客户端来与 Sentinel 进行通讯。 有两种方式可以和 Sentinel 进行通讯:
以下列出的是Sentinel接受的命令:
客户端可以将 Sentinel 看作是一个只提供了订阅功能的 Redis 服务器: 你不可以使用 PUBLISH 命令向这个服务器发送信息, 但你可以用 SUBSCRIBE 命令或者 PSUBSCRIBE 命令, 通过订阅给定的频道来获取相应的事件提醒。一个频道能够接收和这个频道的名字相同的事件。 比如说, 名为 +sdown 的频道就可以接收所有实例进入主观下线(SDOWN)状态的事件。 通过执行 PSUBSCRIBE * 命令可以接收所有事件信息。 以下列出的是客户端可以通过订阅来获得的频道和信息的格式: 第一个英文单词是频道/事件的名字, 其余的是数据的格式。注意, 当格式中包含 instance details 字样时, 表示频道所返回的信息中包含了以下用于识别目标实例的内容:
<instance-type> <name> <ip> <port> @ <master-name> <master-ip> <master-port>
@ 字符之后的内容用于指定主服务器, 这些内容是可选的, 它们仅在 @ 字符之前的内容指定的实例不是主服务器时使用。
一次故障转移操作由以下步骤组成:
每当一个Redis 实例被重新配置(reconfigured)—— 无论是被设置成主服务器、从服务器、又或者被设置成其他主服务器的从服务器 —— Sentinel都会向被重新配置的实例发送一个CONFIG REWRITE命令, 从而确保这些配置会持久化在硬盘里。
Sentinel 使用以下规则来选择新的主服务器:
Sentinel 自动故障迁移使用 Raft 算法来选举领头(leader)Sentinel , 从而确保在一个给定的纪元(epoch)里, 只有一个领头产生。这表示在同一个纪元中, 不会有两个 Sentinel 同时被选中为领头, 并且各个 Sentinel 在同一个纪元中只会对一个领头进行投票。更高的配置纪元总是优于较低的纪元, 因此每个 Sentinel 都会主动使用更新的纪元来代替自己的配置。简单来说, 我们可以将 Sentinel 配置看作是一个带有版本号的状态。 一个状态会以最后写入者胜出(last-write-wins)的方式(也即是,最新的配置总是胜出)传播至所有其他 Sentinel 。举个例子, 当出现网络分割(network partitions)时, 一个 Sentinel 可能会包含了较旧的配置, 而当这个 Sentinel 接到其他 Sentinel 发来的版本更新的配置时, Sentinel 就会对自己的配置进行更新。如果要在网络分割出现的情况下仍然保持一致性, 那么应该使用 min-slaves-to-write 选项, 让主服务器在连接的从实例少于给定数量时停止执行写操作, 与此同时, 应该在每个运行 Redis 主服务器或从服务器的机器上运行 Redis Sentinel 进程。
Sentinel 的状态会被持久化在 Sentinel 配置文件里面。每当 Sentinel 接收到一个新的配置, 或者当领头 Sentinel 为主服务器创建一个新的配置时, 这个配置会与配置纪元一起被保存到磁盘里面。这意味着停止和重启 Sentinel 进程都是安全的。
即使没有自动故障迁移操作在进行, Sentinel 总会尝试将当前的配置设置到被监视的实例上面。 特别是:
不过, 在以上这些条件满足之后, Sentinel 在对实例进行重新配置之前仍然会等待一段足够长的时间, 确保可以接收到其他 Sentinel 发来的配置更新, 从而避免自身因为保存了过期的配置而对实例进行了不必要的重新配置。
Redis Sentinel严重依赖计算机的时间功能: 比如说, 为了判断一个实例是否可用, Sentinel会记录这个实例最后一次响应PING命令的时间, 并将这个时间和当前时间进行对比, 从而知道这个实例有多长时间没有和 Sentinel 进行任何成功通讯。不过, 一旦计算机的时间功能出现故障, 或者计算机非常忙碌, 又或者进程因为某些原因而被阻塞时, Sentinel 可能也会跟着出现故障。TILT 模式是一种特殊的保护模式: 当 Sentinel 发现系统有些不对劲时, Sentinel就会进入TILT 模式。因为 Sentinel 的时间中断器默认每秒执行 10 次, 所以我们预期时间中断器的两次执行之间的间隔为 100 毫秒左右。 Sentinel 的做法是, 记录上一次时间中断器执行时的时间, 并将它和这一次时间中断器执行的时间进行对比:
当 Sentinel 进入 TILT 模式时, 它仍然会继续监视所有目标, 但是:
如果 TILT 可以正常维持 30 秒钟, 那么 Sentinel 退出 TILT 模式。
标签:name 状态 概念 数据集 class hello 自己 步骤 版本号
原文地址:http://www.cnblogs.com/wxgblogs/p/6791996.html