在生产环境下,往往要求系统具备高可用,承载高并发以及有着较好的抵御单点故障的能力,通常来说,使用集群部署可以达到这个目的
同样,对于redis的使用,即便单节点的性能已经很高了,但考虑到种种可能造成单点故障以及影响其高并发环境下整体性能的因素,因此,在系统设计之初,最好能结合自身的业务对redis的部署架构做一个整体的评估。
关于这个问题,很多同学有不同的见解,比如说项目本身体量不大,在可遇见的业务增长范围内,为了满足快速迭代、快速上线的要求,单节点不是不可以,部署redis单节点,不管从开发、部署、测试还是运维,成本上面考虑,都是最低的,而且就算一段时间之后出现了性能瓶颈,也比较好预测从而通过增加服务器内存等方式提升redis性能
还是那句话,架构的设计是无止境的,这个取决于系统设计之初,项目缔造者对于系统后续整体的考虑,以及在平衡成本之间的抉择
但放在今天这个服务器资源并不是那么昂贵,而且对于系统的用户体验要求越来越高的情况下,建议还是不要为了节省那么一点成本,而做出技术上的妥协了,这个会给后期的维护带来诸多意想不到的麻烦
在具体聊到某种集群模式之前,我们先看下上面的这张图,redis单机模式下,可能存在多个客户端同时对redis服务器进行读写的操作,即读写操作都是针对同一个redis节点的操作,redis所在的机器的性能决定了其最大的吞吐量
抛开单点故障不说,单节点模式下,很明显的一个问题就是,单节点将成为性能的瓶颈,尽管redis单机可以提供较高的性能,甚至官方给出的压测报告也很优秀,但生产环境下,不可预知的因素仍旧会成为并发的瓶颈
换个说法,如果还有其他的redis服务器可以替主节点分担一些读请求的压力,这样情况就能改善不少了,尤其是大多数读多写少的情况下,使用读写分离的模式就体现出它的优势了
谈主从模式,我们需要基本掌握主从模式底层数据同步(复制)的大致流程,可以总结如下几点:
复制集群优缺点
优点
缺点:
上面是一副redis哨兵模式下的架构示意图,关于烧饼模式的搭建,在个人的一篇文章中有详细的说明,有兴趣的同学可以自己尝试搭建一下:redis哨兵模式搭建
哨兵模式解决的问题
在主从模式下,在最后的优缺点总结时,谈到这种模式有一个很重要的缺点就是无法解决主从节点在故障下的自动切换问题,也就是故障自动转移,这个对于那些高并发系统的环境,这种问题是很要紧的,就算是人工恢复,也需要一段时间,从而导致期间无法写入redis的master数据
哨兵集群特点
哨兵模式下,从理解上来说,集群分为2部分,第一部分是 Sentinel集群(监控集群),这个集群存在的目的是为了监控 redis的数据集群的健康状况,实时从redis的数据集群获取最新的信息,一旦监控到数据集群中的master节点出现故障,内部发起投票选举,让其他的slave节点顶上来
而第二部分的集群,就是一个正常的主从模式集群,这个内部的原理和主从模式基本相同,仍旧是一主多从,master负责读写,从节点同步master数据并能提供外部的读请求,分担master的一部分读请求压力
总结起来,哨兵集群大概如下几点:
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的工作原理如下:
sentinel集群优缺点
优点:
缺点:
上面两种模式,主从模式可以解决在一定程度上系统对于并发的问题,通过分担master的读请求压力,将部分压力转给从节点;而哨兵模式更进一步,一旦master出现问题,可以快速实现故障转移和master的重新选举
但这两种模式下,仍然有一个问题没有解决,就是master的写压力,要知道,整个系统的写入瓶颈点在master,另一个问题就是数据存储受到master单机的影响,即单机master服务器的最大的容量决定了系统可写入的最大数据量,因此这两种模式下都没有解决这2个问题
于是,redis的cluster模式(集群模式)就出现并解决这个问题,从上面的简易架构图,也可以看到,Redis Cluster集群模式具有高可用、可扩展、分布式和容错等特性
为什么这么说呢?这个需要从Redis Cluster集群的原理说起
关于分区算法
Redis cluster模式之所以具备高可用性,和这种架构下数据存储有着很大的关系,上面用两张图描述了在集群模式下,数据的分配状况,简单总结如下:
在集群初始化对M1~M3节点进行数据分区(槽分配)时,就涉及到一个具体的分区算法,总结下来,大概有下面几种常用算法:
范围分区
直接指定各节点的槽的范围,那么请求针对同一范围内的范围查询不需要跨节点,节点不多的情况下,可以明显的提升查询速度
节点取余分区
hash(object)%N,这种算法实现简单,但是当需要进行数据节点扩容或者收缩节点时,需要迁移的数据量比较大(该算法容易造成一定范围内的数据倾斜)
一致性hash分区
相对于节点取余最大好处在于加入和删除节点时,只会影响到hash环中的相邻节点,对其他节点影响较小,但使用这种分区算法,当节点数量较少,节点变化将会大范围的影响hash环中的数据映射,因此不太适合少量数据节点的分布式方案
虚拟槽分区
根据槽的总数对节点进行范围分区后,每个节点存储着一定的槽的数据范围,类似于索引的方式,即每个node均匀分配了slot,减小了节点影响的范围,但这带来的问题是需要存储node和slot的对应信息,而Redis cluster集群模式就是采用了这种分配方式
有了上面的概念之后,我们知道Redis cluster最终是使用虚拟槽分区的算法,保存了各个master节点存储的槽位信息,每个master分配到了一定数量的槽位,后续的读取或写入请求过来之后,根据CRC算法定位到具体节点,具体槽位,然后返回数据
注意点:
优缺点
优点:
缺点:
通过以上内容,总结了目前使用redis集群的几种方式,可根据自身项目的实际情况合理选择,本篇到此结束,最后感谢观看!