我们说一下如何构建一个生产系统可用的Redis缓存集群+

Redis本身支持集群,即为Redis Cluser,Redis Cluster相比较于单节点的Redis,可以保存更多的数据,更大的并发,做到了高可用,在单个节点故障的情况下,继续提供服务

Redis Cluster如何进行的集群分布的呢?本质上也是通过分片的方式,将集群分布到多个节点上,Redis Cluster如何分片的?引入了一个槽的概念,本质上就是哈希槽,利用hash来计算分散在哪个槽上,槽的数量也是固定的16384 (16*1024)个

计算的方式为

HASH_SLOT = CRC16(key) mod 16384

先计算出CRC值,然后取模于16384,得到具体的槽

槽的位置是利用集群中每个Reids各自去保存的,集群初始化的时候,Redis自动分配16384个槽,然后当用户去请求一个key的时候,Redis先计算出Key对应的槽,然后找到槽在哪个节点上,然后重定向到这个节点上

解决了分片问题,在进行水平扩容的时候,往集群中增加节点,需要给其分配一些槽,可以进行手动的分配也可以利用官方提供的redis-trib-rb脚本来重新分槽

分片可以解决Redis的海量问题,但是在高可用方面,Reids需要进行解决对应的高可用问题

我们可以增加从节点,做主从复制,Redis Cluster支持给每个分片增加多个从节点,从节点刚刚连接到主节点的时候,会先给主节点发送一个SYNC的命令,请求一次全量的复制,然后之后主节点就会将更新的命令同步传给从节点,主节点故障,会导致从节点中选出一个节点作为主节点继续提供服务.集群其他的节点会了解到新节点的地址

然后是高并发相关,需要读写分离,对于这个问题,理论上Redis也支持读写分离

图片

但是其并不适合于大规模集群

Redis Cluster适合于中小规模的Redis集群,但是不适合大规模集群,毕竟Redis的每个节点上保存了所有槽和节点的映射关系表,客户端可以访问任意一个节点,然后通过重定向的命令,找到数据所在的节点,这种去中心化的保存方式非常不适合于集群变化时候消息的变更

那么,如何使用Redis进行构建大规模的集群呢?

一般的厂子里,每家的解决是不同的,但总体都是大同小异的

我们可以再Redis和客户端之间,增加一层代理服务,代理服务有三个作用

第一个作用,负责在客户端和Redis之间进行响应和转发,客户端和代理服务打交道,代理收到客户端的请求之后,转发到对应的Redis,节点返回的相应经过代理返回客户端

第二就是监控集群中所有Reids的节点状态,如果发现有问题节点,我们及时进行主从切换

然后就是维护集群的元数据,这个元数据就是集群所有节点的主从信息,以及槽和节点关系的映射表

整体架构基本如下

图片

开源的Redis集群方案twemproxy和Codis就是这种架构

这个结构的有点就是对客户端透明,从客户端的视角看,整个集群和超大容量的单节点redis是一致的,并且分片算法是代理服务控制的,扩容更加方便,新节点加入后,直接修改代理服务的元数据

当然,这增加了一层代理转发,带来了新的性能消耗

图片

或者将代理服务的功能前移到客户端去,客户端发起请求之前,先查询元数据,获取集群信息

这个元数据虽然是一个单点,但是数据量并不大,访问量并不大,客户端还可以进行缓存元数据

但这个架构比较复杂,需要专门的定制化Redis客户端,只有规模较大的企业做得好些

我们说了三个Redis集群的部署方式

小规模的集群建议使用Redis Cluster,节点数量不多的时候,各方面都不错

大一些的可以考虑代理的集群架构

还有些定制客户端的方式,性能更好

发表评论

邮箱地址不会被公开。 必填项已用*标注