写点什么

Redis Cluster 原理初探

  • 2019-09-20
  • 本文字数:3405 字

    阅读完需:约 11 分钟

Redis Cluster原理初探

虽然到现在仍未发现公司内部有团队在使用 Redis Cluster,但是这丝毫不影响我们去了解它。Redis Cluster 是一个可以在多个 Redis 节点之间进行数据共享的分布式集群。和以往了解的客户端通过一致性哈希解决 redis 多节点负载均衡的方式不同,Redis Cluster 是在服务端,通过节点之间的特殊协议进行通讯,达到服务端对请求进行负载均衡。对于客户端来说,其负载均衡策略是透明的,客户端不需要自己做负载均衡。

集成简介

Redis Cluster 特性之一是引入了槽的概念。一个 redis 集群包含 16384 个哈希槽,集群中的每个 redis 节点,分配到一部分槽。而集群使用公式 CRC16(key) % 16384 来计算每次请求的键 key 属于哪个槽,通过查询集群配置,便可知道 key 对应的槽属于哪个 redis 节点,然后再将请求打到该节点。举个例子,一个集群可以有两个节点,其中:


1.节点 A 负责处理 0 号至 5000 号哈希槽。


2.节点 B 负责处理 5001 号至 10000 号哈希槽。


3.节点 C 负责处理 10001 号至 16383 号哈希槽。


通过上述公式,可对 key X 计算出一个值,该值为 0-16383 中的一个数。假设 key X 通过上述公式计算出来的值为 34,根据上面例子,34 即为槽标识,亦 key X 属于槽 34,而槽 34 分配到了节点 A,也就是说节点 A 负责 key X 的读写。


通过将哈希槽分布到不同节点,我们可以很容易地向集群中添加或者删除节点。比如说:


  1. 如果用户将新节点 D 添加到集群中,那么集群只需要将节点 A 、B、C 中的某些槽移动到节点 D 就可以了。

  2. 与此类似,如果用户要从集群中移除节点 A ,那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C ,然后再移除节点 A 就可以了。


因为槽在节点之间移动不会造成节点阻塞,所以无论是添加新节点还是移除已存在节点,又或者改变某个节点包含的哈希槽数量,都不会造成集群下线,redis 集群能保证槽的平滑移动。


RedisCluster 还有一个特性便是去中心化。客户端可以连接集群中的任意一个节点,集群中的任意一个节点都可对外提供服务。节点之间可共享集群配置(如槽的分配)。或者我们可以理解为,集群中的任意一个节点都是中心节点。假设有两个节点 A 和 B,客户端连接了 A 节点,并发起了一次请求 a,A 节点计算请求 a 的 key 得知该请求应该打到 B 节点上,然后 A 节点对请求 a 返回一个 MOVED B,通知客户端重定向到 B 节点。

集成简介

redis 集群架构图


因为槽在节点之间移动不会造成节点阻塞,所以无论是添加新节点还是移除已存在节点,又或者改变某个节点包含的哈希槽数量,都不会造成集群下线,redis 集群能保证槽的平滑移动。


以上图片,蓝色的为 redis 节点,这里是指 master 节点,一个 master 节点可以配置多个 slave。绿色为客户端,可以理解为我们的应用。


架构细节:


(1)所有的 redis 节点彼此互联(PING-PONG 机制),内部使用二进制协议优化传输速度和带宽。


(2)节点的 fail 是通过集群中超过半数的节点检测失效或者某个节点主从全挂时才生效。


(3)客户端与 redis 节点直连,不需要中间 proxy 层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。


(4)redis-cluster 把所有的物理节点映射到[0-16383]slot 上。

集群容错

为了当部分节点失效时,cluster 仍能保持可用,Redis 集群采用每个节点拥有 1(主服务自身)到 N 个副本的主从模型。类似于 master/slave。但是 redis cluster 却不是强一致性的,因为 cluster 内部 master 和 slave 之间是通过异步复制做数据同步的,复制过程中可能 master 挂了,这就导致部分数据没有完全同步至 slave 上,不过这种可能性还是很小的。


以上是集群选举过程。


选举过程是集群中所有 master 参与,如果半数以上 master 节点与当前 master 节点通信超时,则集群认为当前 master 节点挂掉.


什么时候整个集群不可用?当集群不可用时, 所有对集群的操作做都将失败。以下是会导致集群不可用的其中两种情况:


a:集群任意 master 挂掉,并且当前 master 没有 slave,集群不可用。


b:集群超过半数以上 master 挂掉,无论是否有 slave,集群不可用。

集群扩展

什么时候整个集群不可用?当集群不可用时, 所有对集群的操作做都将失败。以下是会导致集群不可用的其中两种情况:


选举过程是集群中所有 master 参与,如果半数以上 master 节点与当前 master 节点通信超时,则集群认为当前 master 节点挂掉。


以往的一致性哈希方案,如果我们移除或者新增节点时,虽然说不会导致全局 key 的 rehash,但是也会影响到部分 key 的失效。Redis Cluster 在可用性和可扩展性上比较重视,如果集群新增一个节点,在给该节点分配槽时,这些槽所属的源节点和该节点会进行一次 key 的迁移,并且迁移过程中不阻塞集群服务。如果移除一个节点,同理,我们需要将待移除的节点的 key 迁移到另一个节点上。


那集群是如何做到 key 迁移不阻塞集群服务的呢?


key 迁移过程中,涉及到 CLUSTER SETSLOT slot8 MIGRATING node 命令和 CLUSTER SETSLOT slot8 IMPORTING node 命令,前者用于将给定节点 node 中的槽 slot8 迁移出节点,而后者用于将给定槽 slot8 导入到节点 node :


(1)、如果一个槽被设置为 MIGRATING 状态时,原本持有该槽的节点会继续接受关于这个槽的命令请求,但只有当键存在于该节点时,节点才会处理这个请求。如果命令所使用的键不存在于该节点,那么节点将向客户端返回一个 ASK 转向(redirection)错误,告知客户端,要将命令请求发送到槽的迁移目标节点。


(2)、如果一个槽被设置为 IMPORTING 状态时,节点仅在接收到 ASKING 命令之后,才会接受关于这个槽的命令请求。如果客户端向节点发送该槽的数据请求,命令为非 ASKING 时,那么节点会使用 MOVED 转向错误将命令请求转向至真正负责处理这个槽的节点。


举个例子来看看。


假设现在,我们有 A 和 B 两个节点,我们想将槽 8 从节点 A 移动到节点 B ,于是我们:


**(1)、向节点 B 发送命令 CLUSTER SETSLOT 8 IMPORTING A


(2)、向节点 A 发送命令 CLUSTER SETSLOT 8 MIGRATING B**


每当客户端向其他节点发送关于哈希槽 8 的命令请求时,这些节点都会向客户端返回指向节点 A 的转向信息(迁移中,虽然 A 和 B 都有槽 8 所对应的 key,但是各个节点仍然认为槽 8 由 A 负责,只有迁移结束后,槽 8 才属于 B 节点而不属于 A)。


(1)、如果命令要处理的键已经存在于槽 8 里面,那么这个命令将由节点 A 处理。



(2)、如果命令要处理的键未存在于槽 8 里面,那么这个命令由节点 B 处理。



这种机制将使得节点 A 不再创建关于槽 8 的任何新键。


与此同时,一个特殊的客户端 redis-trib 以及 Redis 集群配置程序(configuration utility)会将节点 A 中槽 8 里面的键移动到节点 B 。移动 key 的操作是原子性的,也就是一个 key 如果从 A 移动到 B,那么移动时,都不会出现 key 在 A 和 B 中同时出现。

内部数据结构

RedisCluster 涉及三个核心的数据结构 clusterState、clusterNode、clusterLink 都在 cluster.h 中定义。这三个数据结构中最重要的属性就是:clusterState.slots、clusterState.slots_to_keys 和 clusterNode.slots,它们保存了三种映射关系:


clusterState:集群状态


nodes:所有结点


migrating_slots_to:迁出中的槽


importing_slots_from:导入中的槽


slots_to_keys:槽中包含的所有 Key,用于迁移 Slot 时获得其包含的 Key


slots:Slot 所属的结点,用于处理请求时判断 Key 所在 Slot 是否自己负责 clusterNode:结点信息


slots:结点负责的所有 Slot,用于发送 Gossip 消息通知其他结点自己负责的 Slot。


clusterLink:与其他结点通信的连接


以下为这三个数据结构的定义:






结合以上数据结构,我们看看客户端请求集群时,集群处理的的流程:


1、检查 key 所在 Slot 是否属于当前节点?


  • 1.1 计算 crc16(key) % 16384 得到 Slot

  • 1.2 查询 clusterState.slots 负责 Slot 的结点指针

  • 1.3 与 myself 指针比较


2、若不属于,则响应 MOVED 错误重定向客户端


3、若属于且 Key 存在,则直接操作,返回结果给客户端


4、若 Key 不存在,检查该 Slot 是否迁出中?(clusterState.migrating_slots_to)


5、若 Slot 迁出中,返回 ASK 错误重定向客户端到迁移的目的服务器上


6、若 Slot 未迁出,检查 Slot 是否导入中?(clusterState.importing_slots_from)


7、若 Slot 导入中且请求有 ASKING 标记,则直接操作


8、否则响应 MOVED 错误重定向客户端


本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。


原文链接:


https://mp.weixin.qq.com/s/zjwiOkRFvQDpKfeFL1-dUQ


2019-09-20 14:228754

评论 2 条评论

发布
用户头像
若客户端连接的master 节点挂了,是如何处理的呢?

客户端与 redis 节点直连,不需要中间 proxy 层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

2021-02-25 12:00
回复
集群下,一般客户端不会配置链接一个节点。如果链接的节点都挂了,那就没办法了
2023-09-16 10:28 · 福建
回复
没有更多了
发现更多内容

秒杀系统问题与方案设计

superman

秒杀 架构总结

Newbe.Claptrap 框架如何实现多级生命周期控制?

newbe36524

架构 微服务 .net core ASP.NET Core

Vue中使用装饰器,我是认真的

前端有的玩

Java Vue 装饰器

财务分析与主要的模型

松子(李博源)

第九周

hdhdh

手写一个重入锁

诸葛小猿

synchronized CAS 重入锁 compareAndSwap ReentrantLock

<<前端进阶篇>> PDF 出炉了 — 「阿宝哥」,精心准备的 6 万多字 170 页的前端进阶资料

阿宝哥

大前端

英特尔®AI计算盒参考设计发布 加速智能边缘崛起

最新动态

JVM系列之:JIT中的Virtual Call

程序那些事

Java JVM JIT

数据人必须知道的SQL概念(A—Z)

大唐小生

sql 数据 职场成长

ARTS打卡 第10周

引花眠

ARTS 打卡计划

老哥,您看我这篇Java集合,还有机会评优吗?

苹果看辽宁体育

Java 后端

授人以渔:stm32资料查询技巧

华为云开发者联盟

架构 armv8 芯片 华为云 二进制

谈一谈webpack打包

林浩

Java 大前端 webpack

架构师训练营第八章-作业1

A Matt

华为云GaussDB(DWS)内存知识点,你知道吗?

华为云开发者联盟

数据库 大数据 数据 内存 华为云

什么?不写代码也能做功能开发! -RUOYI 教程二

Java_若依框架教程

Java 无代码开发 若依

计算机网络基础(十一)---网络层-OSPF协议

书旅

计算机网络 网络 协议栈 OSPF

《深度工作》学习笔记(3)

石云升

学习 深度工作 工作哲学

初识分布式:MIT 6.284系列(一)

Kerwin

分布式 MIT 28天写作

技术管理者带团队的几个实用技巧

Phoenix

团队管理 企业文化 团队 价值观

基于 Golang的侵入式 Opentracing实现全链路追踪 ----实践篇

是老郭啊

你问我答:微服务治理应该如何去做?

BoCloud博云

容器 微服务 PaaS API 博云

飞天茅台超卖事故:Redis分布式锁请慎用!

程序员生活志

redis 分布式

实用!一键生成数据库文档,堪称数据库界的Swagger

程序员小富

Java MySQL

智能膜切机,解决手机贴膜行业难题

Geek_116789

微软苏州集体抵制来自阿里、华为的跳槽者:请停止你的“奋斗逼”行为!网友:看到 955 不加班的公司名单,我酸了

程序员生活志

程序员 加班 996

云小课 | IPv4枯了,IPv6来了

华为云开发者联盟

IP 公有云 虚拟私有云 华为云 虚拟化

在人工智能时代追逐的“后浪”

华为云开发者联盟

程序员 AI 开发者 技术社区 华为云

程序的机器级表示-算术与逻辑运算

引花眠

计算机基础

系统设计系列之如何设计一个短链服务

看山

架构 面试 分布式 架构设计 短链服务

Redis Cluster原理初探_文化 & 方法_邱润景_InfoQ精选文章