redis:持久化
redis:主从复制
redis:哨兵
redis:集群

1 概述

1.1 作用

从宏观角度回顾一下Redis实现高可用相关的技术。它们包括:持久化、复制、哨兵和集群,其主要作用和解决的问题是:

  • 持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。
  • 复制:复制是高可用Redis的基础,哨兵和集群都是在复制基础上实现高可用的。复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。
  • 哨兵:在复制的基础上,哨兵实现了自动化的故障恢复。缺陷:写操作无法负载均衡;存储能力受到单机的限制。
  • 集群:通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。

哨兵功能:哨兵的核心功能是主节点的自动故障转移。下面是Redis官方文档对于哨兵功能的描述:

  • 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。
  • 自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
  • 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置提供者和通知功能,则需要在与客户端的交互中才能体现。

1.2 架构

它由两部分组成,哨兵节点和数据节点:

  • 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
  • 数据节点:主节点和从节点都是数据节点。

2 部署

2.1 部署主从节点

在上一篇文章中已经写过部署主从节点,使用主从复制。

redis主从节点部署

2.2 部署sentinel节点

哨兵节点本质上是特殊的Redis节点。

3个哨兵节点的配置几乎是完全一样的,主要区别在于端口号的不同(26379/26380/26381),下面以26379节点为例介绍节点的配置和启动方式;

#sentinel-26379.conf
port 26379
daemonize yes
logfile "26379.log"
sentinel monitor mymaster 192.168.92.128 6379 2
sentinel auth-pass mymaster 密码

其中,sentinel monitor mymaster 192.168.92.128 6379 2 配置的含义是:该哨兵节点监控192.168.92.128:6379这个主节点,该主节点的名称是mymaster(自己配置的),最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。

sentinel auth-pass mymaster 密码 配置的含义是:如果主节点有密码需要在此配置密码。

哨兵节点的启动有两种方式,二者作用是完全相同的:

redis-sentinel sentinel-26379.conf
redis-server sentinel-26379.conf --sentinel

按照上述方式配置和启动之后,整个哨兵系统就启动完毕了。可以通过redis-cli连接哨兵节点进行验证,如下图所示:可以看出26379哨兵节点已经在监控mymaster主节点,并发现了其2个从节点和另外2个哨兵节点

此时在看sentinel的配置文件,以端口为26379的配置文件为例:

其中,dir只是显式声明了数据和日志所在的目录(在哨兵语境下只有日志);

known-slave和known-sentinel显示哨兵已经发现了从节点和其他哨兵;

带有epoch的参数与配置纪元有关(配置纪元是一个从0开始的计数器,每进行一次领导者哨兵选举,都会+1;领导者哨兵选举是故障转移阶段的一个操作,在后文会介绍)。

3 sentinel初始化

启动一个sentinel 使用命令:

redis-sentinel sentinel-26379.conf
redis-server sentinel-26379.conf --sentinel
//这两个命令的效果完成相同

当一个Sentinel启动时,他需要执行以下步骤:

  1. 初始化服务器
  2. 将普通的redis服务器使用的代码替换成sentinel专用代码
  3. 初始化Sentinel状态
  4. 根据给定的配置文件,初始化Sentinel的监视器主服务器列表
  5. 创建连向主服务器的网络连接。

3.1 初始化服务器

首先,因为Sentinel 本质上只是一个运行在特殊模式下的Redis服务器,所以启动Sentinel的第一步,就是初始化一个普通的Redis服务器。

不过,因为Sentinel执行的工作和普通Redis服务器执行的工作不同,所以Sentinel的初始化过程和普通Redis服务器的初始化过程并不完全相同。
例如,普通服务器在初始化时会通过载人RDB文件或者AOF文件来还原数据库状态,但是因为Sentinel并不使用数据库,所以初始化Sentinel时就不会载人RDB文件或者AOF文件。
表16-1展示了Redis服务器在Sentinel模式下运行时,服务器各个主要功能的使用情况。

3.2 使用sentinel专用代码

启动Sentinel的第二个步骤就是将一部分普通的Redis服务器使用的代码替换成Sentinel专用代码。

例如:普通Redis服务器使用redis.c/redisCommandTable作为服务器的命令表:

Sentinel则使用sentinel.c/sentinelcmds作为服务器的命令表,并且其中的INFO命令会使用Sentinel模式下的专用实现sentinel.c/sentinelInfoCommand函数而不是普通redis服务器使用的实现redis.c/infoCommand函数:

这也说明了为什么在Sentinel模式下,Redis服务器不能执行set,eval等命令,因为命令表中没有载入这些命令。

3.3 初始化Sentinel状态

接下来,服务器会初始化sentinel.c/sentinelState结构(叫做,Sentinel状态),这个结构保存了服务器所有和Sentinel功能有关的状态。

3.4 初始化Sentinel状态的master属性

初始化Sentinel状态的masters属性。Sentinel状态中的masters字典记录了所有被Sentinel监视的主服务器的相关信息,其中:

字典的键是被监视主服务器的名字。
而字典的值则是被监视主服务器对应的sentinel. c/ sentinelRedisInstance结构。

每个sentinelRedisInstance结构( 后面简称“实例结构”)代表一个被Sentinel监视
的Redis服务器实例( instance),这个实例可以是主服务器、从服务器,或者另外一个Sentinel。

3.5 创建连向主服务器的网络连接

初始化Sentinel的最后一步是创建连向被监视服务器的网络连接,Sentinel将成为主服务器的客户端,他可以向主服务器发送命令,并从命令恢复中获取相关信息。

创建两个连向主服务器的异步网络连接:

  1. 一个是命令连接,用于向主服务器发送命令,并接受命令回复。
  2. 一个是订阅连接,这个链接专门用于订阅主服务器的_sentinel_:hello频道。

为什么有两个连接?
在Redis目前的发布与订阅功能中,被发送的信息都不会保存在Redis服务器里面,如果在信息发送时,想要接收信息的客户端不在线或者断线,那么这个客户端就会丢失这条信息。因此,为了不丢失_ sentine1__ :he1lo 频道的任何信息,Sentinel 必须专门用一个订阅连接来接收该频道的信息。

另一方面,除了订阅频道之外,Sentinel 还必须向主服务器发送命令,以此来与主服务器进行通信,所以Sentinel还必须向主服务器创建命令连接。

因为Sentinel需要与多个实例创建多个网络连接,所以Sentinel 使用的是异步连接。

4 基本原理

4.1 发送info信息

4.1.1 向主服务器发送

Sentinel默认会以每10秒一次的频率,通过命令连接向被监视的主服务器发送INFO命令,并通过分析INFO命令的回复来获取主服务器的当前信息。

通过分析主服务器返回的INFO命令回复,Sentinel可以获取两方面的信息:

  1. 关于主服务器本身的信息,包括run_id域记录的服务器运行ID,以及role域记录的服务器角色
  2. 关于主服务器下属的所有从服务器信息,每个从服务器都由一个“slave”字符串开头的行记录,每行的ip=域记录了从服务器的IP地址,而port=域记录从服务器端口,根据这些sentinel无须用户提供从服务器的地址信息,就可以自动发现从服务器。

4.1.2 向从服务发送

当Sentinel发现主服务器有新的从服务器出现时,Sentinel会为这个新的从服务器创建相应的实例结构(实例结构保存在主服务器的实例结构中),Sentinel还会创建连接到从服务器的命令连接和订阅连接。

创建命令连接之后,Sentinel会和对主服务器一样,在默认的情况下,会以每10秒一次的频率发送INFO命令,获取类似以下信息:

获取到信息,Sentinel会对保存的从服务器实例结构更新。

4.2 发送publish信息

在默认情况下,Sentinel会以每两秒一次的频率,通过命令连接向所有被监视的主服务器和从服务器发送以下格式的命令:

这条命令向服务器的_sentinel_:hello 频道发送了一条信息。信息中包括sentinel和主服务器的相关信息。

4.3 接收频道信息

Sentinel对_sentinel_:hello频道的订阅会一直持续到Sentinel与服务器的连接断开为止。

对于每一个Sentinel连接的服务器,Sentinel既可以通过命令连接向服务器的_sentinel_:hello频道发送信息,又可以通过订阅连接从服务器的_sentinel_:hello频道接收信息。

对于监视同一个服务器的多个Sentinel来说,一个Sentinel发送的信息会被其他Sentinel(包括自己)接收到,这些信息可以用于更新其他Sentinel对发送信息Sentinel的认知,也会更新其他Sentinel对被监视器服务器的认知。

Sentinel接收到自己的信息会不做处理,如果是其他Sentinel信息会对监视服务器的实例进行更新保存其他Sentinel的信息。

当Sentinel通过频道信息发现一个新的Sentinel时,不仅会为新的Sentinel在监视服务器的实例结构的sentinels字典中创建相应的实例结构,还会创建一个连向新Sentinel的命令连接,而新的Sentinel也会同样创建连向这个Sentinel的命令连接,最终监视同一主服务器的多个Sentinel将形成相互连接的网络:

Sentinel之间不会创建订阅连接

Sentinel在连接主服务器或者从服务器时,会同时创建命令连接和订阅连接,但是在连接其他Sentinel时,却只会创建命令连接,而不创建订阅连接。这是因为Sentinel需要通过接收主服务器或者从服务器发来的频道信息来发现未知的新Sentinel,所以才需要建立订阅连接,而相互已知的Sentinel只要使用命令连接来进行通信就足够了。

4.4 检测服务器状态

4.4.1 检测主观下线状态

在默认情况下,Sentinel会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器,从服务器,其他Sentinel在内)发送PING命令,并通过实例返回的PING命令回复来判断实例是否在线。

实例对PING命令的回复可以分为以下两种情况:

  1. 有效回复:实例返回+PONG,-LOADING,-MASTERDOWN三种回复的其中一种。
  2. 无效回复:返回除以上三种之外的信息或者在指定时限中没有返回任何回复。

Sentinel配置文件中的down-after-milliseconds选项指定了Sentinel判断实例进入主观下线所需的时间长度:如果一个实例在down-after-millsecods毫秒内,连续向Sentinel返回无效回复,那么Sentinel会修改这个实例所对应的实例结构,在结构的flags属性中打开SRI_S_DOWN标识,以此来表示这个实例已经进入主观下线状态。

这个选项不仅作为监视的主服务器的判断主观下线状态,也是主服务器的从服务器,以及其他的Sentinel判断下线的状态。

4.4.2 检查客观下线状态

需要特别注意的是,客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。

当Sentinel 将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会向同样监视这一主服务器的其他Sentinel进行询问,看它们是否也认为主服务器已经进入了下线状态(可以是主观下线或者客观下线)。当Sentinel从其他Sentinel那里接收到足够数量(这个数量是在Sentinel中配置的)的已下线判断之后,Sentinel 就会将从服务器判定为客观下线,并对主服务器执行故障转移操作。

4.5 选举领头Sentinel

当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel会进行协商,选举出一个领头的Sentinel,并由领头Sentinel对下线主服务器执行故障转移操作。

在一次配置纪元中,发现主服务器客观下线的Sentinel会要求其他监视主服务器的Sentinel选举自己为局部领头Sentinel(向其他Sentinel发送信息,最先接收到哪个Sentinel的信息就选举哪个Sentinel为局部领头Sentinel),如果超过所有Sentinel数量的一半,那么就选举成功,配置纪元+1进行领头Sentinel故障转移,如果都没有超过一半,那么配置纪元+1,再次进行选择。

4.6 故障转移

在选举产生出领头Sentinel之后,领头Sentinel将对已下线的主服务器执行故障转移操
作,该操作包含以下三个步骤:

(1) 在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为
主服务器。

故障转移操作第一步 要做的就是在已下线主服务器属下的所有从服务器中,挑选出一个状态良好、数据完整的从服务器,然后向这个从服务器发送SLAVEOF no one命令,将这个从服务器转换为主服务器。

补充:redis设计与实现

(2)让已下线主服务器属下的所有从服务器改为复制新的主服务器。

当新的主服务器出现之后,领头Sentinel下一步要做的就是,让已下线主服务器属下的所有从服务器去复制新的主服务器,这一动作可以通过向从服务器发送SLAVEOF命令来实现。

(3)将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线
时,它就会成为新的主服务器的从服务器。

故障转移的最后就是,将已下线的主服务器设置为新的主服务器的从服务器。

5 相关配置和实践建议

搬运文档

5.1 相关配置

与哨兵相关的几个配置。

(1) sentinel monitor {masterName} {masterIp} {masterPort} {quorum}

sentinel monitor是哨兵最核心的配置,在前文讲述部署哨兵节点时已说明,其中:masterName指定了主节点名称,masterIp和masterPort指定了主节点地址,quorum是判断主节点客观下线的哨兵数量阈值:当判定主节点下线的哨兵数量达到quorum时,对主节点进行客观下线。建议取值为哨兵数量的一半加1。

(2) sentinel down-after-milliseconds {masterName} {time}

sentinel down-after-milliseconds与主观下线的判断有关:哨兵使用ping命令对其他节点进行心跳检测,如果其他节点超过down-after-milliseconds配置的时间没有回复,哨兵就会将其进行主观下线。该配置对主节点、从节点和哨兵节点的主观下线判定都有效。

down-after-milliseconds的默认值是30000,即30s;可以根据不同的网络环境和应用要求来调整:值越大,对主观下线的判定会越宽松,好处是误判的可能性小,坏处是故障发现和故障转移的时间变长,客户端等待的时间也会变长。例如,如果应用对可用性要求较高,则可以将值适当调小,当故障发生时尽快完成转移;如果网络环境相对较差,可以适当提高该阈值,避免频繁误判。

(3) sentinel parallel-syncs {masterName} {number}

sentinel parallel-syncs与故障转移之后从节点的复制有关:它规定了每次向新的主节点发起复制操作的从节点个数。例如,假设主节点切换完成之后,有3个从节点要向新的主节点发起复制;如果parallel-syncs=1,则从节点会一个一个开始复制;如果parallel-syncs=3,则3个从节点会一起开始复制。

parallel-syncs取值越大,从节点完成复制的时间越快,但是对主节点的网络负载、硬盘负载造成的压力也越大;应根据实际情况设置。例如,如果主节点的负载较低,而从节点对服务可用的要求较高,可以适量增加parallel-syncs取值。parallel-syncs的默认值是1。

(4) sentinel failover-timeout {masterName} {time}

sentinel failover-timeout与故障转移超时的判断有关,但是该参数不是用来判断整个故障转移阶段的超时,而是其几个子阶段的超时,例如如果主节点晋升从节点时间超过timeout,或从节点向新的主节点发起复制操作的时间(不包括复制数据的时间)超过timeout,都会导致故障转移超时失败。

failover-timeout的默认值是180000,即180s;如果超时,则下一次该值会变为原来的2倍。

5.2 实践建议

(1)哨兵节点的数量应不止一个,一方面增加哨兵节点的冗余,避免哨兵本身成为高可用的瓶颈;另一方面减少对下线的误判。此外,这些不同的哨兵节点应部署在不同的物理机上。

(2)哨兵节点的数量应该是奇数,便于哨兵通过投票做出“决策”:领导者选举的决策、客观下线的决策等。

(3)各个哨兵节点的配置应一致,包括硬件、参数等;此外,所有节点都应该使用ntp或类似服务,保证时间准确、一致。

(4)哨兵的配置提供者和通知客户端功能,需要客户端的支持才能实现,如前文所说的Jedis;如果开发者使用的库未提供相应支持,则可能需要开发者自己实现。

(5)当哨兵系统中的节点在docker(或其他可能进行端口映射的软件)中部署时,应特别注意端口映射可能会导致哨兵系统无法正常工作,因为哨兵的工作基于与其他节点的通信,而docker的端口映射可能导致哨兵无法连接到其他节点。例如,哨兵之间互相发现,依赖于它们对外宣称的IP和port,如果某个哨兵A部署在做了端口映射的docker中,那么其他哨兵使用A宣称的port无法连接到A。

6 总结

在主从复制的基础上,哨兵引入了主节点的自动故障转移,进一步提高了Redis的高可用性;但是哨兵的缺陷同样很明显:哨兵无法对从节点进行自动故障转移,在读写分离场景下,从节点故障会导致读服务不可用,需要我们对从节点做额外的监控、切换操作。

此外,哨兵仍然没有解决写操作无法负载均衡、及存储能力受到单机限制的问题;这些问题的解决需要使用集群。

7 参考文档

https://www.cnblogs.com/kismetv/p/9609938.html

redis的设计与实现

Redis:哨兵(sentinel)相关推荐

  1. Redis哨兵(sentinel)

    Redis哨兵(sentinel) [目标] 掌握解决主从复制故障的解决方案 掌握哨兵监控的搭建 掌握哨兵监控机制及故障的自动转移 [理论知识] 哨兵监控架构设计 主观和客观下线 Leader选举流程 ...

  2. Redis 哨兵Sentinel 文档

    Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务: 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服 ...

  3. Redis哨兵Sentinel的搭建和原理说明

    原文地址:http://www.cnblogs.com/zhoujinyi/p/5570024.html 背景: Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Red ...

  4. Redis哨兵Sentinel

    Sentinel 是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器以及它们的下属从服务器. 1.Sentinel基本监视原理 如下图显 ...

  5. redis哨兵模式没有切换主机_Redis哨兵(Sentinel)模式

    Redis哨兵(Sentinel)模式 在这里插入图片描述 一.主从复制高可用 当我们使用主从复制出现的问题 手动故障转移 写能力和存储能力受限 主从复制 -master 宕机故障处理 主从切换技术的 ...

  6. redis logfile 只读_docker 配置redis主从,哨兵sentinel

    注释:docker自行安装,主从使用一主两从,然后使用sentinel进行高可用配置,当主服务器挂掉,从服务器自动升为主服务器. 主从模式介绍 主从模式是三种模式中最简单的,在主从复制中,数据库分为两 ...

  7. redis 系列25 哨兵Sentinel (高可用演示 下)

    原文:redis 系列25 哨兵Sentinel (高可用演示 下) 一. Sentinel 高可用环境准备 1.1 Sentinel 集群环境 环境 说明 操作系统版本 CentOS  7.4.17 ...

  8. redis 哨兵模式 cluster模式区别_Redis哨兵(Sentinel)模式快速入门

    当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用. 所以更多时候,我们优先考虑哨兵(sentinel) 模式. Redis sentin ...

  9. Redis哨兵模式(sentinel)学习总结及部署记录(主从复制、读写分离、主从切换)

    Redis的集群方案大致有三种:1)redis cluster集群方案:2)master/slave主从方案:3)哨兵模式来进行主从替换以及故障恢复. 一.sentinel哨兵模式介绍 Sentine ...

  10. Redis 哨兵(sentinel)模式集群配置(5.0.3版本)

    一.准备工作 1.系统环境:centos6.4 2.服务器六台(1主5从): 192.168.1.161(master) 192.168.1.162(slave) 192.168.1.163(slav ...

最新文章

  1. Spring in Action 4th 学习笔记 之 AOP
  2. win10系统下“从开始屏幕取消固定”无反应解决方法
  3. 计算机科学的理论基础
  4. matlab转向梯形优化设计,转向梯形优化设计matlab程序
  5. maven生成jar,运行却提示没有“没有主清单属性”
  6. php 实现百度文库搭建
  7. python实现范围框跟随_调整边界框的大小和位置,同时使其稍微居中
  8. [Python] Ubuntu 16.04 上安装 python3.7 和 pip 并配置虚拟环境
  9. python框架django教程_[Python] Django框架入门3——深入视图
  10. C++ 日志框架总结
  11. 人口logistic模型公式_数学建模logistic人口增长模型
  12. 早悟兰因(兰因絮果)
  13. c语言斐波那契数列_母函数——斐波那契数列通项公式
  14. Linux上Meson安装及使用
  15. (Python学习) 10位老师随机分配到4个教室,保证每个教室至少有2个老师
  16. 华为HMS全球应用创新大赛启动 百万美元奖金激励开发者
  17. 微软发布安卓手机的Office预览版,需申请内测
  18. Linux 命令行操作 while read ; cut 提取指定列; uniq命令并计数;sort 命令倒序查找
  19. mysql格式化日期如果日期为空_为什么在使用MySQL数据库格式化日期时,此查询会提供一个空集?...
  20. echarts 去掉折线图中的圆点

热门文章

  1. Node.js学习入门手册
  2. mac 使用altool上传iOSApp到App Store Connect
  3. 云原生k8s之CA证书创建和使用
  4. 《数字孪生电网白皮书》发布 UINO打造电力行业数字化转型新引擎
  5. oracle保留两位小数 00,oracle保留小数,例如0.00
  6. 人体24小时使用手册
  7. 在线eps转pdf,MATLAB导出图片不清晰,fig转为eps显示不全
  8. Ubuntu18.04等远程桌面无法打开终端和文件管理器解决方法
  9. 写给大忙人看的进程和线程
  10. 48074-75-5,m-PEG5-2-methylacrylateMichael加成反应中,丙烯酸甲酯基团与胺反应