Redis教程

redis常用集群方案汇总

本文主要是介绍redis常用集群方案汇总,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

在生产环境下,往往要求系统具备高可用,承载高并发以及有着较好的抵御单点故障的能力,通常来说,使用集群部署可以达到这个目的

同样,对于redis的使用,即便单节点的性能已经很高了,但考虑到种种可能造成单点故障以及影响其高并发环境下整体性能的因素,因此,在系统设计之初,最好能结合自身的业务对redis的部署架构做一个整体的评估。

是否使用集群

关于这个问题,很多同学有不同的见解,比如说项目本身体量不大,在可遇见的业务增长范围内,为了满足快速迭代、快速上线的要求,单节点不是不可以,部署redis单节点,不管从开发、部署、测试还是运维,成本上面考虑,都是最低的,而且就算一段时间之后出现了性能瓶颈,也比较好预测从而通过增加服务器内存等方式提升redis性能

还是那句话,架构的设计是无止境的,这个取决于系统设计之初,项目缔造者对于系统后续整体的考虑,以及在平衡成本之间的抉择

但放在今天这个服务器资源并不是那么昂贵,而且对于系统的用户体验要求越来越高的情况下,建议还是不要为了节省那么一点成本,而做出技术上的妥协了,这个会给后期的维护带来诸多意想不到的麻烦

redis的集群模式汇总

在这里插入图片描述

在具体聊到某种集群模式之前,我们先看下上面的这张图,redis单机模式下,可能存在多个客户端同时对redis服务器进行读写的操作,即读写操作都是针对同一个redis节点的操作,redis所在的机器的性能决定了其最大的吞吐量

1、读写分离模式(主从复制)

抛开单点故障不说,单节点模式下,很明显的一个问题就是,单节点将成为性能的瓶颈,尽管redis单机可以提供较高的性能,甚至官方给出的压测报告也很优秀,但生产环境下,不可预知的因素仍旧会成为并发的瓶颈

换个说法,如果还有其他的redis服务器可以替主节点分担一些读请求的压力,这样情况就能改善不少了,尤其是大多数读多写少的情况下,使用读写分离的模式就体现出它的优势了

在这里插入图片描述

谈主从模式,我们需要基本掌握主从模式底层数据同步(复制)的大致流程,可以总结如下几点:

  • 集群启动之后,如果是初次启动,master与其他的多个slave节点之间将会开启全量同步,具体来说,master将会通过RDB日志文件,将日志中的数据同步给各个从节点,首次同步,耗时较长,执行全量同步
  • 而后,各个从节点保持与master的心跳,接收master的命令完成数据同步
  • 主从复制的过程是非阻塞的,即从服务器在进行主从同步数据过程中,master仍然可以处理外界的请求
  • 主从复制的过程是非阻塞的,即从服务器在进行主从同步数据过程中,从redis仍然可以处理外界的请求,只不过在未完成同步之前,外界请求的数据还是老数据

复制集群优缺点

优点

  1. 搭建较为简单,当读取成为系统的瓶颈时,扩展从节点也比较容易
  2. 一旦master出现故障,可以通过手动的方式,快速切换某个从节点为master
  3. 从redis2.8之后,从节点采用异步复制,性能较好

缺点:

  1. 仍未解决master的单点写故障,一旦master挂掉,这种模式下,需要手动切换,在这个期间,系统对于redis的写操作将不可用
  2. 当主从之间的网络出现故障或不稳定时,主从之间的数据同步将会耗费较长时间,影响客户端数据读取
  3. 对机器的整体消费较大,一旦集群开始正常运转之后,由于从节点是全量保存master数据的备份,因此当master的数据占据空间越来越大时,从节点的空间消耗也随之增大
  4. 从节点可能存在脏数据,由于从节点一般情况下只是为了读取,但是不会主动删除数据,除非在同步master数据时接收到主节点的删除命令,在这种情况下,假如从节点配置了可写,将会产生一些脏数据,从而和master的数据不一致

2、哨兵模式

在这里插入图片描述

上面是一副redis哨兵模式下的架构示意图,关于烧饼模式的搭建,在个人的一篇文章中有详细的说明,有兴趣的同学可以自己尝试搭建一下:redis哨兵模式搭建

哨兵模式解决的问题

在主从模式下,在最后的优缺点总结时,谈到这种模式有一个很重要的缺点就是无法解决主从节点在故障下的自动切换问题,也就是故障自动转移,这个对于那些高并发系统的环境,这种问题是很要紧的,就算是人工恢复,也需要一段时间,从而导致期间无法写入redis的master数据

哨兵集群特点

哨兵模式下,从理解上来说,集群分为2部分,第一部分是 Sentinel集群(监控集群),这个集群存在的目的是为了监控 redis的数据集群的健康状况,实时从redis的数据集群获取最新的信息,一旦监控到数据集群中的master节点出现故障,内部发起投票选举,让其他的slave节点顶上来

而第二部分的集群,就是一个正常的主从模式集群,这个内部的原理和主从模式基本相同,仍旧是一主多从,master负责读写,从节点同步master数据并能提供外部的读请求,分担master的一部分读请求压力

总结起来,哨兵集群大概如下几点:

  • 监控 ,监控主从节点是否运转正常
  • 提醒 ,当监控到主从节点出现问题,可以配置邮件或通知及时告知运维人员
  • 自动故障转移,当master出现故障,sentinel通过投票选取新的master
  • 配置提供者 , 客户端连接集群时,不需要直连redis集群,而是直接连接sentinel即可

sentinel集群工作原理

了解哨兵模式的工作原理,有助于更好的理解这种模式的架构设计的精妙之处,了解其工作原理之前,有几个概念需要简单了解下:

定时任务

Sentinel内部有3个定时任务
每一秒每个Sentinel对其他的Sentinel节点和Redis节点执行ping命令,即心跳检查
每2秒每个Sentinel通过Master节点channel交换信息,实时感知redis数据节点的信息
每10秒每个Sentinel会对Master和Slave执行Info命令,通过info命令可以拿到节点相信的信息

主观下线

主观下线,指的是单个Sentinel实例对redis服务器做出的下线判断,即单个Sentinel认为某个服务器下线(可能是接收不到订阅,或者网络出现临时闪断等因素)

客观下线

客观下线,指的是多个Sentinel实例在对同一个redis服务器做出主观下线判断,并且通过命令互相交流感知之后,共同得出的对redis服务下线的判断,然后开启failover

仲裁

即搭建Sentinel集群时,配置文件中配置多少个Sentinel节点认为redis服务挂掉时需要进行failover的个数

总结来说,Sentinel的工作原理如下:

  1. 每秒进行PING(期待redis集群能正常响应PANG)
  2. 有效回复PANG命令的时间超过了配置文件中的配置的最大响应时间,认为主观下线
  3. 再次确认主观下线状态(其他的Sentinel节点也做上述操作)
  4. 满足仲裁的条件,即Sentinel集群中一半以上的节点认为主观下线,认定为客观下线
  5. Sentinel重新投票选取主节点,从节点复制数据
  6. 当主节点被标记为客观下线后,INFO命令将由10秒触发一次改为1秒一次
  7. 若没有足够数量的Sentinel同意Master下线,Master的客观下线状态将会被移除

sentinel集群优缺点

优点:

  1. 降低了误报的可能性,多个sentinel节点组成集群后,任意一个sentinel节点挂掉后,其他的节点仍然可以对外(客户端连接sentinel)提供服务,从而降低了对客户端的影响
  2. 可以更快的实现主从的切换,使得系统更加健壮,从而提升了系统的高可用性
  3. Sentinel会不断监测主从服务器是否运转正常,当Master节点的redis服务出现故障时,可以通过配置及时向管理员或者运维人员发送通知消息

缺点:

  1. 主从切换之间,由于Sentinel内部需要重新发起选举,在这个期间可能会出现短暂的master不可写入的问题,造成部分数据丢失
  2. 仍未解决主节点单点写的压力
  3. 主节点写的能力,存储能力受到单机限制
  4. 冬天扩容较为复杂,与i与集群来说,容量达到上限时,在线扩容比较复杂

3、cluster模式

在这里插入图片描述

上面两种模式,主从模式可以解决在一定程度上系统对于并发的问题,通过分担master的读请求压力,将部分压力转给从节点;而哨兵模式更进一步,一旦master出现问题,可以快速实现故障转移和master的重新选举

但这两种模式下,仍然有一个问题没有解决,就是master的写压力,要知道,整个系统的写入瓶颈点在master,另一个问题就是数据存储受到master单机的影响,即单机master服务器的最大的容量决定了系统可写入的最大数据量,因此这两种模式下都没有解决这2个问题

于是,redis的cluster模式(集群模式)就出现并解决这个问题,从上面的简易架构图,也可以看到,Redis Cluster集群模式具有高可用可扩展分布式容错等特性

为什么这么说呢?这个需要从Redis Cluster集群的原理说起

  • 分布式存储,请求的数据是分散存储在从 M1~M3的3个(或者更多个)节点上
  • 当监测或预估到当前master的节点数量不够时,可以动态扩展master数量
  • 从M1~M3,每个节点均可以对外提供读写请求,即使某个master挂掉了,也不影响整体的对外提供服务
  • 由于每个master存在备份节点,备份节点是对master节点的全量数据备份,一旦master挂掉,可以立即顶上去加入master集群,对外提供读写服务
  • 写请求过来后,根据集群的分派算法,将请求的key路由到M1~M3中的具体的机器,然后提供数据返回

关于分区算法

在这里插入图片描述

在这里插入图片描述
Redis cluster模式之所以具备高可用性,和这种架构下数据存储有着很大的关系,上面用两张图描述了在集群模式下,数据的分配状况,简单总结如下:

  1. cluster模式下,会根据master的节点数量,对整个hash槽(实际存储key/value的数据逻辑抽象)进行分配
  2. 可认为M1~M3三个master节点共同组成一个环状节点分布图,集群初始化的时候,将整个hash槽16384个,根据一定的算法,分配给这3个master,这样算下来,每个节点可以分配到大约5000多个槽用于存放key/value,即每个节点存储一定范围的数据
  3. 新的请求过来,集群根据一定的算法,计算请求的key对应的槽所在的节点,节点获取key/value返回数据

在集群初始化对M1~M3节点进行数据分区(槽分配)时,就涉及到一个具体的分区算法,总结下来,大概有下面几种常用算法:

  • 范围分区
    直接指定各节点的槽的范围,那么请求针对同一范围内的范围查询不需要跨节点,节点不多的情况下,可以明显的提升查询速度

  • 节点取余分区
    hash(object)%N,这种算法实现简单,但是当需要进行数据节点扩容或者收缩节点时,需要迁移的数据量比较大(该算法容易造成一定范围内的数据倾斜)

  • 一致性hash分区
    相对于节点取余最大好处在于加入和删除节点时,只会影响到hash环中的相邻节点,对其他节点影响较小,但使用这种分区算法,当节点数量较少,节点变化将会大范围的影响hash环中的数据映射,因此不太适合少量数据节点的分布式方案

  • 虚拟槽分区
    根据槽的总数对节点进行范围分区后,每个节点存储着一定的槽的数据范围,类似于索引的方式,即每个node均匀分配了slot,减小了节点影响的范围,但这带来的问题是需要存储node和slot的对应信息,而Redis cluster集群模式就是采用了这种分配方式

在这里插入图片描述

有了上面的概念之后,我们知道Redis cluster最终是使用虚拟槽分区的算法,保存了各个master节点存储的槽位信息,每个master分配到了一定数量的槽位,后续的读取或写入请求过来之后,根据CRC算法定位到具体节点,具体槽位,然后返回数据

注意点:

  • 使用Redis cluster算法之后,不会再有redis的数据库的概念(默认16个库),而是槽位,即每个节点负责一部分槽位信息,槽位的信息存放在每个节点
  • Redis集群节点不要太大,否则在进行节点定位的时候会消耗较多时间

优缺点

优点:

  • 去中心化
  • 扩展性好
  • 高可用性
  • 自动故障转移

缺点:

  • 数据通过异步复制,无法保证数据的强一致性
  • 集群搭建略为复杂,后续的维护成本较高

通过以上内容,总结了目前使用redis集群的几种方式,可根据自身项目的实际情况合理选择,本篇到此结束,最后感谢观看!

这篇关于redis常用集群方案汇总的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!