一、概述

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中的情况了,我们这个时候可以把哨兵转到客户端环境中。

Redis哨兵原理详解的更多相关文章

  1. redis入门到精通系列(九):redis哨兵模式详解

    (一)哨兵概述 前面我们讲了redis的主从复制,为了实现高可用,会选择一台服务器作为master,多台服务器作为slave.现在有这样一种情况,master宕机了,这时系统会选择一台slave作为m ...

  2. Redis哨兵的详解

    1 哨兵的作用 哨兵是redis集群架构中非常重要的一个组件,主要功能如下: 集群监控:负责监控redis master和slave进程是否正常工作 消息通知:如果某个redis实例有故障,那么哨兵负 ...

  3. (转) Redis哨兵的详解

    1 哨兵的作用 哨兵是redis集群架构中非常重要的一个组件,主要功能如下: 1. 集群监控:负责监控redis master和slave进程是否正常工作 2. 消息通知:如果某个redis实例有故障 ...

  4. Redis快照原理详解

    本文对Redis快照的实现过程进行介绍,了解Redis快照实现过程对Redis管理很有帮助. Redis默认会将快照文件存储在Redis当前进程的工作目录中的dump.rdb文件中,可以通过配置dir ...

  5. Redis多线程原理详解

    本篇文章为你解答一下问题: 0:redis单线程的实现流程是怎样的? 1:redis哪些地方用到了多线程,哪些地方是单线程? 2:redis多线程是怎么实现的? 3:redis多线程是怎么做到无锁的? ...

  6. Redis原理详解

    Redis原理详解 数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redi ...

  7. [转]Reids配置文件redis.conf中文详解

    转自: Reids配置文件redis.conf中文详解 redis的各种配置都是在redis.conf文件中进行配置的. 有关其每项配置的中文详细解释如下: 对应的中文版解释redis.conf # ...

  8. Redis AOF 持久化详解

    Redis 是一种内存数据库,将数据保存在内存中,读写效率要比传统的将数据保存在磁盘上的数据库要快很多.但是一旦进程退出,Redis 的数据就会丢失. 为了解决这个问题,Redis 提供了 RDB 和 ...

  9. Redis主从复制机制详解

    Redis主从复制机制详解 Redis有两种不同的持久化方式,Redis服务器通过持久化,把Redis内存中持久化到硬盘当中,当Redis宕机时,我们重启Redis服务器时,可以由RDB文件或AOF文 ...

随机推荐

  1. [转]sql where 1=1和 0=1 的作用

    sql where 1=1和 0=1 的作用 原文地址:http://www.cnblogs.com/junyuz/archive/2011/03/10/1979646.html where 1=1; ...

  2. matlab新手入门(一)(翻译)

    桌面基础知识 启动MATLAB®时,桌面将以其默认布局显示. 桌面包括以下面板: 当前文件夹 - 访问您的文件. 命令窗口 - 在命令行中输入命令,由提示符(>>)指示. 工作区 - 浏览 ...

  3. C# ConfigurationManager 类的使用

    一.前言 在项目中,我们习惯使用 ConfigurationManager 来读取一些常量.如链接数据库字符串.一些需配置的数据(微信.QQ.支付宝)等的配置.我们需要把这些数据记录在 app.con ...

  4. 图解SynchronousQueue原理详解-非公平模式

    SynchronousQueue原理详解-非公平模式 开篇 说明:本文分析采用的是jdk1.8 约定:下面内容中Ref-xxx代表的是引用地址,引用对应的节点 前面已经讲解了公平模式的内容,今天来讲解 ...

  5. Solr 6.7学习笔记(04)-- Suggest

    当我们使用baidu或者Google时,你输入很少的字符,就会自动跳出来一些建议选项,在Solr里,我们称之为Suggest,在solrconfig.xml里做一些简单的配置,即可实现这一功能.配置如 ...

  6. webpack 打包和手动创建一个vue的项目

    首先我们为啥要用webpack,为啥不用其他的打包的工具. 先听我捋捋, Webpack有人也称之为 模块打包机 ,由此也可以看出Webpack更侧重于模块打包,当然我们可以把开发中的所有资源(图片. ...

  7. ThinkSNS+ 是如何计算字符显示长度的

    什么是ThinkSNS+ ThinkSNS(简称TS),一款全平台综合性社交系统,目前最新版本为ThinkSNS+.ThinkSNS V4 ThinkSNS[简]. 今天我们来聊一下可能很多人都会头疼 ...

  8. vue+element-ui实现无限级动态菜单树

    使用vue+element-ui实现无限级动态菜单 该案例实现主要使用递归的思想,递归对新人来容易迷惑的是自己调用自己,直到满足条件为止,接下来我们就一步一步实现一个动态多级菜单vue组件 搭建项目并 ...

  9. eclipse 通过svn导入maven工程

    http://blog.csdn.net/zdnlp/article/details/7238194

  10. 整理的各种模板 (随时弃坑emmmmm)

    线段树: #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> ...