2024年最全碾压阿里面试官,RedisCluster集群全网最全知识点,首发Java程序员人手必备的进阶知识体系

最后

学习视频:

大厂面试真题:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

3.指派槽

4.主从

官方工具安装


1.配置开启节点

2. meet

3.指派槽

4.主从

配置开启Redis-1:

port ${port}

daemonize yes

dir “/opt/redis/redis/data/”

dbfilename “dump-${port}.rdb”

logfile “${port}.log”

cluster-enabled yes

cluster-config-file nodes-${port}.conf

配置开启Redis-2

redis-server redis-7000.conf

redis-server redis-7001.conf

redis-server redis-7002.conf

redis-server redis-7003.conf

redis-server redis-7004.conf

redis-server redis-7005.conf

meet

Cluster节点主要配置

分配槽

设置主从

Redis 3.0后,节点之间通过去中心化,提供了完整的shardingreplication(复制机制仍使用原有机制,并且具备感知主备的能力)、failover解决方案,称为Redis Cluster。

即:将proxy/sentinel的工作融合到了普通Redis节点。

Redis Cluster 集群架构

=================================================================================

Redis Cluster采用无中心结构,每个节点都可以保存数据和整个集群状态,每个节点都和其他所有节点连接。要让集群正常运作至少需要三个主节点,即Cluster 至少为6个才能保证组成完整高可用的集群,三主三从:

  • 主节点分配槽,处理客户端的命令请求

  • 从节点可用在主节点故障后,顶替主节点

集群架构为拓扑结构。一个Redis Cluster由多个Redis节点组成。不同的节点组服务的数据无交集,每个节点对应数据sharding的一个分片。

节点组内部分为主备2类,对应masterslave。两者数据准实时一致,通过异步的主备复制保证。

一个节点组有且仅有一个master,同时有0到多个slave。只有master对外提供写服务,读服务可由master/slave提供

  • Redis Cluster结构

key-value全集被分成5份,5个slot(实际上Redis Cluster有 16384 [0-16383] 个slot,每个节点服务一段区间的slot,此处仅是为了举例)。

A、B为M节点,对外提供写服务。分别负责1/2/3和4/5的slot。A/A1和B/B1/B2之间通过主备复制以同步数据。

这5个节点,两两通过Redis Cluster Bus交互,相互交换如下的信息:

  • 数据分片(slot)和节点的对应关系

  • 集群中每个节点可用状态

  • 集群结构发生变更时,通过一定的协议对配置信息达成一致。数据分片的迁移、主备切换、单点master的发现和其发生主备关系变更等,都会导致集群结构变化

  • publish/subscribe(发布/订阅)功能,在Cluster版内部实现所需要交互的信息

Redis Cluster Bus通过单独的端口进行连接,由于Bus是节点间的内部通信机制,交互的是字节序列化信息。相对Client的字符序列化来说,效率较高。

Redis Cluster是一个去中心化的分布式实现方案,客户端和集群中任一节点连接,然后通过后面的交互流程,逐渐的得到全局的数据分片映射关系。

说说Redis Cluster 的优点?

  • 去中心化

  • 可扩展性

数据是按槽分配的,节点之间数据共享,节点动态的添加和删除

  • 高可用性

部分节点不可用时,集群仍是可用的,因为从节点作为副本提供了数据的备份保障

  • 自动故障转移

节点之间投票选举,从升级为主

说说Redis Cluster 的缺点?

  • 数据通过异步复制,无法保证数据强一致性

  • 集群环境搭建略微复杂。

2 配置的一致性

=======================================================================

对于去中心化的实现,集群的拓扑结构并不保存在单独的配置节点上,后者的引入同样会带来新的一致性问题。

那么各自为政的节点间,如何对集群的拓扑达成一致,是Redis Cluster配置机制要解决的问题。

Redis Cluster通过引入2个自增的epoch变量,来使得集群配置在各个节点间最终达成一致。

2.1 配置信息数据结构


Redis Cluster中的每个节点(Node)都保存了集群的配置信息,并且存储在clusterState中,结构如下

  • clusterState 记录了从集群中某个节点视角,来看集群配置状态

  • currentEpoch 表示整个集群中最大的版本号,集群信息每变更一次,改版本号都会自增

  • nodes 是一个列表,包含了本节点所感知的,集群所有节点的信息(clusterNode),也包含自身的信息。

  • clusterNode 记录了每个节点的信息,其中包含了节点本身的版本 Epoch;自身的信息描述:节点对应的数据分片范围(slot)、为M时的R列表、为R时的M节点

  • 每个节点包含一个全局唯一的NodeId

  • 当集群的数据分片信息发生变更(数据在节点间迁移时),Redis Cluster 仍然保持对外服务

  • 当集群中某个master宕机,Redis Cluster 会自动发现,并触发故障转移的操作。将master的某个slave晋升为新的 master。

由此可见,每个节点都保存着Node视角的集群结构。它描述了数据的分片方式,节点主备关系,并通过Epoch 作为版本号实现集群结构信息的一致性,同时也控制着数据迁移和故障转移的过程。

2.2 信息交互

=======================================================================

去中心化的架构不存在统一的配置中心。在Redis Cluster中,这个配置信息交互通过Redis Cluster Bus来完成(独立端口)。Redis Cluster Bus 上交互的信息结构如下:

  • Redis Cluster 交互信息数据结构

clusterMsg 中的type指明了消息的类型,配置信息的一致性主要依靠PING/PONG。每个节点向其他节点频繁的周期性的发送PING/PONG消息。

对于消息体中的 Gossip部分,包含了sender/receiver 所感知的其他节点信息,接受者根据这些Gossip 跟新对集群的认识。

对于大规模的集群,如果每次PING/PONG 都携带着所有节点的信息,则网络开销会很大。此时Redis Cluster 在每次PING/PONG,只包含了随机的一部分节点信息。由于交互比较频繁,短时间的几次交互之后,集群的状态也会达成一致。

2.3 一致性的达成


当Cluster 结构不发生变化时,各个节点通过gossip 协议在几轮交互之后,便可以得知Cluster的结构信息,达到一致性的状态

但是当集群结构发生变化时(故障转移/分片迁移等),优先得知变更的节点通过Epoch变量,将自己的最新信息扩散到Cluster,并最终达到一致。

clusterNode 的Epoch描述的单个节点的信息版本;

clusterState 的currentEpoch描述的是集群信息的版本,它可以辅助Epoch 的自增生成

因为currentEpoch 是维护在每个节点上的,在集群结构发生变更时,Cluster 在一定的时间窗口控制更新规则,来保证每个节点的currentEpoch都是最新的

更新规则

  • 当某个节点率先知道了变更时,将自身的currentEpoch 自增,并使之成为集群中的最大值

再用自增后的currentEpoch 作为新的Epoch 版本

  • 当某个节点收到了比自己大的currentEpoch时,更新自己的currentEpoch

  • 当收到Redis Cluster Bus 消息中的某个节点的Epoch > 自身的时,将更新自身的内容

  • 当Redis Cluster Bus 消息中,包含了自己没有的节点时,将其加入到自身的配置中

上述规则保证了信息的更新是单向的,最终朝着Epoch更大的信息收敛。同时Epoch也随currentEpoch增加而增加,最终将各节点信息趋于稳定。

sharding


不同节点分组服务于相互无交集的分片(sharding)

Redis Cluster 不存在单独的proxy或配置服务器

所以需要将客户端路由到目标的分片

1 数据分片(slot)

Redis Cluster 将所有的数据划分为16384 [0-16383] 个分片,每个分片负责其中一部分。

每条数据(key/value)根据K值,通过数据分布算法(一致性哈希)映射到16384 个slot中的一个。

数据分布算法

slotId = crc16(key) % 16384

客户端根据 slotId 决定将请求路由到哪个Redis 节点。

Cluster 不支持跨节点的单命令,如:sinterstore,若涉及的2个K对应的slot 在不同Node,则执行失败。

通常Redis的K带有业务意义,如:

  • Product:Trade:20180890310921230001

  • Product:Detail:20180890310921230001

当在集群中存储时,上述同一商品的交易和详情可能会存储在不同的节点上,进而对于这2个K 不能以原子的方式操作

为此,Redis引入HashTag,使得数据分布算法可以根据key 的某一部分进行计算,让相关的2 条记录落到同一个数据分片

商品交易记录key:Product:Trade:{20180890310921230001}

商品详情记录key:Product:Detail:{20180890310921230001}

Redis 会根据 {} 之间的字符串作为数据分布式算法的输入。

客户端的路由

Redis Cluster的客户端相比单机Redis 需要具备路由语义的识别能力,且具备一定的路由缓存能力

当Client 访问的K不在当前Redis节点的slots中,Redis 会返回给Client一个moved命令。并告知其正确路由信息

Client接收到moved 后,再次请求新的Redis时,此时Cluster结构又可能发生了变化。此时有可能再次返回moved。

Client 会根据moved响应,更新其内部的路由缓存信息,以便后续操作直接找到正确节点,减少交互次数。

当Cluster在数据重新分布过程中时,可通过ask命令控制客户端的路由,如下所示:

​​​​上图中,slot1 需迁移到新节点,此时若客户端已完成迁移的K,节点将相应ask告知客户端想目标节点重试。

ask V.S moved
  • moved 会更新Client数据路由

  • ask 只是重定向新节点,但是后续相同slot仍会路由到旧节点

迁移的过程可能会持续一段时间,这段时间某个slot的数据,同时可能存在于新旧 2 个节点。

由于move 操作会使Client 的路由缓存变更,若新旧节点对迁移中的slot 所有key 都回应moved,客户端的路由缓存会频繁变更。因此引入ask 类型消息,将重定向和路由缓存分离

3 分片的迁移

在一个稳定的Redis Cluster 中,每个slot 对应的节点都是确定的。在某些情况下,节点和分片需要变更:

新的节点作为master加入;

某个节点分组需要下线;

负载不均衡需要调整slot 分布。

此时需要进行分片的迁移,迁移的触发和过程控制由外部系统完成。Redis Cluster 只提供迁移过程中需要的原语,包含下面 2 种:

节点迁移状态设置:迁移前标记源/目标节点。

key迁移的原子化命令:迁移的具体步骤。

image.gif

slot 1 从节点A 迁移到B的过程

image

1、向节点B发送状态变更命令,将B的对应slot 状态置为importing。

2、向节点A发送状态变更命令,将A对应的slot 状态置为migrating。

3、针对A上的slot 的所有key,分别向A 发送migrate 命令,告知A 将对应的key 迁移到B。

当A节点的状态置为migrating 后,表示对应的slot 正在从A迁出,为保证该slot 数据的一致性。A此时提供的写服务和通常状态下有所区别,对于某个迁移中的slot:

如果Client 访问的key 尚未迁出,则正常的处理该key;

如果key已经迁出或者key不存在,则回复Client ASK 信息让其跳转到B处理;

image.gif

当节点B 状态变成importing 后,表示对应的slot 正在向B迁入。即使B 能对外提供该slot 的读写服务,但是和通常情况下有所区别:

当Client的访问不是从ask 跳转的,说明Client 还不知道迁移。有可能操作了尚未迁移完成的,处在A上面的key,如果这个key 在A上被修改了,则后续会产生冲突。

所以对于该slot 上所有非ask 跳转的操作,B不会进行操作,而是通过moved 让Client 跳转至A执行。

image.gif

这样的状态控制,保证了同一个key 在迁移之前总是在源节点执行。迁移后总是在目标节点执行,从而杜绝了双写的冲突。迁移过程中,新增加的key 会在目标节点执行,源节点不会新增key。使得迁移有界限,可以在某个确定的时刻结束。

单个key 的迁移过程可以通过原子化的migrate 命令完成。对于A/B的slave 节点,是通过主备复制,从而达到增删数据。

当所有key 迁移完成后,Client 通过 cluster setslot 命令设置B的分片信息,从而包含了迁入的slot。设置过程中会让Epoch自增,并且是Cluster 中的最新值。然后通过相互感知,传播到Cluster 中的其他节点。

failover

同Sentinel 一样,Redis Cluster 也具备一套完整的故障发现、故障状态一致性保证、主备切换机制。

1、failover的状态变迁

1)故障发现:当某个master 宕机时,宕机时间如何被集群其他节点感知。

2)故障确认:多个节点就某个master 是否宕机如何达成一致。

3)slave选举:集群确认了某个master 宕机后,如何将它的slave 升级成新的master;如果有多个slave,如何选择升级。

最后

毕竟工作也这么久了 ,除了途虎一轮,也七七八八面试了不少大厂,像阿里、饿了么、美团、滴滴这些面试过程就不一一写在这篇文章上了。我会整理一份详细的面试过程及大家想知道的一些问题细节

美团面试经验

美团面试
字节面试经验
字节面试
菜鸟面试经验
菜鸟面试
蚂蚁金服面试经验
蚂蚁金服
唯品会面试经验
唯品会

因篇幅有限,图文无法详细发出

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

了 ,除了途虎一轮,也七七八八面试了不少大厂,像阿里、饿了么、美团、滴滴这些面试过程就不一一写在这篇文章上了。我会整理一份详细的面试过程及大家想知道的一些问题细节

美团面试经验

[外链图片转存中…(img-D0qj9iJb-1715117776169)]
字节面试经验
[外链图片转存中…(img-bSdvAG37-1715117776169)]
菜鸟面试经验
[外链图片转存中…(img-AAgS1prZ-1715117776169)]
蚂蚁金服面试经验
[外链图片转存中…(img-KefRb15M-1715117776170)]
唯品会面试经验
[外链图片转存中…(img-xSpSgVy1-1715117776170)]

因篇幅有限,图文无法详细发出

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值