文档章节

分布式Redis深度历险-Sentinel

李红欧巴
 李红欧巴
发布于 07/20 14:35
字数 2358
阅读 3472
收藏 73

上一篇介绍了Redis的主从服务器之间是如何同步数据的。试想下,在一主一从或一主多从的结构下,如果主服务器挂了,整个集群就不可用了,单点问题并没有解决。Redis使用Sentinel解决该问题,保障集群的高可用。

 

如何保障集群高可用

保障集群高可用,要具备如下能力:

  • 能监测服务器的状态,当主服务器不可用时,能及时发现
  • 当主服务器不可用时,选择一台最合适的从服务器替代原有主服务器
  • 存储相同数据的主服务器同一时刻只有一台

要实现上述功能,最直观的做法就是,使用一台监控服务器来监视Redis
服务器的状态。《分布式Redis深度历险-Sentinel》

监控服务器和主从服务器间维护一个心跳连接,当超出一定时间没有收到主服务器心跳时,主服务器就会被标记为下线,然后通知从服务器上线成为主服务器。《分布式Redis深度历险-Sentinel》

当原来的主服务器上线后,监控服务器会将其转换为从服务器。
《分布式Redis深度历险-Sentinel》

按照上述流程似乎解决了集群高可用的问题,但似乎有哪里不对:如果监控服务器出了问题怎么办?我们可以在加上一个从监控服务器,当主服务器不可用的时候顶上。
《分布式Redis深度历险-Sentinel》

但问题是谁来监控’监控服务器’呢?子子孙孙无穷尽也。。

先把疑问放在一旁,先来看下Redis Sentinel集群的实现

 

Sentinel

和上一小节的想法一样,Redis通过增加额外的Sentinel服务器来监控数据服务器,Sentinel会与所有的主服务器和从服务器保存连接,用以监听服务器状态以及向服务器下达命令。

《分布式Redis深度历险-Sentinel》

Sentinel本身是一个特殊状态的Redis服务器,启动命令:
redis-server /xxx/sentinel.conf --sentinel,sentinel模式下的启动流程与普通redis server是不一样的,比如说不会去加载RDB文件以及AOF文件,本身也不会存储业务数据。

 

与主服务器建立连接

Sentinel启动后,会与配置文件中提供的所有主服务器建立两个连接,一个是命令连接,一个是订阅连接。

命令连接用于向服务器发送命令。

订阅连接则是用于订阅服务器的_sentinel_:hello频道,用于获取其他Sentinel信息,下文会详细说。

 

获取主服务器信息

Sentinel会以一定频率向主服务器发送Info命令获取信息,包括主服务器自身的信息比如说服务器id等,以及对应的从服务器信息,包括ip和port。Sentinel会根据info命令返回的信息更新自己保存的服务器信息,并会与从服务器建立连接。

 

获取从服务器信息

与和主服务器的交互相似,Sentinel也会以一定频率通过Info命令获取从服务器信息,包括:从服务器ID,从服务器与主服务器的连接状态,从服务器的优先级,从服务器的复制偏移等等。

 

向服务器订阅和发布消息

如何保障集群高可用小节留下了一个疑问:用如何保证监视服务器的高可用? 在这里我们可以先给出简单回答:用一个监视服务器集群(也就是Sentinel集群)。如何实现,如何保证监视服务器的一致性暂且先不说,我们只要记住需要用若干台Sentinel来保障高可用,那一个Sentinel是如何感知其他的Sentinel的呢?

前面说过,Sentinel在与服务器建立连接时,会建立两个连接,其中一个是订阅连接。Sentinel会定时的通过订阅连接向_sentinel_:hello频道频道发送消息(对Redis发布订阅功能不太了解的同学可以去去了解下),其中包括:

  • Sentinel本身的信息,如ip地址、端口号、配置纪元(见下文)等
  • Sentinel监视的主服务器的信息,包括ip、端口、配置纪元(见下文)等

同时,Sentinel也会订阅_sentinel_:hello频道的消息,也就是说Sentinel即向该频道发布消息,又从该频道订阅消息。
《分布式Redis深度历险-Sentinel》

Sentinel有一个字典对象sentinels,保存着监视同一主服务器的其他所有Sentinel服务器,当一个Sentinel接收到来自_sentinel_:hello频道的消息时,会先比较发送该消息的是不是自己,如果是则忽略,否则将更新sentinels中的内容,并对新的Sentinel建立连接。

 

主观下线

Sentinel默认会以每秒一次的频率向所有建立连接的服务器(主服务器,从服务器,Sentinel服务器)发送PING命令,如果在down-after-milliseconds内都没有收到有效回复,Sentinel会将该服务器标记为主观下线,代表该Sentinel认为这台服务器已经下线了。需要注意的是不同Sentinel的down-after-milliseconds是可以不同的。

 

客观下线

为了确保服务器真的已经下线,当Sentinel将某个服务器标记为主观下线后,它会向其他的Sentinel实例发送Sentinel is-master-down-by-addr命令,接收到该命令的Sentinel实例会回复主服务器的状态,代表该Sentinel对该主服务器的连接情况。

Sentinel会统计发出的所有Sentinel is-master-down-by-addr命令的回复,并统计同意将主服务器下线的数量,如果该数量超出了某个阈值,就会将该主服务器标记为客观下线。

 

选举领头Sentinel

当Sentinel将一个主服务器标记为客观下线后,监视该服务器的各个Sentinel会通过Raft算法进行协商,选举出一个领头的Sentinel。
建议你先看Raft算法的基础知识,再来看下文。

规则:

  • 所有的Sentinel都有可能成为领头Sentinel的资格
  • 每次选举后,无论有没有选出领头Sentinel,配置纪元都会+1
  • 在某个纪元里,每个Sentinel都有为投票的机会
  • 我们称要求其他人选举自己的Sentinel称为源Sentinel,将被要求投票的Sentinel称为目标Sentinel
  • 每个发现主服务器被标记为客观下线且还没有被其他Sentinel要求投票的Sentinel都会要求其他Sentinel将自己设置为头
  • 目标Sentinel在一个配置纪元里,一旦为某个Sentinel(也可能是它自己)投票后,对于之后收到的要求投票的命令,将拒绝
  • 目标Sentinel对于要求投票的命令将回复自己选举的Sentinel的id以及当前配置纪元
  • 源Sentinel在接收到要求投票的回复后:如果回复的配置纪元与自己的相同,则再检测目标Sentinel选举的头Sentinel是不是自己
  • 如果某个Sentinel被半数以上的Sentinel设置成了领头Sentinel,那它将称为领头Sentinel
  • 一个配置纪元只会选出一个头(因为一个头需要半数以上的支持)
  • 如果在给定时间内,还没有选出头,则过段时间再次选举(配置纪元会+1)

还记得我们在文章开头提出的如何保证Redis服务器高可用的问题吗?
答案就是使用若干台Sentinel服务器,通过Raft一致性算法来保障集群的高可用,只要Sentinel服务器有一半以上的节点都正常,那集群就是可用的。

 

故障转移

领头Sentinel将会进行以下3个步骤进行故障转移:

1.在已下线主服务器的所有从服务器中,挑选出一个作为新的主服务器

2.将其他从服务器的主服务器设置成新的

3.将已下线的主服务器的role改成从服务器,并将其主服务器设置成新的,当该服务器重新上线后,就会一个从服务器的角色继续工作

第一步中挑选新的主服务器的规则如下:

1.过滤掉所有已下线的从服务器

2.过滤掉最近5秒没有回复过Sentinel命令的从服务器

3.过滤掉与原主服务器断开时间超过down-after-milliseconds*10的从服务器

4.根据从服务器的优先级进行排序,选择优先级最高的那个

5.如果有多个从服务器优先级相同,则选取复制偏移量最大的那个

6.如果上一步的服务器还有多个,则选取id最小的那个

 

原文:Java架构笔记

免费Java高级资料需要自己领取,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高并发分布式等教程,一共30G。            
传送门:             https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q

© 著作权归作者所有

李红欧巴

李红欧巴

粉丝 43
博文 110
码字总数 342204
作品 0
长沙
私信 提问
加载中

评论(1)

耒耒耒耒耒
耒耒耒耒耒
老哥这个帖子是抄的书上的吧
分布式Redis深度历险-Clustor

Redis集群是Redis官方提供的分布式方案,整个集群通过将所有数据分成16384个槽来进行数据共享。 集群基础实现 一个集群由多个Redis节点组成,不同的节点通过 命令进行连接: 收到命令的节点会...

java知识分子
2018/09/13
29
0
分布式Redis深度历险-Cluster

本文为分布式Redis深度历险系列的第三篇,主要内容为Redis的Cluster,也就是Redis集群功能。 Redis集群是Redis官方提供的分布式方案,整个集群通过将所有数据分成16384个槽来进行数据共享。 ...

李红欧巴
07/22
3.1K
0
redis 主从分布式

1.测试环境 master: 127.0.0.1 6379 slave1: 127.0.0.1 6479 slave2: 127.0.0.1 6579 master-sentinel: 127.0.0.1 26379 slave1-sentinel: 127.0.0.1 26479 slave2-sentinel: 127.0.0.1 26......

大陆大陆
2015/12/03
52
0
基于Docker的Redis高可用集群搭建(redis-sentinel)

前言   之前介绍了用docker来搭建redis主从环境,但这只是对数据添加了从库备份(主从复制),当主库down掉的时候,从库是不会自动升级为主库的,也就是说,该redis主从集群并非是高可用的。...

mario阿东
2018/07/06
0
0
redis主从集群搭建及容灾部署(哨兵sentinel)

Redis也用了一段时间了,记录一下相关集群搭建及配置详解,方便后续使用查阅。 提纲 Redis安装 整体架构 Redis主从结构搭建 Redis容灾部署(哨兵sentinel) Redis常见问题 Redis安装 发行版:...

Zero零_度
2016/08/29
71
0

没有更多内容

加载失败,请刷新页面

加载更多

spring cloud

一、从面试题入手 1.1、什么事微服务 1.2、微服务之间如何独立通讯的 1.3、springCloud和Dubbo有哪些区别 1.通信机制:DUbbo基于RPC远程过程调用;微服务cloud基于http restFUL API 1.4、spr...

榴莲黑芝麻糊
7分钟前
0
0
Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
昨天
6
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
昨天
8
0
详解箭头函数和普通函数的区别以及箭头函数的注意事项、不适用场景

箭头函数是ES6的API,相信很多人都知道,因为其语法上相对于普通函数更简洁,深受大家的喜爱。就是这种我们日常开发中一直在使用的API,大部分同学却对它的了解程度还是不够深... 普通函数和...

OBKoro1
昨天
7
0
轻量级 HTTP(s) 代理 TinyProxy

CentOS 下安装 TinyProxy yum install -y tinyproxy 启动、停止、重启 # 启动service tinyproxy start# 停止service tinyproxy stop# 重启service tinyproxy restart 相关配置 默认...

Anoyi
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部