乐趣区

Redis从入门到精通七Redis-Sentinel

Redis Sentinel 是 Redis 官方提供的高可用解决方案。

Redis 本身可以实现主从复制, 但是并没有自动切换主备的功能, 当出现其中一个主实例宕机的情况, 客户端将无法执行写入命令,Sentinel 可以在没有人工干预的情况下执行故障转移, 不影响正常的写入操作。

Sentinel 是一个分布式的系统, 多个 Sentinel 进程之间协调工作, 一来保证故障检测的误报率, 二来保证了 Sentinel 本身的可用性。

Redis Sentinel

Sentinel 提供了以下功能:

  • 监控。Sentinel 会不断检查主从是否按预期工作。
  • 通知。Sentinel 可以通过 API 通知系统管理员,另一台计算机程序,其中一个受监控的 Redis 实例出现问题。
  • 自动故障转移。如果主服务器未按预期工作,Sentinel 可以启动故障转移过程,其中从服务器升级为主服务器,其他其他服务器重新配置为使用新主服务器,并且使用 Redis 服务器的应用程序通知有关新服务器的地址连接。
  • 配置提供商。Sentinel 充当客户端服务发现的权限来源:客户端连接到 Sentinels,以便询问负责给定服务的当前 Redis 主服务器的地址。如果发生故障转移,Sentinels 将报告新地址。

配置

我挑了一些主要的配置项出来, 其它的都与 redis.conf 类似

# sentinel announce-ip <ip>
# sentinel announce-port <port>

sentinel auth-pass mymaster <password>

# sentinel monitor <master-group-name> <ip> <port> <quorm>
sentinel monitor mymaster 127.0.0.1 6379 2

# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000

# sentinel parallel-syncs <master-name> <numreplicas>
sentinel parallel-syncs mymaster 1

# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
  • sentinel auth-pass <master-group-name> <password> , 配置主服务器的密码
  • sentinel monitor <master-group-name> <ip> <port> <quorm>, 配置需要监视的主服务器, 最后一个为 仲裁参数 , 代表 Sentinel 集群中必须有至少 2 个实例认为主服务器不可用, 其中一个尝试启动故障转移, 默认 127.0.0.1 6379 2
  • sentinel down-after-milliseconds <master-name> <milliseconds> , 主服务器未回复 sentinel ping 的时长, 如果超过这个时长, 则这个 sentinel 实例主观的认为主服务器不可用, 默认3000
  • sentinel parallel-syncs <master-name> <numreplicas> , 设置可在同一故障转移后重新配置以使用新主服务器的从服务器数, 默认 1
  • sentinel failover-timeout <master-name> <milliseconds> , 指定故障转移超时时长, 默认 180000

启动

可以通过以下两种方式开启 Sentinel:

redis-server sentinel.conf --sentinel

redis-sentinel sentinel.conf

Sentinel 解析

任何一个 sentinel 实例主要达到 SDOWN 的条件, 就将该服务器标记为 SDOWN, 如果有至少 qurom 个实例都认为该服务器 SDOWN, 就标记为 ODOWN, 此时触发故障转移, 需要满足大多数 Sentinel 实例的授权才能进行故障转移。例设有 5 个 sentinel 实例, 配置 qurom 为 2 , 5 个实例, 有 2 个认为服务器无法访问, 就尝试故障转移, 只有 3 个或以上实例授权后才能执行故障转移, 如果 qurom 设置为 5, 则当 ODOWN 时, 直接进行故障转移。

Sentinel 实例之间的通信

Sentinel 实例之间通过名为 __sentinel__:hello 的 Pub/Sub channel 进行通信

  • 每个 Sentinel 每隔 2 秒向 channel 中发送 ip port runid 宣布它的存在
  • 每个 Sentinel 订阅 channel , 当检测到新的 Sentinel 后, 将它添加进集群中
  • 消息中包括完整的当前服务器的配置, 如果某个 Sentinel 还是旧的服务器的配置, 将会立刻更新
  • 在向主服务器添加新的标记之前,Sentinel 始终检查是否已存在具有相同 runid 或相同地址(ip 和端口对)的标记。在这种情况下,将删除所有匹配的标记,并添加新的标记。

SDOWN 和 ODOWN 状态

  • Subjectively Down(SDOWN, 主观下线), 单个实例对服务器做出的下线判断
  • Objectively Down(ODOWN, 客观下线), 多个实例对同一个服务器做出的下线判断, 并且多个实例之间已经通过 SENTINEL is-master-down-by-addr 交流之后做出的下线判断。

Sentinel 每隔 1 秒向服务器发出 ping 命令, 如果服务器距离上次回复 ping 已经超过了 down-after-milliseconds 所设置的时长, 或者不是以下三个中的命令时,sentinel 认为这个服务器下线了(主观下线):

  • +PONG
  • -LOADING
  • -MASTERDOWN

当多个 sentinel 实例 (qurom) 对同一个服务器做出主观下线的判断后, 状态变为 ODOWN

Slave 选择和优先权

当 Sentinel 开始执行故障转移时, 需要在 从服务器之间选出一个, 来提升为主服务器, 只要参考以下 4 个方面:

  1. 与原主服务器断开连接的时长
  2. Slave priority, 在 redis.conf 中有配置 slave-priority, 默认为 100, 数字越小将越优先
  3. 已经处理的复制偏移量
  4. Run ID

分区下的一致性

             +-------------+
             | Sentinel 1  | <--- Client A
             | Redis 1 (M) |
             +-------------+
                     |
                     |
 +-------------+     |                     +------------+
 | Sentinel 2  |-----+-- / partition / ----| Sentinel 3 | <--- Client B
 | Redis 2 (S) |                           | Redis 3 (M)|
 +-------------+                           +------------+

初始状态下 redis3 是 master, redis1 和 redis2 是 slave。之后 redis3 所在的主机网络不可用了,sentinel1 和 sentinel2 启动了 failover 并把 redis1 选举为 master。

Sentinel 集群的特性保证了 sentinel1 和 sentinel2 得到了关于 master 的最新配置。但是 sentinel3 依然持着的是旧的配置,因为它与外界隔离了。

客户端将依然可以向 redis3 写数据,但是当网络恢复后,redis3 就会变成 redis 的一个 slave,那么,在网络隔离期间,客户端向 redis3 写的数据将会丢失。

如果你把 redis 当做缓存来使用,那么你也许能容忍这部分数据的丢失。
但如果你把 redis 当做一个存储系统来使用,你也许就无法容忍这部分数据的丢失了。

因为 redis 采用的是异步复制,在这样的场景下,没有办法避免数据的丢失。然而,你可以通过以下配置来配置 redis3 和 redis1,使得数据不会丢失。

可以通过下面 2 个参数进行配置, 保证只要有一个从服务器断开了与主服务器的连接就不执行写入操作。具体可以参考 Redis 从入门到精通(六、Redis 主从复制)

min-slaves-to-write 1
min-slaves-max-lag 10

Sentinel persistent state

Sentinel 状态保留在 sentinel 配置文件中。这意味着停止并重新启动 Sentinel 进程是安全的。


更多详细资料参考:

Redis Sentinel 官方文档

退出移动版