前文回顾

建议前面文章没看过的同学先看下前面的文章:

「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」

「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩、击穿、穿透」

「老司机带你玩转面试(3):Redis 高可用之主从模式」

哨兵模式

前面介绍了 Redis 的主从模式,主从模式只能实现读高可用,致命的弱点是写无法高可用,一旦 master 节点挂了,整个集群将无法写入数据,这并不符合我们对 Redis 高可用集群的期望。

那么,是不是有一种方法,可以做到不仅仅读高可用,写一样要高可用,当然有,这就是我们今天要介绍的哨兵模式。

哨兵模式可以理解成主从模式的一个升级版,主从模式 master 节点和 slave 节点是一开始就定好的,而在哨兵模式中, master 节点是可以转移,一旦发现当前的 master 节点挂掉,通过选举可以指定一个 slave 节点晋升成为 master ,保证在任何情况下,都有 master 节点可以支持写入操作,也间接实现了写高可用。

简介

哨兵模式可以看做是前面主从模式的一个升级版,主从模式没有故障转移, master 节点挂了就挂了,而哨兵模式就是为了解决这个问题而出现的。

  • 集群监控:负责监控 Redis master 和 slave 进程是否正常工作。
  • 消息通知:如果某个 Redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
  • 故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
  • 配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。

核心

假如我们现在有两个哨兵实例,就长下面这样:

+----+         +----+
| M1 |---------| R1 |
| S1 | | S2 |
+----+ +----+

再了解两个参数: quorum 、 majority

  • quorum: 表示认为 master 宕机的哨兵数量。
  • majority: 表示授权进行主从切换的最少的哨兵数量,而这个数字,需要大于一半。

在只有两个节点的情况下,如果 master 宕机, s1 和 s2 中只要有 1 个哨兵认为 master 宕机了,就可以进行切换,同时 s1 和 s2 会选举出一个哨兵来执行故障转移。

这时,需要 majority,也就是大多数哨兵都是运行的。

所以此时,如果此时仅仅是 M1 进程宕机了,哨兵 s1 正常运行,那么故障转移是 OK 的。但是如果是整个 M1 和 S1 运行的机器宕机了,那么哨兵只有 1 个,此时就没有 majority 来允许执行故障转移,虽然另外一台机器上还有一个 R1,但是故障转移不会执行。

所以就有了以下这一条建议:

  • 哨兵至少需要 3 个实例,来保证自己的健壮性,并且实例数量最好是奇数。

因为在进行选举的时候,需要超过一半的哨兵同意,也就是 majority 。

2 个哨兵,majority=2
3 个哨兵,majority=2
4 个哨兵,majority=2
5 个哨兵,majority=3
6 个哨兵,majority=3
7 个哨兵,majority=4
...

可以看到,只有在奇数的时候,是可以最大化的利用 majority 数量。

经典的三哨兵模型下面这样:

       +----+
| M1 |
| S1 |
+----+
|
+----+ | +----+
| R2 |----+----| R3 |
| S2 | | S3 |
+----+ +----+

如果 M1 所在机器宕机了,那么三个哨兵还剩下 2 个,S2 和 S3 可以一致认为 master 宕机了,然后选举出一个来执行故障转移,同时 3 个哨兵的 majority 是 2,所以还剩下的 2 个哨兵运行着,就可以允许执行故障转移。

Redis 哨兵模式数据丢失问题

首先先说一个结论:

  • 哨兵 + Redis 主从的部署架构,是不保证数据零丢失的,只能保证 Redis 集群的高可用性。

然后我们再说两种会导致数据丢失的情况:

第一种:是异步复制可能会导致数据丢失

由于 master 向 salve 复制数据是异步,有可能,有部分数据还没有向 salve 复制,这时 master 宕机了,那么这部分数据就丢失了。

第二种:脑裂导致的数据丢失

脑裂是指,由于网络波动或者其他因素影响, master 所在的机器突然间无法被其他哨兵梭访问到,但是实际上这个 master 节点还在正常运行中。

此时哨兵会以为这个 master 节点已经宕机,开始进行新的 master 节点的选举,将其他的 salve 节点切换成了 master 节点,这时集群中就会存在两个 master 节点,也就是脑裂产生了。

这时虽然产生了新的 master 节点,但是客户端可能还没进行切换,还在像老的 master 写数据,但是当老的 master 恢复访问的时候,会被作为一个 salve 挂载到新的 master 节点上,自己的数据会被清空,重新从新的 master 复制数据,而在脑裂过程中写入老的 master 的数据就这么没了。

数据丢失的解决方案有么?没有,因为这个问题是客观存在的,我们解决不了这个问题,只能尽量的去减少这个问题带来的损失,这时,可以使用下面这两个配置:

min-slaves-to-write 1
min-slaves-max-lag 10

这两个配置的意思是:

两个参数的意思:

  • 要求至少有 1 个 slave ,数据复制和同步的延迟不能超过 10 秒。
  • 如果说一旦所有的 slave ,数据复制和同步的延迟都超过了 10 秒钟,那么这个时候, master 就不会再接收任何请求了。

(1) 减少异步复制的数据丢失:

有了 min-slaves-max-lag 这个配置,就可以确保说,一旦 slave 复制数据和 ack 延时太长,就认为可能 master 宕机后损失的数据太多了,那么就拒绝写请求,这样可以把 master 宕机时由于部分数据未同步到 slave 导致的数据丢失降低的可控范围内。

(2) 减少脑裂的数据丢失:

如果一个 master 出现了脑裂,跟其他 slave 丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的 slave 发送数据,而且 slave 超过 10 秒没有给自己 ack 消息,那么就直接拒绝客户端的写请求。

这样脑裂后的旧 master 就不会接受 client 的新数据,也就避免了数据丢失。

上面的配置就确保了,如果跟任何一个 slave 丢了连接,在 10 秒后发现没有 slave 给自己 ack ,那么就拒绝新的写请求

因此在脑裂场景下,最多就丢失 10 秒的数据。

主观宕机和客观宕机

  • sdown: 主观宕机,就一个哨兵如果自己觉得一个 master 宕机了,那么就是主观宕机。
  • odown: 客观宕机,如果 quorum 数量的哨兵都觉得一个 master 宕机了,那么就是客观宕机。

sdown 达成的条件很简单,如果一个哨兵 ping 一个 master,超过了 is-master-down-after-milliseconds 指定的毫秒数之后,就主观认为 master 宕机了;如果一个哨兵在指定时间内,收到了 quorum 数量的其它哨兵也认为那个 master 是 sdown 的,那么就认为是 odown 了。

参考

https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/redis-sentinel.md

https://blog.csdn.net/weixin_40663800/article/details/90316507

老司机带你玩转面试(4):Redis 高可用之哨兵模式的更多相关文章

  1. 老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩、击穿、穿透

    前文回顾 建议前一篇文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 过期策略 Redis 的过期策略都有哪些? 在聊这个问题之前,一定 ...

  2. 老司机带你玩转面试(3):Redis 高可用之主从模式

    前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...

  3. 老司机带你玩转面试(5):Redis 集群模式 Redis Cluster

    前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...

  4. 老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化

    引言 今天周末,我在家坐着掐指一算,马上又要到一年一度的金九银十招聘季了,国内今年上半年受到 YQ 冲击,金三银四泡汤了,这就直接导致很多今年毕业的同学会和明年毕业的同学一起参加今年下半年的秋招,这个 ...

  5. 编程老司机带你玩转 CompletableFuture 异步编程

    本文从实例出发,介绍 CompletableFuture 基本用法.不过讲的再多,不如亲自上手练习一下.所以建议各位小伙伴看完,上机练习一把,快速掌握 CompletableFuture. 个人博文地 ...

  6. 老司机带你玩转web service

    当大型需求被数个公司分割开来,各公司系统相互交换数据的问题就会接踵而来.毕竟是多家不同的公司的产品,研发开发语言.采用技术框架基本上是百花齐放.怎样让自家系统提供的服务具有跨平台.跨语言.跨各种防火墙 ...

  7. 老司机带你玩Spring.Net -入门篇

    网上有 Spring.Net 的相关的很多介绍的文章还有实践例子,推荐个还不错的博客 Spring.Net 学习笔记 .以前对 Spring.Net 算是有过一面之缘,但却迟迟未真正相识.在网上有太多 ...

  8. 老司机带你走进Core Animation

    为什么时隔这么久我又回来了呢? 回来圈粉. 开玩笑的,前段时间ipv6被拒啊,超级悲剧的,前后弄了好久,然后需求啊什么的又超多,所以写好的东西也没有时间整理.不过既然我现在回来了,那么这将是一个井喷的 ...

  9. 老司机带你开飞机 一: mssql on linux 安装指导

    通常在本机开发环境中需要搭建所有的服务,还要修改本地的hosts,实在是不胜其烦.如今有了docker,完全不用污染本地环境,且看老司机带你搭建一个asp.net core的开发环境集群.愿你走出虚拟 ...

随机推荐

  1. Java8新特性之函数式接口

    <Java 8 实战>学习笔记系列 定义 函数式接口只定义一个抽象方法,可以有多个默认方法 函数式接口的接口名上,会被@FunctionalInterface标注 作用 函数式接口的方法可 ...

  2. 基于web网站项目的性能测试结果分析

    业务背景: 最近公司研发了一款对并发要求比较高的web项目,需要对其压力测试,模拟线上可能存在的问题,这个过程中遇到一些很多问题,这里重新梳理一下思路,希望能给遇到同样问题的小伙伴提供一个参考. 工具 ...

  3. selenium自动化操作

    在前面爬虫的相关介绍中,我们介绍了如何抓取静态页面信息.但是,在实际的网页浏览过程中,我们可能会经常碰到各种需要进行交互的操作,典型的如输入信息.点击按钮之类. 对于这种场景,之前的静态页面操作方式已 ...

  4. Charles的介绍,配置与使用

    简介 Charles中文名叫青花瓷 它是一款基于HTTP协议的代理服务器 通过成为客户端或者浏览器的代理 然后截取请求和请求结果达到分析抓包的目的. 特点 跨平台 win linux mac 半免费 ...

  5. python的常用魔法方法详细总结

    构造和初始化 __init__我们很熟悉了,它在对象初始化的时候调用,我们一般将它理解为"构造函数". 实际上, 当我们调用x = SomeClass()的时候调用,__init_ ...

  6. ThinkPHP 5接阿里云短信接口

    1.首先将api_sdk文件放入vendor文件夹下 2.在config文件中作相应的配置 3.封装发送短信的方法 4.调用发送短信方法

  7. 设计模式系列之代理模式(Proxy Pattern)——对象的间接访问

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  8. python用pandas遍历csv文件

    import pandas as pd df = pd.read_csv('a.csv') for index, row in df.iterrows(): x, y = row['X'], row[ ...

  9. python字典套字典

    定义字典 familyinfo = { "family name":"Python", "family structure":[ {&quo ...

  10. python+opencv实现图像缩放

    x, y = img_.shape[0:2] img_ = cv2.resize(img_, (int(y/2), int(x/2))) 实现图像长宽缩小为原来的一半