22、哨兵Sentinel机制

学习目标:

1、了解Sentine机制的原理

2、掌握Sentine的搭建

学习过程:

       上一节我们讲到redis的主从配置并不能保证高可用性,仅仅只配置了主从服务器,如果主服务器挂了,那么需要客户端改变连接地址为从服务器才行,在生产环境肯定不可能的,需要实现主从自动切换,可达到高可用的目标。需要结合sentinel监控多个Redis服务,如果主服务器挂了,通过选举重新选举新的主服务器,sentinel是一个独立的进程,其功能类似zookeeper,如果只使用单个sentinel来监控redis集群是不可靠的,所以必要使用sentinel集群,否则一台sentinel挂了,高可用也无法保证了。

我们可以先动手尝试一下,现在我们需要三台电脑.

1) 192.168.137.101、192.168.137.102和192.168.137.103为三台redis服务器,同时也作为sentinel服务器,为什么要三台呢,熟悉zookeeper的同学应该知道,需要2n+1台服务器的。

2) 三台redis服务器各自启动一个Sentinel服务。当然如果你资源充足,也可以使用另外的服务器启动Sentinel服务,但是至少要三台。生产环境你可以部署独立的Sentinel集群,可以监控多个redis集群服务。

3)当master宕机导致不可运行时,Sentinel监控到。通知给其它节点,而剩余节点上的Sentinel将重新选举出新的master,原来的master重新恢复正常后,会加入进来并成为Slave;

4)规定整个架构体系中,master提供读写服务,而slave只提供读取服务,挺资源浪费资源的,因为这样slave节点作为备份节点不提供服务。

   我们接着上一节课的,现在192.168.137.103安装一个redis服务,然后和192.168.137.102一样,作为slave,也就是修改一下redis.confi。具体配置参考上一节课的。

   接着我们在192.168.137.101服务器上面把sentinel.conf复制到/etc/目录,在之前的redis源代码中有这个sentinel.conf文件。

   [root@run1]# cp sentinel.conf /etc/

   编辑并修改内容如下:具体的配置我们后面再说

1

2

3

4

5

6

7

8

sentinel monitor mymaster 192.168.137.101 2

sentinel down-after-milliseconds mymaster 30000

sentinel failover-timeout mymaster 180000

sentinel parallel-syncs mymaster 1

 

daemonize yes

logfile "/var/log/redis/sentinel.log"

protected-mode no  # 这个记得要加上去,不然选择会失败的。

把这个配置文件复制到其他机器上面,也就是说三台服务器的sentinel.conf配置是一样的。

scp sentinel.conf root@192.168.137.102:/etc

scp sentinel.conf root@192.168.137.103:/etc

因为上面我们把日志文件建立到一个文件下面,所以需要建立日志文件

[root@run3 bin]# mkdir -p /var/log/redis/

[root@run3 bin]#  touch sentinel.log

启动sentinel 服务,先把三台redis服务启动了,然后把三台sentinel 服务器启动,在三台服务器也执行下面的启动命令:

./redis-sentinel /etc/sentinel.conf 

查看日志

1259:X 16 Mar 15:01:55.014 * Increased maximum number of open files to 10032 (it was originally set to 1024).

                _._                                                  

           _.-``__ ''-._                                             

      _.-``    `.  `_.  ''-._           Redis 3.2.11 (00000000/0) 64 bit

  .-`` .-```.  ```\/    _.,_ ''-._                                   

 (    '      ,       .-`  | `,    )     Running in sentinel mode

 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379

 |    `-._   `._    /     _.-'    |     PID: 1259

  `-._    `-._  `-./  _.-'    _.-'                                   

 |`-._`-._    `-.__.-'    _.-'_.-'|                                  

 |    `-._`-._        _.-'_.-'    |           http://redis.io        

  `-._    `-._`-.__.-'_.-'    _.-'                                   

 |`-._`-._    `-.__.-'    _.-'_.-'|                                  

 |    `-._`-._        _.-'_.-'    |                                  

  `-._    `-._`-.__.-'_.-'    _.-'                                   

      `-._    `-.__.-'    _.-'                                       

          `-._        _.-'                                           

              `-.__.-'                                               

 

1259:X 16 Mar 15:01:55.016 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

1259:X 16 Mar 15:01:55.016 # Sentinel ID is 4b9874ad82aca4de98a81203c7b3762e2ea04455

1259:X 16 Mar 15:01:55.016 # +monitor master mymaster 192.168.137.101  6379 quorum 2

测试,把master停了,

    192.168.137.101:6379> shutdown 

   看一下sentinel的日志,会重新选举vote-for-leader  ,可以看到最后把switch-master mymaster 192.168.137.101 6379 192.168.137.102 6379,master从192.168.137.101变成了192.168.137.102了。

1259:X 16 Mar 15:10:16.769 # +sdown master mymaster 192.168.137.101 6379

1259:X 16 Mar 15:10:16.873 # +new-epoch 1

1259:X 16 Mar 15:10:16.874 # +vote-for-leader 401a501f69a11d89afb4aa623a828e760e26b5d1 1

1259:X 16 Mar 15:10:17.161 # +config-update-from sentinel 401a501f69a11d89afb4aa623a828e760e26b5d1 192.168.8.234 26379 @ mymaster 192.168.8.234 6379

1259:X 16 Mar 15:10:17.161 # +switch-master mymaster 192.168.137.101 6379 192.168.137.102 6379

查看以下info,确实变成了master了。

# Replication

role:master

connected_slaves:1

slave0:ip=192.168.137.103,port=6379,state=online,offset=40489,lag=0

master_repl_offset:40489

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:2

repl_backlog_histlen:40488

重新启动原理的主服务器,会看到变成了slave服务器了。日志输出

1259:X 16 Mar 15:14:55.444 # -sdown slave 192.168.137.101:6379 192.168.137.103 6379 @ mymaster 192.168.137.102 6379

 

sentinet的维护命令

登陆和管理注意端口不是redis服务的端口哦。

[root@run1 bin]# ./redis-cli -p 6379

127.0.0.1:26379> sentinel masters 

sentinel支持的其他合法命令如下:

PING sentinel回复PONG.

SENTINEL masters 显示被监控的所有master以及它们的状态.

SENTINEL master <master name> 显示指定master的信息和状态;

SENTINEL slaves <master name> 显示指定master的所有slave以及它们的状态;

SENTINEL get-master-addr-by-name <master name> 返回指定master的ip和端口,如果正在进行failover或者failover已经完成,将会显示被提升为master的slave的ip和端口。

SENTINEL reset <pattern> 重置名字匹配该正则表达式的所有的master的状态信息,清楚其之前的状态信息,以及slaves信息。

SENTINEL failover <master name> 强制sentinel执行failover,并且不需要得到其他sentinel的同意。但是failover后会将最新的配置发送给其他sentinel。

Sentinel的配置

   看会我们前面的配置,sentinel.conf文件作为sentinel的配置文件,配置文件自带了关于各个配置项的解释。典型的配置项如下所示:

我们可以看到下面面这样的配置

1

2

3

4

5

6

7

8

9

10

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

    上面的配置项配置了两个名字分别为mymaster和resque的master,配置文件只需要配置master的信息就好啦,不用配置slave的信息,因为slave能够被自动检测到(master节点会有关于slave的消息)。需要注意的是,配置文件在sentinel运行期间是会被动态修改的,例如当发生主备切换时候,配置文件中的master会被修改为另外一个slave。这样,之后sentinel如果重启时,就可以根据这个配置来恢复其之前所监控的redis集群的状态。

    接下来我们将一行一行地解释上面的配置项:

sentinel monitor mymaster 127.0.0.1 6379 2

    这一行代表sentinel监控的master的名字叫做mymaster,地址为127.0.0.1:6379,行尾最后的一个2代表什么意思呢?我们知道,网络是不可靠的,有时候一个sentinel会因为网络堵塞而误以为一个master redis已经死掉了,当sentinel集群式,解决这个问题的方法就变得很简单,只需要多个sentinel互相沟通来确认某个master是否真的死了,这个2代表,当集群中有2个sentinel认为master死了时,才能真正认为该master已经不可用了。(sentinel集群中各个sentinel也有互相通信,通过gossip协议)。

    除了第一行配置,我们发现剩下的配置都有一个统一的格式:

sentinel <option_name> <master_name> <option_value>

    接下来我们根据上面格式中的option_name一个一个来解释这些配置项:

down-after-milliseconds

    sentinel会向master发送心跳PING来确认master是否存活,如果master在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了(subjectively down, 也简称为SDOWN)。而这个down-after-milliseconds就是用来指定这个“一定时间范围”的,单位是毫秒。

    不过需要注意的是,这个时候sentinel并不会马上进行failover主备切换,这个sentinel还需要参考sentinel集群中其他sentinel的意见,如果超过某个数量的sentinel也主观地认为该master死了,那么这个master就会被客观地(注意哦,这次不是主观,是客观,与刚才的subjectively down相对,这次是objectively down,简称为ODOWN)认为已经死了。需要一起做出决定的sentinel数量在上一条配置中进行配置。

parallel-syncs

    在发生failover主备切换时,这个选项指定了最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave处于不能处理命令请求的状态。

    其他配置项在sentinel.conf中都有很详细的解释。所有的配置都可以在运行时用命令SENTINEL SET command动态修改。

配置版本号

    为什么要先获得大多数sentinel的认可时才能真正去执行failover呢?

    当一个sentinel被授权后,它将会获得宕掉的master的一份最新配置版本号,当failover执行结束以后,这个版本号将会被用于最新的配置。因为大多数sentinel都已经知道该版本号已经被要执行failover的sentinel拿走了,所以其他的sentinel都不能再去使用这个版本号。这意味着,每次failover都会附带有一个独一无二的版本号。我们将会看到这样做的重要性。

    而且,sentinel集群都遵守一个规则:如果sentinel A推荐sentinel B去执行failover,A会等待一段时间后,自行再次去对同一个master执行failover,这个等待的时间是通过failover-timeout配置项去配置的。从这个规则可以看出,sentinel集群中的sentinel不会再同一时刻并发去failover同一个master,第一个进行failover的sentinel如果失败了,另外一个将会在一定时间内进行重新进行failover,以此类推。

    redis sentinel保证了活跃性:如果大多数sentinel能够互相通信,最终将会有一个被授权去进行failover.

    redis sentinel也保证了安全性:每个试图去failover同一个master的sentinel都会得到一个独一无二的版本号。

    因为每一个配置都有一个版本号,所以以版本号最大的那个为标准。

    假设有一个名为mymaster的地址为192.168.1.50:6379。一开始,集群中所有的sentinel都知道这个地址,于是为mymaster的配置打上版本号1。一段时候后mymaster死了,有一个sentinel被授权用版本号2对其进行failover。如果failover成功了,假设地址改为了192.168.1.50:9000,此时配置的版本号为2,进行failover的sentinel会将新配置广播给其他的sentinel,由于其他sentinel维护的版本号为1,发现新配置的版本号为2时,版本号变大了,说明配置更新了,于是就会采用最新的版本号为2的配置。

    这意味着sentinel集群保证了第二种活跃性:一个能够互相通信的sentinel集群最终会采用版本号最高且相同的配置。

注意:

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

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

    当网络恢复以后,我们知道sentinel3将会更新它的配置。但是,如果客户端所连接的master被网络隔离,会发生什么呢?

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

    也许你不会希望这个场景发生:

    如果你把redis当做缓存来使用,那么你也许能容忍这部分数据的丢失。

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

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

min-slaves-to-write 1

min-slaves-max-lag 10

   通过上面的配置,当一个redis是master时,如果它不能向至少一个slave写数据(上面的min-slaves-to-write指定了slave的数量),它将会拒绝接受客户端的写请求。由于复制是异步的,master无法向slave写数据意味着slave要么断开连接了,要么不在指定时间内向master发送同步数据的请求了(上面的min-slaves-max-lag指定了这个时间)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值