redis sentinel

redis 哨兵

哨兵为redis提供了高可用的性, 在实际应用中, 当redis server 发生故障了,通过使用redis 哨兵实现自动化系统监控和故障恢复,而无需人工的介入.

哨兵的特性:
- 监控: 哨兵会实时检测master和slave是否按正常运行.

  • 通知: 当监控的redis实例发生异常时候,通过特定api,哨兵可以通知系统或者其他应用程序.

  • 故障恢复: 如果master 主机出现了故障,哨兵会启动故障恢复功能,通过选举一个slave从机做为master, 其他添加上来的slave机器将会被从新配置新的master主机信息.

  • 客户端配置提供者:哨兵为客户端提供服务配置提供者,当客户端连接到哨兵询问当前redis master主机的地址. 如果master故障发生了, 哨兵就会将选举出的新master的地址发送给客户端.

哨兵 分布式特性 (distributed nature of Sentinel)

redis 哨兵是一个分布式的系统:
哨兵自身被设计可以支持:多哨兵一个共同协作的环境下. 多哨兵协作工作的优势如下:
1. 当多个哨兵一致认为当前的master 不在可用,这是才会执行故障检测恢复。 这样作法降低了单哨兵的误判率.
2. 即使并不是所有哨兵都在工作,但还是可以保证系统的健壮性, 只要有一个哨兵正常工作,就可以及时检测出系统的故障问题.

哨兵, redis实例(主从), 和连接到哨兵、redis的客户端组成了非常庞大的具有特殊属性的分布是系统. 官网文档介绍从了解哨兵基本属性信息到哨兵的实践工作原理.

快速启动(quick Start)

获取哨兵

哨兵最新的版本是Sentinel 2. 作为第一版的升级版,它采用更强更简单的预测算法. 在redis 最新的稳定版本2.8, 和3.0 都使用了升级版的Sentinel 2 . 研发版的哨兵正在非稳定版中使用, 一些新特性有时也会插入到2.8,和3.0版本中去,直到他们被认为是稳定版时. 哨兵的第一个版本是在redis 2.6中使用, 2.6版本的redis是弃用的,不赞成使用它.

运行哨兵

哨兵有两种启动方式
– 直接启动通过使用redis-sentinel

redis-sentinel /path/to/sentinel.conf

– 当启动redis服务使用哨兵模式启动

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

两种方式都可以正常工作.

启动redis的哨兵是强制需要通过配置文件启动的,文件用于系统保持当前状态, 避免哨兵重启可以重新加载. 当启动时没有
提供配置文件或者配置文件不可写,哨兵会直接拒绝启动的. 启动哨兵后会开启tcp 端口26379 ,该端口是用来接收其他哨兵实例的连接, 如果没有开启哨兵间无法建立通信,故障转移也不会被执行.

部署前注意基本事项
  1. 如果想部署一个健壮性环境, 至少需要三个哨兵实例
  2. 三个哨兵应该部署在三个不物理机器或者是不同分区的虚拟机中,避免集体失败的概率
  3. 由于redis 是使用的是异步复制, 当发生故障时候, 哨兵 + redis分布是系统并不保证可靠的写操作. 可以部署哨兵让窗口事情写的能力指定在特定的时候.
  4. 使用哨兵需要再客户端的支持,流行的客户端库都有哨兵的支持, 但不是所有的都是
  5. 如果在开发环境中没有进行一次次的测试, 就不会有高可用的应用. 甚至于同样在成产环境下多次测试后, 他们才真正可用. 你如果有一个配置错误, 当显示出来时,已经太晚了(有可能你的master会在凌晨3点停止工作)
  6. 哨兵, Docker,或者其他网络地址端口转换平台, 应该小心的集合使用, Docker 执行的端口冲映射会打断哨兵自动发现其他哨兵和主从. 关于哨兵和Docker的检测章节会在下面提到.
配置哨兵

redis源码描述包含有一个叫做sentinel.conf的文件.它是一个配置说明示例. 可以使用提供的示例来学习配置哨兵;

只需要指定需要监控的主, 并提供每个主一个别名. 不需要配置从机, 哨兵可以通过主自动发现从机器. 当新增一个从机时候,哨兵将会自动更新配置文件. 配置文件随时会被重写, 在主发生故障,从机被选举成新的master时, 或者新的哨兵被发现时候。

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

上面配置了两组redis 实例监控, 每组都由一个master和未定义数量的slaves。

语法格式

sentinel monitor <master-group-name> <ip> <port> <quorum>

第一行是监控一个叫做mymaster的主机,它的ip地址是:127.0.0.1监听端口是6379,并带有两个需要确认数量.

quorum值是哨兵一致认为master主机不可通信的数量, 当发生故障时,quorum 使用检测故障, 为了执行故障转移, 哨兵需要选举成故障转移的领导者,并授权进行. 这些发生在大部分的哨兵的投票中.

例如: 有5个哨兵在运行,并且设置监控master的quorum设置为2:

  • 如果有两个哨兵认为这个master不可通信, 其中一个就会尝试启动故障恢复.

  • 如果至少三个哨兵都可以正常通信, 故障恢复也会被确认并真实的启动.

  • 在实际的项目中,在故障期间,如果大部分的哨兵不能通信,是不能进行故障恢复的.
其他选项

其他属性选项大部分都是这个格式

sentinel <option_name> <master_name> <option_value>
  • down-after-milliseconds 是一个毫秒单位的时间. sentinel启动时如果发现一个redis实例在指定时间内不可通信,就认为它下线了(不可通信包括:不能响应ping命令, 或者返回错误)
  • parallel-syncs 发生故障后,设置slave同时被配置使用新的master的数量。数量越低,故障恢复处理时间就越长, 然而如果slaves被配置到服务旧数据, 你不希望所有的slaves 重新同时同步master信息. 设置一个小值可以规避在故障恢复过程中, 所有的slaves 不可通信的问题.

其他的选项说明可以再sentinel.conf 中找到详细描述; 所有的参数都支持在运行期间修改,可以使用sentinel set 命令,详细下面介绍.

哨兵部署示例

了解了Sentinel的基本信息后,接下来Sentinel 应该安装在哪里,生成环境中需要多少了Sentinel进行协调工作等等,下面展示少许部署实例.下面将使用ASCII art 来展示图形化界面.

+--------------------+
| 这样的一个盒子代表 |
| 一台独立运行物理机 |
| 或者是一台虚拟机   |
|                    |
+--------------------+

我们将运行的程序放到“盒子”里,就像这样:

+-------------------+
| Redis master M1   |
| Redis Sentinel S1 |
+-------------------+

不同的“盒子”可以通过”线“ 连接 代表它们可以进行通信; 就像这样:

+-------------+               +-------------+
| Sentinel S1 |---------------| Sentinel S2 |
+-------------+               +-------------+

网络中断,可以使用双斜杠表示,就像这样:

+-------------+                +-------------+
| Sentinel S1 |------ // ------| Sentinel S2 |
+-------------+                +-------------+

注释:
- Masters 简写:M1, M2, M3, …Mn.
- Slaves 简写: R1, R2, R3, …Rn (R是replica简写)
- Sentinels 简写:S1, S2, S3, …Sn.
- Clients 简写: C1, C2, C3, …Cn.
- 如果一个redis实例由于Sentinel的操作而改变的自身角色, 我们就将它放到一对中括号中,例如:[M1] 意味着由于Sentinel介入实例现在转变成了master.

注意: 为了故障恢复,哨兵需要与大部分的哨兵进行通信, 所以不要部署只有两个的哨兵环境.

实例一: 两个哨兵环境,不要这样做
+----+         +----+
| M1 |---------| R1 |
| S1 |         | S2 |
+----+         +----+

Configuration: quorum = 1
  • 使用这种配置,如果M1异常关闭, R1将被晋升master,两个Sentinel可以正常通信一直认为故障发生(设置的quorum数值是1), 所有这种情况故障情况可以正常工作.
  • 如果M1和S1都不能正常运行,运行的S2不能发现故障, 所以系统将变成了不可用状态.

注 大部分sentinel的都认为发射故障后,会将最新状态配置通知给所有的Sentinel, 上述的情况,单方面都发生故障,没有任何哨兵确认,就会变的很危险

+----+           +------+
| M1 |----//-----| [M1] |
| S1 |           | S2   |
+----+           +------+

使用上面的配置方式, 这里一对称的方式创建了两个master(假设S2不需要取人,就可以故障恢复). client 将不清楚完全独立的两个区域哪边才是正确的.
所以说至少将三个哨兵部署到三个不同的物理机或者虚拟机上.

示例二: 三个boxes的基本设置

这是一个非常简单的设置, 而且很方便进行安全扩展,发布到三个独立的环境中, 每个环境都运行着一组redis和哨兵程序:

       +----+
       | M1 |
       | S1 |
       +----+
          |
+----+    |    +----+
| R2 |----+----| R3 |
| S2 |         | S3 |
+----+         +----+

Configuration: quorum = 2

如果master M1异常关闭, S2和S3将会发现异常,并确认后进行故障恢复, 可以让clients 能够继续使用服务. 在每一个哨兵设置中, 在发生redis 异步复制过程中, 总会有失去一些些的操作的风险, 因为一个确认的写操作,有可能还没有同步到被新选举的Master 中. 上面的设置中,由于异常客户端和老的master隔离了,就会发生写丢失的情况. 就像下面这种情况:

         +----+
         | M1 |
         | S1 | <- C1 (这时候C1的写操作,将会丢失)
         +----+
            |
            /
            /
+------+    |    +----+
| [M2] |----+----| R3 |
| S2   |         | S3 |
+------+         +----+

对于这种由于网络隔离的原因,导致老的master M1与slave失去连接 ,像这种slave R2晋升为新的master的情况中, Client C1又与老的master在同相同的网络区域, 这时C1还可以继续向老的master写数据. 这时候写的数据将会永久性的丢失,当网络隔离恢复正常的情况下, 老的master将会被重新配置成为一个slave,进而丢弃自身的数据.

通过是用redis复制特性可以减少这样的情况发生, 如果master探测到不能给指定数量的slaves 同步写操作了,就会停止接受写的请求. 详细设置如下:

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

通过上面的配置redis的实例, 如果master不能将写操作同步给至少一个slave,就会停止接受写操作. 既然复制过程是异步操作的,过程中无论slave是断开连接或者是在指定的时间max-lag内没有发送异步响应消息,client都不能进行写操作. 然而没有免费的午餐, 使用者的配置,如果两个slaves都失去连接, master将会失去些写能力. 其中优缺点自己权衡.

示例三: 配置sentinel 在客户端

有时候我们只有两个可以用的redis物理机, 一个提供给master,另外一个为slave提供服务. 在示例二中,那种配置是不可行的, 然而我们可以使用下面的方式,将多个sentinels 嵌套在不同的client端.


            +----+         +----+
            | M1 |----+----| R1 |
            | S1 |    |    | S2 |
            +----+    |    +----+
                      |
         +------------+------------+
         |            |            |
         |            |            |
      +----+        +----+      +----+
      | C1 |        | C2 |      | C3 |
      | S1 |        | S2 |      | S3 |
      +----+        +----+      +----+

      Configuration: quorum = 2

使用这种部署方式: 直接将Clients 当作Sentinel对待. 如果大部分的客户端都认为master是连接Ok的, C1, C2, C3是一般Clients,就像 应用服务器.

如果M1和S1所在的box宕机, 毫无疑问故障恢复一定会启动, 然而
不同的网络隔离会引发不同的结果;例如: 如果在clients和redis服务器之间网络出现了问题,哨兵将无法起作用, master 和slave 将变为不可用.

注意如果C3和M1被隔离到了同一个网络分区, 他们被分为了两个网络分区, 跟示例二不同之处就是,被分割的redis示例数量是非对称的,因为这里只有一个主,一个从,所以master和slave断开了连接,master不能停止接受查询操作,否则master 在slave故障恢复期间,将变的完全为不可以用.

示例四: 少于三个嵌套在client的哨兵

在示例三种,如果没有最少三个客户端,那么那种配置将变的不可靠. 有时我们可能会使用的配置环境.

            +----+         +----+
            | M1 |----+----| R1 |
            | S1 |    |    | S2 |
            +----+    |    +----+
                      |
               +------+-----+
               |            |  
               |            |
            +----+        +----+
            | C1 |        | C2 |
            | S3 |        | S4 |
            +----+        +----+

      Configuration: quorum = 3

这种配置虽然有些像示例三,但是在这里我们运行了四个哨兵在四个不同的物理机上; 如果M1宕机, 其他三个哨兵就会执行故障恢复. 理论上如果删除了C2,S4然后设置quorum为2 系统可以正常运行. 然而我们希望无论redis服务端还是我们的应用程序端都具有HA的特性.

快速指导

下面将详细介绍Sentinel API和配置信息, 详细介绍如果配置3个哨兵实例

这里做一些假设:

  • 运行的应用程序示例占用的端口分别是5000, 5001, 5002. 】
  • redis master占用端口为6379,从机slave运行在6380.
  • 示例中使用本机回环地址127.0.1

三个哨兵的配置文件如下 :

port 5000
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1

另为两个处理使用的端口分别是5001和5002其他的配置信息完全相同
注意事项:
- master 配置的名称是mymaster. 每个master都有自的名称, 哨兵可以同时监听多组不同的master和slaves的组合.
- quorum 配置为2
- down-after-milliseconds的值是5000毫米,就是5秒,所以如果在指定时间内接受不到任何响应masters将被认为故障.

询问master的状态

启动哨兵最常用就是检测监控的master是运行良好:

$ redis-cli -p 5000
127.0.0.1:5000> sentinel master mymaster
 1) "name"
 2) "mymaster"
 3) "ip"
 4) "127.0.0.1"
 5) "port"
 6) "6379"
 7) "runid"
 8) "953ae6a589449c13ddefaee3538d356d287f509b"
 9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "735"
19) "last-ping-reply"
20) "735"
21) "down-after-milliseconds"
22) "5000"
23) "info-refresh"
24) "126"
25) "role-reported"
26) "master"
27) "role-reported-time"
28) "532439"
29) "config-epoch"
30) "1"
31) "num-slaves"
32) "1"
33) "num-other-sentinels"
34) "2"
35) "quorum"
36) "2"
37) "failover-timeout"
38) "60000"
39) "parallel-syncs"
40) "1"
当前master包含的地址

由于我们已经指定了哨兵监控对象, 所以哨兵可以作为应用程序提供masters或者slaves信息去连接. 由于存在故障和重配置的情况,应用程序有知道哪些是当前master和slave,所以sentinel提供了Api接口询问:

127.0.0.1:5000> SENTINEL get-master-addr-by-name mymaster
1) "127.0.0.1"
2) "6379"
测试故障恢复

现在我们可以去测试部署的哨兵. 我们可以只停止我们的master,然后查看配置信息是否改变 . 就像这样做:

redis-cli -p 6379 DEBUG sleep 30

这样的配置可以让我们master直接进入休眠等待30s. 这里只是模拟master死亡.
如果你查看了Sentinel日志, 有可能查看到一些下面信息:
1. 每一个哨兵通过+sdown事件,检测出master失去连接.
2. 稍后时间将升级为+odown ,意味多个哨兵都认为master失去了连接.
3. 所有哨兵开始选取一个故障恢复发起者.
4. 故障恢复启动.

欢迎大家吐槽,没有交流就没有进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值