一、为什么要使用Redis集群
- 保证Redis缓存的可用性
- 分散Redis存储的压力
二、实现原理
1.1 基本概念:Redis Cluster集群是将所有数据通过hash算法映射到0-16383slot之间,集群中每一个节点存储部分slot;从而实现降低每一个台Redis实例存储压力的目的;
1.2 拓扑结构:下面我们3台master和6台slave举例,大致的拓扑结构如下图:

如上图所示,集群中共有9个节点其中3个master节点,每一个master有3个slave节点;数据的读写都走master节点,slave节点从master节点同步数据;客户端和可以连接集群中人一个master节点;
1.3 分片种类
根据分片操作是由谁进行的可以将其实现方式分为3类
-
1.3.1 由服务端进行分片
客户端随意与集群中的任何节点通信,服务器端负责计算某个key在哪个机器上,再根据具体情况进行数据读取;具体流程如下图:
数据读写.png
- 客户端向集群中任意节点发送读写命令
- 节点计算key对应的slot
-
- 根据slot判断数据在本节点上
- 是,则返回数据
- 否,返回moved消息,并告知数据在哪个节点上
- 根据返回的消息到对应的节点取数据,并返回给客户端
-
1.3.2 由客户端进行分片
提前分配好集群里面各个节点对应的slot,然后由客户端自己计算数据的key应该在哪个机器上存储和查找;
数据读写过程.png
-
1.3.3 由中间代理实现分片
此方式是借助一个代理服务器实现数据分片,客户端直接与proxy联系,proxy计算集群节点信息,并把请求发送到对应的集群节点;
下面是三种方式的优缺点
方式 | 优点 | 缺点 |
---|---|---|
服务端分片 | 1.扩展方便;对客户端而言操作整个集群像是操作一台机器 | 1.数据读写可能需要连接两次服务器 |
客户端分片 | 1.降低了服务器集群的复杂度,客户端实现数据分片时,服务器是独立的,服务器之前没有任何关联 | 1.服务端的redis集群拓扑结构发生变化时,所有的客户端都需要重新调整更新 2.客户端需要提前知晓服务端的相关信息 3连接不能共享,让应用规模增大时,资源浪费制约优化 |
中间代理分片 | 低了客户端和服务端的复杂度 | 需要proxy收集集群节点信息 |
1.4 高可用保障
和Redis的Sentinel机制相似,主要通过以下流程保证服务的高可用
- 1)故障发现
- redis cluster集群中的master通过两两相互发送PING PONG报文的方式来确认对方是否存活,一定时间范围内没有收到对方返回的报文消息便将这台master标记为PFAIL;
- 2)故障确认
- 有可能集群中某一个节点没有收到对方的报文回应是因为网络出现的两者连接的网络出现问题,并不是该节点真的down掉;此时就需要我们进行故障确认;当集群中超过一定数量(一般为半数)的master节点认为某一个节点PFAIL时便认为该节点置为FAIL。
- 3)slave选举
- 当集群中的某一个master节点被确认为FAIL时,便需要在它的salve节点中选举出来一个新的slave节点充当master节点;一般而言优先级最高的slave节点成为新的master可能性越大,数据越的节点成为新master节点的可能性越大
- 4)集群结构变更
当slave 收到超过一半的master同意时,会成为新的 master。 通过PONG 消息广播自己成为master,让Cluster 的其他节点尽快的更新拓扑结构
1.5 其他特性
-
- redis cluster的读写分离
- 一般而言,redis的读写都只在master节点进行,但为了提高redis集群的性能,可以允许客户端在slave节点进行读操作。
-
- 单点故障
- 如集群拓扑图所示,当redis1的没有slave节点而其他节点仍然有多个slave节点时,cluster会从其他master的slave节点中选一个slave作为redis1的salve
网友评论