redis的高可用实现方案:哨兵与集群(代码片段)

流楚丶格念 流楚丶格念     2022-12-01     436

关键词:

文章目录

高可用

什么是高可用?

高可用 这个词一般出现于分布式系统,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)

  • 假设系统一直能够提供服务,我们说系统的可用性是100%。
  • 如果系统每运行100个时间单位,会有1个时间单位无法提供服务,我们说系统的可用性是99%。
  • 很多公司的高可用目标是4个9,也就是99.99%,这就意味着,系统在一年中,停机时间总共为 8.76个小时。

那么如何实现高可用?

在《大型网站技术架构 – 核心原理与案例分析》一书指出:

在数据层高可用

  • 需要有数据备份机制与故障转移机制

  • 缓存服务是否需要高可用,两种观点:

    ① 缓存服务不可用会让数据库失去保护,因此需要保证缓存服务高可用

    ② 缓存服务不是数据存储服务,缓存宕机应当通过其他手段解决,如扩大缓存规模,一个缓存服务器的宕机只会影响局部

在Redis中正好对应了:数据持久化、集群、哨兵的高可用方案,持久化之前介绍过了,下面我们来看一下哨兵与集群吧:

Redis中的高可用

在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供正常服务(如主从分离、快速容灾技术),还需要考虑数据容量的扩展、数据安全不会丢失等。

在Redis中,实现高可用的技术主要包括持久化、主从复制、哨兵和Cluster集群,下面分别说明它们的作用,以及解决了什么样的问题。

  • 持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。

  • 主从复制:主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。缺陷:故障恢复无法自动化:写操作无法负载均衡:存储能力受到单机的限制。

  • 哨兵:在主从复制的基础上,哨兵实现了自动化的故障恢复。缺陷:写操作无法负载均衡;存储能力受到单机的限制。

  • 集群:通过集群,Redis解决了写操作无负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。

实现方案

实现Redis的高可用,主要有哨兵和集群两种方式:

哨兵:

概念:

Redis Sentinel(哨兵)是一个分布式架构,它包含若干个哨兵节点(sentinel)和数据节点(master、slave)。每个哨兵节点会对数据节点和其余的哨兵节点进行监控,当发现节点不可达时,会对节点做下线标识。

如果被标识的是主节点,它就会与其他的哨兵节点进行协商,当多数哨兵节点都认为主节点不可达时,它们便会选举出一个哨兵节点来完成自动故障转移的工作,同时还会将这个变化实时地通知给应用方。

注意:整个过程是自动的,不需要人工介入,这样有效地解决了Redis的高可用问题!

一组哨兵可以监控一个主节点,也可以同时监控多个主节点,两种情况的拓扑结构如下图:

哨兵节点的特性

哨兵节点包含如下的特征:

  1. 哨兵节点会定期监控数据节点,其他哨兵节点是否可达;
  2. 哨兵节点会将故障转移的结果通知给应用方;
  3. 哨兵节点可以将从节点晋升为主节点,并维护后续正确的主从关系;
  4. 哨兵模式下,客户端连接的是哨兵节点集合,从中获取主节点信息;
  5. 节点的故障判断是由多个哨兵节点共同完成的,可有效地防止误判;
  6. 哨兵节点集合是由多个哨兵节点组成的,即使个别哨兵节点不可用,整个集合依然是健壮的;
  7. 哨兵节点也是独立的Redis节点,是特殊的Redis节点,它们不存储数据,只支持部分命令。

工作原理:超半数选举

哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols) 来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。

每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方宕机了,这就是所谓的”主观认为宕机” (Subjective Down,简称sdown)。若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master真正宕机,即“客观上认为宕机”(Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为 master,然后自动修改相关配置

工作原理:Redis主从复制

主从复制概念

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(Master),后者称为从节点(Slave);数据的复制是单向的,只能由主节点到从节点。

默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

主从复制的作用

  • 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
  • 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
  • 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
  • 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

主从复制流程:

(1)若启动一个slave机器进程,则它会向Master机器发送一个“sync command”命令,请求同步连接。
(2)无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照保存到数据文件中(执行rdb操作),同时Master还会记录修改数据的所有命令并缓存在数据文件中。
(3)后台进程完成缓存操作之后,Master机器就会向slave机器发送数据文件,slave端机器将数据文件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给Slave端机器。若Slave出现故障导致宕机,则恢复正常后会自动重新连接。
(4)Master机器收到slave端机器的连接后,将其完整的数据文件发送给slave端机器,如果Mater同时收到多个slave发来的同步请求,则Master会在后台启动一个进程以保存数据文件,然后将其发送给所有的slave端机器,确保所有的slave端机器都正常。

流程图如下:

集群:

概念:

Redis集群是一个提供在多个Redis节点之间共享数据的程序集。它并不像Redis主从复制模式那样只提供一个master节点提供写服务,而是会提供多个master节点提供写服务,每个master节点中存储的数据都不一样,这些数据通过数据分片的方式被自动分割到不同的master节点上。

为了保证集群的高可用,每个master节点下面还需要添加至少1个slave节点,这样当某个master节点发生故障后,可以从它的slave节点中选举一个作为新的master节点继续提供服务。不过当某个master节点和它下面所有的slave节点都发生故障时,整个集群就不可用了。

这样就组成了下图中的结构模式:

数据存储原理:

Redis集群采用虚拟槽分区来实现数据分片,它把所有的键根据哈希函数映射到 0-16383 整数槽内,计算公式为 slot=CRC16(key)&16383 ,每一个节点负责维护一部分槽以及槽所映射的键值数据。

虚拟槽分区具有如下特点:

  1. 解耦数据和节点之间的关系,简化了节点扩容和收缩的难度;
  2. 节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据;
  3. 支持节点、槽、键之间的映射查询,用于数据路由,在线伸缩等场景。

Redis集群中数据的分片逻辑如下图:

就比如R说下面例子:

Redis集群有16384个哈希槽,进行set操作时,每个key会通过CRC16校验后再对16384取模来决定放置在哪个槽,搭建Redis集群时会先给集群中每个master节点分配一部分哈希槽。比如当前集群有3个master节点,master1节点包含0~5500号哈希槽,master2节点包含5501~11000号哈希槽,master3节点包含11001~16384号哈希槽,当我们执行“set key value”时,假如 CRC16(key) % 16384 = 777,那么这个key就会被分配到master1节点上,如下图:

Redis Cluster是Redis的分布式解决方案,在3.0版本正式推出,有效地解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用Cluster架构方案达到负载均衡的目的。

集群的功能限制:

Redis集群方案在扩展了Redis处理能力的同时,也带来了一些使用上的限制:

  1. key批量操作支持有限。如mset、mget,目前只支持具有相同slot值的key执行批量操作。对于映射为不同slot值的key由于执行mset、mget等操作可能存在于多个节点上所以不被支持。
  2. key事务操作支持有限。同理只支持多key在同一节点上的事务操作,当多个key分布在不同的节点上时无法使用事务功能。
  3. key作为数据分区的最小粒度,因此不能将一个大的键值对象(如hash、list等)映射到不同的节点
  4. 不支持多数据库空间。单机下的Redis可以支持16个数据库,集群模式下只能使用一个数据库空间,即DB0
  5. 复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复制结构

集群的通信原理:

在分布式存储中需要提供维护节点元数据信息的机制,所谓元数据是指:节点负责哪些数据,是否出现故障等状态信息。常见的元数据维护方式分为:集中式和P2P方式。

Redis集群采用P2P的Gossip(流言)协议Gossip协议的工作原理就是节点彼此不断通信交换信息,一段时间后所有的节点都会知道集群完整的信息,这种方式类似流言传播。通信的大致过程如下:

  1. 集群中每个节点都会单独开辟一个TCP通道,用于节点之间彼此通信,通信端口号在基础端口号上加10000;
  2. 每个节点再固定周期内通过特定规则选择几个节点发送ping消息;
  3. 接收ping消息的节点用pong消息作为响应。

Gossip 可视化操作可以看这个网站的演示:https://flopezluis.github.io/gossip-simulator/

补充:Gossip 协议

与 Paxos 和 Raft 目标是强一致性不同,Gossip 达到的是最终一致性

官方介绍:A gossip protocol is a procedure or process of computer peer-to-peer communication that is based on the way epidemics spread.
翻译:Gossip 协议是基于流行病传播方式的计算机对等通信的过程或过程

它可以快速地将信息散播给集群中每个成员,散播速度为 𝑙 𝑜 𝑔 𝑓 ( 𝑁 ) 𝑙𝑜𝑔_𝑓 (𝑁) logf(N) ,其中 f 术语称为 fanout,代表每次随机传播的成员数,而 N 代表总共成员数。例如:

  • 𝑙 𝑜 𝑔 4 ( 40 ) ≈ 2.66 𝑙𝑜𝑔_4 (40)≈2.66 log4(40)2.66 ,也就是大约三轮传播,就可以让集群达到一致
  • 实际传播次数可能会高于此结果,因为随机时会随到一些重复的成员

Gossip 协议工作流程示例

  1. 例如,图中红色节点有其它节点不知道的信息,它的传播方式如下

  1. 在红色节点能连通的节点中随机挑选 fanout 个(粗线所示)

  1. 把信息传播给它们(感染)

  1. 在这些已被【感染】的节点中,重复 2. 3. 两步,直至全部感染,即达到最终一致性

Gossip 协议优点

  • 扩展性高,传播次数不会受集群成员增长而增长过快
    • 例如: 𝑙 𝑜 𝑔 4 ( 80 ) ≈ 3.16 𝑙𝑜𝑔_4 (80)≈3.16 log4(80)3.16 ,集群实际成员翻了一倍,但传播次数几乎不变
  • 容错性好,即使某些节点间发生了故障无法通信,也不会影响最终的一致性
    • 例如:A 与 B 之间发生故障无法通信,但只要 A 与其他能连通 B 的节点通信,那么信息就一定会散播到 B
  • Robust(鲁棒性),即皮实,集群中的节点是对等的,即便一些节点挂了,一些节点新添加进来,也不会影响其它节点的信息传播

Gossip协议消息分类

其中,Gossip协议的主要职责就是信息交换,而信息交换的载体就是节点彼此发送的Gossip消息,Gossip消息分为:meet消息、ping消息、pong消息、fail消息等。

  • meet消息:用于通知新节点加入,消息发送者通知接受者加入到当前集群。meet消息通信正常完成后,接收节点会加入到集群中并进行周期性的ping、pong消息交换。
  • ping消息:集群内交换最频繁的消息,集群内每个节点每秒向多个其他节点发送ping消息,用于检测节点是否在线和交换彼此状态信息。ping消息封装了自身节点和一部分其他节点的状态数据。
  • pong消息:当接收到meet、ping消息时,作为响应消息回复给发送方确认消息正常通信。pong消息内封装了自身状态数据,节点也可以向集群内广播自身的pong消息来通知整个集群对自身状态进行更新。
  • fail消息:当节点判定集群内另一个节点下线时,会向集群内广播一个fail消息,其他节点接收到fail消息之后把对应节点更新为下线状态。

虽然Gossip协议的信息交换机制具有天然的分布式特性,但它是有成本的。因为Redis集群内部需要频繁地进行节点信息交换,而ping/pong消息会携带当前节点和部分其他节点的状态数据,势必会加重带宽和计算的负担。所以,Redis集群的Gossip协议需要兼顾信息交换的实时性和成本的开销。

  • 集群里的每个节点默认每隔一秒钟就会从已知节点列表中随机选出五个节点,然后对这五个节点中最长时间没有发送过PING消息的节点发送PING消息,以此来检测被选中的节点是否在线。

  • 如果节点A最后一次收到节点B发送的PONG消息的时间,距离当前时间已经超过了节点A的超时选项设置时长的一半(cluster-node-timeout/2),那么节点A也会向节点B发送PING消息,这可以防止节点A因为长时间没有随机选中节点B作为PING消息的发送对象而导致对节点B的信息更新滞后。

  • 每个消息主要的数据占用:slots槽数组(2KB)和整个集群1/10的状态数据(10个节点状态数据约1KB)

redis集群-哨兵模式原理(sentinel)(代码片段)

...&故障转移1.哨兵模式(Sentinel)哨兵模式是Redis的高可用性解决方案:由一个或多个Se 查看详情

redis集群-哨兵模式原理(sentinel)(代码片段)

...&故障转移1.哨兵模式(Sentinel)哨兵模式是Redis的高可用性解决方案:由一个或多个Se 查看详情

redis进阶-高可用:集群(代码片段)

...载均衡。Redis集群解决了上述问题,实现了较为完善的高可用方案。本文将详细介绍集群,主要内容包括:集群的作用; 查看详情

redis高可用方案:sentinel(哨兵模式)和集群(代码片段)

...了sentinel哨兵模式。哨兵模式简介:sentinel是官方提供的高可用方案,其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。同时sentinel是一个分布式系统,可以在一个架构中运行多... 查看详情

redis数据库主从哨兵群集(代码片段)

...括持久化、主从复制、哨兵和集群持久化持久化是最简单的高可用方法(有些时候会不被归为高可用措施)主要作用是数据备份,也就是将数据存储在硬盘,保证数据不会因进程退出而丢失主从复制主从复制是高... 查看详情

sentinel哨兵实现高可用(代码片段)

...溃了,势必造成影响。而redis为我们提供了Sentinel来做redis的高可用工具,因此个人觉得实际上redis并不需要像Nginx那样,与keepalived组合成高可用,或者进 查看详情

高可用集群架构——redis的主从复制与哨兵模式,cluster(代码片段)

redis的集群一、redis的集群模式1、三种模式2、redis集群与哈希槽二、Redis主从复制概述1、Redis主从复制概述2、主从复制流程三、哨兵模式1、简单介绍2、哨兵的工作原理5、哨兵模式下的故障迁移四、Cluster群集redis-Cluster的故障转... 查看详情

深入学习redis:集群(代码片段)

...载均衡。Redis集群解决了上述问题,实现了较为完善的高可用方案。本文将详细介绍集群,主要内容包括:集群的作用; 查看详情

redis的高可用详解:redis哨兵复制集群的设计原理,以及区别

谈到Redis服务器的高可用,如何保证备份的机器是原始服务器的完整备份呢?这时候就需要哨兵和复制。 哨兵(Sentinel):可以管理多个Redis服务器,它提供了监控,提醒以及自动的故障转移的功能。 复制(Replication):则是负... 查看详情

rediscluster初探之部署(代码片段)

一、简介在3.0版本之前,redis通过哨兵实现主从的高可用,在3.0版本之后,redis官方推出了高可用的redis集群解决方案。重点知识:数据分区分布式数据库是将数据根据分区规则划分到多个节点上,每个节点负责存储一部分数据;... 查看详情

redis高可用之哨兵机制实现细节(代码片段)

...一篇的文章《Redis高可用全景一览》中,我们学习了Redis的高可用性。高可用性有两方面含义:一是服务少中断,二是数据少丢失。主从库模式和哨兵保证了服务少中断,AOF日志和RDB快照保证了数据少丢失。并且我们学习了哨兵... 查看详情

如何保证redis高可用和高并发(主从+哨兵+集群)(代码片段)

...;但同样复杂度也相比单实例高出很多。那么如何保证Redis的高并发和高可用?Redis主要有三种集群方式用来保证高并发和高可用:主从复制,哨兵模式和集群。2.主从复制在分布式系 查看详情

redis_12_redis集群实现sentinel哨兵应对高可用(代码片段)

文章目录一、前言二、Sentinel原理2.1Sentinel原理2.2Sentinel选主2.3Sentinel哨兵的四个功能2.4最简单是Redis哨兵主从结构至少需要三个机器三、Sentinel实践3.1Sentinel配置3.2实践:Sentinel基本使用3.2.1实践:Sentinel搭建3.2.2实践:... 查看详情

大厂二面高可用之redis哨兵策略(代码片段)

前言笔者在二面某知名大厂时,从Redis的高可用问到kafka的高可用、MySQL的高可用,又让我阐述从高可用的角度设计自己应用程序的高可用,自己回答得不够好,特别是自己项目在QPS陡增时如何设计系统,快速... 查看详情

深入学习redis:集群(代码片段)

...载均衡。Redis集群解决了上述问题,实现了较为完善的高可用方案。本文将详细介绍集群,主要内容包括:集群的作用;集群的搭建方法及设计方案;集群的基本原理;客户端访问集群的方法;以及其... 查看详情

redis_09_redis集群实现sentinel哨兵应对高可用(代码片段)

...3.2.2实践:主节点宕机之后的选主过程(Sentinel保证高可用)3.2.3实践:新节点加入之后 查看详情

redis高可用方案主从及哨兵(代码片段)

Redis集群——主从复制以及哨兵模式##主从复制的定义Redis的主从复制表示将Redis的服务器分为主服务器(Master)以及多个从服务器(Slaves),其目的是减少主服务器的读取数据的压力。一个Master可以有多个该服... 查看详情

redis集群介绍与搭建(主从哨兵cluster集群)!(代码片段)

redis集群一.Redis集群1.简介2.Redis集群的优势3.Redis集群的实现方法二.Redis三种模式原理介绍1.主从模式2.哨兵模式(Sentinel)(1)哨兵模式集群架构(2)哨兵模式主要功能(3)哨兵们监控整个系统节点的过程... 查看详情