Fork me on GitHub

【redis】redis Sentinel 简介

[TOC]

redis Sentinel

1. 高可用

1.1 主从模式的高可用性

redis主从复制模式下主节点故障,故障转移过程:

  • 主节点发生故障后, 客户端(client) 连接主节点失 败, 两个从节点与主节点连接失败造成复制中断
  • 如果主节点无法正常启动, 需要选出一个从节点 (slave-1) , 对其执行slaveof no one命令使其成为新的主节点
  • 原来的从节点(slave-1) 成为新的主节点后, 更新应 用方的主节点信息, 重新启动应用方
  • 客户端命令另一个从节点(slave-2) 去复制新的主节 点(new-master)
  • 待原来的主节点恢复后, 让它去复制新的主节点。

产生的问题:

  • 判断节点不可达的机制是否健全和标 准
  • 如果有多个从节点, 怎样保证只有一个被晋升为主节点
  • 通知客户端新的主节点机制是否足够健壮

1.2 Redis Sentinel的高可用性

当主节点出现故障时, Redis Sentinel能自动完成故障发现和故障转移, 并通知应用方, 从而实现真正的高可用

Redis Sentinel是一个分布式架构, 其中包含若干个Sentinel节点和Redis 数据节点, 每个Sentinel节点会对数据节点和其余Sentinel节点进行监控, 当 它发现节点不可达时, 会对节点做下线标识。 如果被标识的是主节点, 它还 会和其他Sentinel节点进行“协商”, 当大多数Sentinel节点都认为主节点不可 达时, 它们会选举出一个Sentinel节点来完成自动故障转移的工作, 同时会 将这个变化实时通知给Redis应用方。

1个主节点、 2个从节点、 3个Sentinel节点组成的Redis Sentinel 架构故障转移机制:

  • 主节点出现故障, 此时两个从节点与主节点失去连 接, 主从复制失败
  • 每个Sentinel节点通过定期监控发现主节点出现了故 障。
  • 多个Sentinel节点对主节点的故障达成一致, 选举出 sentinel-3节点作为领导者负责故障转移。
  • Sentinel领导者节点执行了故障转移 ,和主从复制模式下流程相同
  • 故障转移完成

1.3 Redis Sentinel 的功能

  • 监控: Sentinel节点会定期检测Redis数据节点、 其余Sentinel节点是否 可达。
  • 通知: Sentinel节点会将故障转移的结果通知给应用方。
  • 主节点故障转移: 实现从节点晋升为主节点并维护后续正确的主从关 系。
  • 配置提供者: 在Redis Sentinel结构中, 客户端在初始化的时候连接的 是Sentinel节点集合, 从中获取主节点信息。

2. redis Sentinel 部署

2.1 配置

1
2
3
4
5
6
7
8
9
10
port 26379
dir /opt/soft/redis/data
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
#主节点设置了密码
#sentinel auth-pass <master-name> <password>
#sentinel notification-script <master-name> <script-path>
#sentinel client-reconfig-script <master-name> <script-path>
  • sentinel monitor
1
sentinel monitor <master-name> <ip> <port> <quorum>

代表要判定主节点最终不可达所需要的票数

启动后配置文件变化,会自动发现了从节点、 其余Sentinel节点 ;去掉了默认配置, 例如parallel-syncs、 failover-timeout参数;添加了配置纪元相关参数。

1
2
3
4
5
6
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 127.0.0.1 6380
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-sentinel mymaster 127.0.0.1 26381 6201f902c6d584980bb9e6eb05dc26947ae346e0
sentinel known-sentinel mymaster 127.0.0.1 26380 a9c803c3d4f07b0389163d837de2262559ed0321
sentinel current-epoch 0
  • sentinel down-after-milliseconds
1
sentinel down-after-milliseconds <master-name> <times>

(单位为毫秒) 就是超时时间

每个Sentinel节点都要通过定期发送ping命令来判断Redis数据节点和其余Sentinel节点是否可达, 如果超过了down-after-milliseconds配置的时间且没 有有效的回复, 则判定节点不可达

  • sentinel parallel-syncs
1
sentinel parallel-syncs <master-name> <nums>

parallel-syncs 用来限制在一次故障转移之后, 每次向新的主节点发起复制操作的从节点个数

  • sentinel failover-timeout
1
sentinel failover-timeout <master-name> <times>

failover-timeout故障转移超时时间,作用于故障各个阶段:

  1. 选出合适从节点。
  2. 晋升选出的从节点为主节点。
  3. 命令其余从节点复制新的主节点。
  4. 等待原主节点恢复后命令它去复制新的主节点。
  • sentinel notification-script
1
sentinel notification-script <master-name> <script-path>

sentinel notification-script的作用是在故障转移期间, 当一些警告级别的 Sentinel事件发生(指重要事件, 例如-sdown: 客观下线、 -odown: 主观下 线) 时, 会触发对应路径的脚本, 并向脚本发送相应的事件参数

  • sentinel client-reconfig-script
1
sentinel client-reconfig-script <master-name> <script-path>

sentinel client-reconfig-script的作用是在故障转移结束后, 会触发对应路 径的脚本, 并向脚本发送故障转移结果的相关参数

2.2 监控多 个节点

指定多个masterName来区分不同的主节点 即可

1
2
3
4
5
6
7
8
sentinel monitor master-business-1 10.10.xx.1 6379 2
sentinel down-after-milliseconds master-business-1 60000
sentinel failover-timeout master-business-1 180000
sentinel parallel-syncs master-business-1 1
sentinel monitor master-business-2 10.16.xx.2 6380 2
sentinel down-after-milliseconds master-business-2 10000
sentinel failover-timeout master-business-2 180000
sentinel parallel-syncs master-business-2 1

2.3 部署优化

  • Sentinel节点不应该部署在一台物理“机器”上
  • 部署至少三个且奇数个的Sentinel节点。
  • 如果Sentinel节点集合监控的是同一个业务的多个主节点集合, 那么使用一套Sentinel、 否则一般建议采用多套Sentinel

3. Redis Sentinel 客户端

3.1 客户端实现流程

  1. 遍历Sentinel节点集合获取一个可用的Sentinel节点,Sentinel节点之间可以共享数据, 所以从任意一个Sentinel节点获取主节点信 息都是可以的
  2. 通过sentinel get-master-addr-by-name master-name这个API来获取对应 主节点的相关信息
  3. 验证当前获取的“主节点”是真正的主节点, 这样做的目的是为了防 止故障转移期间主节点的变化
  4. 保持和Sentinel节点集合的“联系”, 时刻获取关于主节点的相关“信 息”

3.2 Jedis Sentinel操作

1
2
3
4
5
public JedisSentinelPool(String masterName, Set<String> sentinels,
final GenericObjectPoolConfig poolConfig, final int connectionTimeout,
final int soTimeout,
final String password, final int database,
final String clientName)

Options:

  • masterName——主节点名。
  • sentinels——Sentinel节点集合。
  • poolConfig——common-pool连接池配置。
  • connectTimeout——连接超时。
  • soTimeout——读写超时。
  • password——主节点密码。
  • database——当前数据库索引。
  • clientName——客户端名
1
2
3
4
5
6
7
8
9
10
11
//获取jedis
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
// jedis command
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
if (jedis != null)
jedis.close();
}