您的位置:首页 > 数据库 > Redis

Redis哨兵原理详解

2020-02-06 14:06 337 查看

 

一、概述

Redis哨兵(以下称哨兵)是为Redis提供一个高可靠解决方案,对一定程序上的错误,可以不需要人工干预自行解决。

哨兵功能还有监视、事件通知、配置功能。以下是哨兵的功能列表:

监控:不间断的检查主从服务是否如预期一样正常工作

事件通知:对被监视的redis实例的异常,能通知系统管理员,或者以API接口通知其他应用程序。

智能援救:当被监视的主服务异常时,哨兵会智能的把某个从服务提升为主服务,同时其他从服务与新的主服务之间的关系将得到重新的配置。应用程序将通过redis服务端重新得到新的主服务的地址并重新建立连接。

配置服务:客户端可连接哨兵的接口,获得主从服务的相关信息,如果发生改变,哨兵新通知客户端。

 

哨兵的分布式

哨兵是个分布式系统,通过配置文件可以多个哨兵合作,以实现它的健壮性:

1.某个主服务是否正常,需要通过多个哨兵确认,这样可保证误判的低概率。

2.当哨兵工作的时候,总会有个别哨兵不能正常运行,如个别系统出现故障,所以多个哨兵合作运行,保证了系统的健壮性。

所有的哨兵、redis实例(包括主与从)和客户端相互之间会有交互,这是一个大的分布式系统,在此文档中将由浅入深地介绍哨兵的基础概念,以便更好的理解其基本属性,然后是更复杂的特性,让你理解它是如果精确的工作。

 

二、开始

1.获得哨兵

哨兵当前为Sentinel 2,它是在原来版本的基础上用了更健壮更简单的预演算法(后文有详解)。

哨兵的稳定版本与redis2.8与redis3.0一起发布,新特性的研发在不稳定版本分支时,当它被确认稳定后,将会被追加到redis2.8与redis3.0版本中。

与redis2.6一起发行的Sentinel 2版本,已淘汰不可用。

2.运行哨兵

如果有哨兵的可执行文件(或者与redis server执行文件有个符号连接(自己查阅Linux连接文件知识)),可通过如下的命令行启动哨兵:

redis-sentinel /path/to/sentinel.conf

不然,就得通过redis server执行文件的哨兵模式直接用以下命令启动:

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

以上两个方式的效果是一样的。

但是当哨兵正运行时,必须使用配置文件,它可以记载哨兵运行状态,当哨兵重启时可重用(重新载入配置文件)。如果没指定配置文件,或者路径不可写(因为需要往配置文件更新运行时状态)那哨兵将不能正常启动的。

哨兵的默认开启的TCP服务端口是26379,所以需要把此端口的防火墙、端口映射之类的工作做好,以便其他哨兵能与其交互、协商相关的工作,不然对redis的援救之类的工作就无法运行了。

3.布置前你必须知道的

1.你最少需要三个哨兵实例,以提高健壮性。

2.三个实例可以布置在不同计算机或者虚拟机中,然而需要确保他们出问题的话,互不影响,如它们运行在相互不影响的不同的物理机或者虚拟机中。

3.哨兵+redis分布系统并不能保证100%的异常通信的写安全,当故障发生时。但是可能有其他方式来调节“窗口”(自行查阅TCP/IP通信相关资料)来保证数据丢失控制在一定范围内,如果没有其他更好的解决方案的话。

4.你需要让你的客户端支持哨兵,设计好的客户端都支持哨兵。

5.在开发环境中,如果没有HA设置(对布置的系统反复测试),它也算安全的,但是在生产环境,那可能会导致一些未知错误,当你发现的时候可能已经晚了。歪国人真是废话多,就是一句话,告诉你在生产环境中,最好要反复测试。

6.对于哨兵、Docker或者其他寻址、端口映射工具要合理应用:Docker是端口从映射,侦测其他哨兵的存在与主服务的从服务列表,关于哨兵与Docker的详细信息参见后文相关章节。

 

4.配置哨兵

与redis一起发布的源文件中,有一个“sentinel.conf”自说明的配置文件模板,它是很好的官方配置说明,以下是最简单的配置项:

sentinel monitor mymaster 127.0.0.1 6379 2

sentinel down-after-milliseconds mymaster60000

sentinel failover-timeout mymaster 180000

sentinel parallel-syncs mymaster 1

sentinel monitor resque 192.168.1.3 6380 4

sentinel down-after-milliseconds resque10000

sentinel failover-timeout resque 180000

sentinel parallel-syncs resque 5

只要设定待监控的主服务,并给它取一个唯一的名称,从服务会被自动检查到,不需要手动指定。哨兵将更新配置文件,当以下几种情况发生时,1.新的从服务被侦测到,2.当异常发生,有从服务被提升为主服务时,3.新的哨兵被侦测到时。

在以上示例中,有两个redis实例被监控,一个主服务与一个未命名的从服务,分别叫mymaster和resque:

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

sentienl monitor是告诉哨兵监控一个叫做mymaster的实例,它的地址与端口分别是127.0.0.1和6379,然后quorum是什么意思呢?

c它是一个权重,如果为2,也就是说最少有2个哨兵认为此主服务down了,授权给它发起援救程序。

c事实上quorum只是用于检测故障,而实行救援,将选举出某个哨兵,并被授权负责救援工作才能实行,而只有在多数哨兵在岗的情况下才能实行选举并实行这项任务。

例如有5个在岗哨兵,主服务的quorum被设置为2,那将发生什么情况:

c如果有两个哨兵认为主服务down了,那它们两中的一个负责与救援工作。

c这里最少有三个哨兵在岗,并想到能交互,救援工作才能被授权,真实的救援工作才能开始。

事实上,如果多数(这里多数少数的概念应该是对半分,超过50%为多数)的哨兵不在岗,不能相互交互,那救援工作是不可能实行的。

 

其他项的说明:

其他项的格式都是一样的,如下:

sentinel <option_name> <master_name> <option_value>

cdown-after-milliseconds是哨兵在多少毫秒内无法联系上的话,这个实例将被认为已经down了,它是个时限。

cparallel-syncs从服务通过地救援成为新的主服务后,与新主服务进行再同步的从服务个数,此值越小,救援花费的时间越长(这个并没有理解),但是越大就意味着越多的从服务因为与主服务同步而不可用。所以把此值设置为1,来保证每次只有一个从服务因为同步而不可用。

其他项的介绍请参看后文,同时在与redis共同发布的setinel.conf文件里也有自说明。

所有的参数项都可能通过SENTINEL SET命令来修改,关于此指令的说明请参看后后续章节的“运行时哨兵重配置”。

三、配置样例

1.概述

经过前章节的介绍,现在知道了关于哨兵的一些基本知识,现在也许你想知道我们应该把哨兵布置在哪里?需要多少哨兵实例?现在我们以简单的图例来说明如何布置等问题:

一个这样的框,我们叫它为一个“盒子”,它可以是一个物理机或虚拟机,如果有失败、故障它将是独立的,不影响其他“盒子”。

如图,M1表示主服务1,而S1表示哨兵1。

不同的盒子之间用线相连,表示他们之间是可以交互的。

网络隔离不可相互交流的话,连线之间加双斜线,表示隔离的。

总结如下:

c M1, M2, M3, ..., Mn代表主服务。

c R1, R2, R3, ..., Rn(R可以理解成Replica(复制))代表从服务。

c S1, S2, S3, ..., Sn代表哨兵。

c C1, C2, C3, ..., Cn代表客户端。

c如果有的角色由于哨兵的调度转变了,那用方括号把它括起来,如[M1]表示它现在是个主服务。

2.样例1:两个哨兵

只有两个哨兵的情况,是无法正常开展救援工作的,因为无法通过以获得多数票来得到授权。

c如果M1主服务Down了的话,那R1将被提升为主服务,在两个哨兵能达成救援决议,因为出席数(quorum)为1,所以能发起救援程序,因为获得两个哨兵的支持,为多数方。所以很明显它是能正常工作的。为什么又不能正常工作呢,请看下一种情况。

c如果M1所在的“盒子”停止了工作,那S1当然也是DOWN了,只剩下S2是无法拿到救援授权的,这样的话整个系统就DOWN了。

所以最少三个哨兵布置到三个不同的独立环境中是非常必要的。

3.样例2:标配(三个独立环境)

最基本的配置,三个哨兵在三个不同的独立环境中,每个环境跑一个redis实例与一个哨兵。如下图:

 

如果M1主服务DOWN了的话,S2与S3能达成协议发起救援程序。然后,redis一般都设置为异步通信的,所以必然会有一些数据还没来得及同步到自己的从服务时,主服务Down了,而这里从服务提升为主服务,这个时候那必然会丢失一些数据,但是这里有更可怕的风险,因为客户端与旧的主服务一起被隔离于其他实例。如下图:

当M1所在的“盒子”与其他“盒子”失去联系,那S2与S3将达成救援协议,把R2提升为主服务,但是可怕的是,因为客户端原先就与M1在同一边的,可能C1与M1之间通信还是正常的,C1还不停的往M1注入数据呢,等到M1与其他redis实例之间的通信恢复后,哨兵会把M1降为M2的从服务,M2才是新的主服务,这个时候,M1(已经是S1)将以M2为主服务,并以M2数据为准进行同步,可悲的事情发生了,C1在M1与其他redis断网期间写入的数据,将彻底的丢失了。

这个问题可以通过以下的redis主从复制的特性得到解决,即当主服务无法将数据同步到自己的指定数量的从服务的时候,那就停止接收数据的写入。

min-slaves-to-write 1

min-slaves-max-lag 10

以上配置效果是,当M1不能把自己的内容同步给最少一个从服务(S2、S3都写入不了了),其实这种情况下,从服务也与主服务失去了连接,那主服务将拒绝客户端的写入。或者没有收到任何一个从服务的回馈超过10秒钟,也会导致一样的效果。通过此配置,M1在10秒钟之后将拒绝写入,当M1的局部网络恢复后,哨兵将重新配置他们的角色,C1也会重新找到谁是新的主服务,当然10秒钟的数据丢失那也是难免的了。

然而,天下并没有免费的午餐,如果两个从服务同时down了的话,那主服务将拒绝写入操作,这犹如该死的政治妥协,让人不爽。

4.样例3:哨兵在客户端环境中

有的时候,我们只有两个独立的环境,一个布置主服务,一个布置从服务。那将发生样例2中的情况了,我们这个时候可以把哨兵转到客户端环境中。

 

 

 

 

转载于:https://www.cnblogs.com/MingoJiang/p/8682012.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
站内首发文章 ddy34589 发布了0 篇原创文章 · 获赞 0 · 访问量 125 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: