当前位置: 首页 > news >正文

Redis Cluster


文章目录

  • 一、集群搭建
    • 1 节点规划
    • 2 集群启动
  • 二、配置一致性
    • 1 基本分工
    • 2 更新规则
  • 三、Sharding
    • 1 数据分片
      • 分片实现
      • 分片特点
    • 2 slot迁移
      • 迁移原因
      • 迁移支持
      • 集群扩容
      • 迁移错误
        • 背景
        • 现象
        • 问题分析
        • 验证
        • 猜想
      • 集群缩容
    • 3. 请求路由
      • client端
      • server端
      • migrating节点的读写
      • importing节点的读写
      • 关于salve节点
    • 4. 迁移小结
  • 四、Failover
    • 1. 状态变迁
    • 2. 故障发现
      • 单节点感知
      • 网络的不确定性
    • 3. 故障确认
    • 4. slave选举
    • 5. 最终变更同步
    • 6. Failover小结
  • 总结


一、集群搭建

1 节点规划

  1. 计划包含多少个master/slave组;
  2. 每组仅存储部分数据;
  3. 配置文件中需要启用cluster mode;

2 集群启动

#!/bin/bash
./redis-server.sh 7380
./redis-server.sh 7381
./redis-server.sh 7382
./redis-server.sh 7383
./redis-server.sh 7384
./redis-server.sh 7385redis-cli --cluster create localhost:7380 localhost:7381 localhost:7382 localhost:7383 localhost:7384 localhost:7385 --cluster-replicas 1

二、配置一致性

1 基本分工

  1. 每个节点保持整个集群的所有信息;
  2. 每个节点持有集群信息更新版本号, 单调递增;
  3. 每个节点周期性地向集群中的其他节点发送心跳, PING中携带自身节点信息, PONG中携带对方所知道的集群信息;

2 更新规则

  1. 当某个节点率先知道了变更时,将自身的currentEpoch自增,并使之成为集群中的最大值。再用自增后的currentEpoch 作为新的Epoch版本;
  2. 当某个节点收到了比自己大的currentEpoch时,更新自己的currentEpoch;
  3. 当收到的Redis Cluster Bus 消息中的某个节点的Epoch > 自身的时,将更新自身的内容;
  4. 当Redis Cluster Bus 消息中,包含了自己没有的节点时,将其加入到自身的配置中。
    上述的规则保证了信息的更新都是单向的,最终朝着Epoch更大的信息收敛。同时Epoch也随着currentEpoch的增加而增加,最终将各节点信息趋于稳定。

三、Sharding

1 数据分片

分片实现

  1. server默认整个集群有16384个slot, 然后在集群初始化时会均匀分配到每个master上, 进而可以知道每个slotId与master的对应关系。
  2. 由于Redis是K-V结构, 当新增某个key时, 通过算法(slotId = crc16(key) % 16384)得到slotId, 然后将目标的key写入目标slot。这里想强调的是, 由于key本身是固定的, 因此其对应的slotId也是固定的, 这是一种逻辑上的对应关系。而物理对应关系则是由配置信息中slotId与master节点的映射来实现。而这个关系对Redis client来说非常重要。

分片特点

  1. 解耦数据和节点之间的关系,简化了节点扩容和收缩难度。
  2. 节点自身维护槽的映射关系,不需要客户端 或 代理服务维护数据分片关系。
  3. Redis Cluster的节点之间会共享消息,每个节点都知道另外节点负责管理的槽范围。每个节点只能对自己负责的槽进行维护 和 读写操作。
    虽然每个分片(shard)维护一定数量的slot, 但slot与shard的映射关系是可以动态调整的。此外, 数据迁移也是以slot为单位进行。

2 slot迁移

当sharding rebalance时, slotId与master的映射关系发生变化, slotId与key的映射关系不变。
此外, 具体的业务场景中, 考虑到数据的局部性, 可能会把相关的数据放入同一个slot上, 此时可以在key中加入{}。此时Redis server不再使用整个key, 而是仅使用{}中的内容来计算slotId。

迁移原因

  1. 新的master节点加入;
  2. 旧节点关机下线或者维护;
  3. 数据分布不均衡, 需要手动调整slot位置以均衡压力;

迁移支持

具体迁移过程由外部触发, Redis Cluster本身只提供了迁移过程中需要的指令支持。

  1. 节点迁移状态设置, 迁移前标记源/目标节点;
  2. key迁移的原子化命令;
  3. 将迁移后的配置循环广播到其他master节点;

集群扩容

  1. 将新节点加入集群;
    cluster meet ip
  2. 在新节点上设置待导入的slot
    cluster setslot {slotId} importing {sourceNodeId}

cluster setslot 0 importing 5df7af18093ac10b8a4a4121abb1b4fd6b0465c3
3. 数据源节点设置待迁移的slot
cluster setslot {slotId} migrating {targetNodeId}

cluster setslot 0 migrating 199a9dec48962ec0a017a28a85a5fa9b414d91f3
4. 源节点获取一批目标slot的key
cluster getkeysinslot {slotId} {count}
cluster getkeysinslot 0 100

  1. 从源节点发起迁移
    migrate {targetNodeIp} {targetNodePort} "" 0 {timeout} keys { key... }
    migrate localhost 7381 “” 0 1000 keys key-c19780 key-c13965 key-c9249
    该步骤手动执行, 如果目标地址错误, 则数据丢失。仅有

  2. 重复4和5直到获取不到新的key

  3. 广播新的slot位置
    cluster setslot {slotId} node {nodeId}

cluster setslot 0 node 7fc05faa8893c7f75aab12e057a40176a873e4ca
设置会让导入节点的Epoch自增,成为Cluster中的最新值,然后通过Redis Cluster Bus相互感知,传播到Cluster中的其他节点。
7. 如果是存量集群内部迁移, 则不考虑新节点加入, 其他步骤相同。

迁移错误

背景

源和目标节点状态设置正确, 但migrate的目标位置错误不是既定的目标节点;

现象

源节点slot状态为migrating;
目标节点slot状态为importing;
migrate也迁移成功,然后在不同节点的表现有点花:

  1. 在源节点上get返回ASK {实际migrate节点};
  2. 在{migrate目标节点}get返回MOVED {源节点};
  3. 在importing节点上get返回MOVED {源节点};

问题分析

  1. 数据是否丢失?
    a. 从上面get的结果来看, 无法从任何一个节点中读取出来;
    b. 从migrate成功来看, 数据一定在{实际migrate节点}上;
    c. 在{实际migrate节点}上, 执行keys发现key是存在的, 因此可以确定数据未丢失;

  2. 为何无法读取?
    显然每个key都有对应的slot, 并且slot需要在当前的节点。因此该问题的root cause是, 数据位置和slot配置信息不一致。而目前由于value无法读取, 因此无法再对数据做移动。只能调整slot位置, 尝试通过cluster set slot设置slot的位置为当前节点。

验证

  1. 执行cluster slot命令到实际数据接收节点, 成功;
  2. 在实际数据接收节点执行get key命令, 成功;
  3. 在其他节点执行get key命令, 统一MOVDED到新节点;
  4. 至此, 问题解决;

猜想

  1. Redis Cluster的配置和存储之间没有强约束, 也就是虽然我当前节点没有某个slot的配置信息, 但是migrate的情况下依然可以接收目标key, 只是无法读取出来;
  2. 设置importing和migrating的状态, 仅是告诉client这个slot中的key有不确定性。这种不确定性由其他节点完成最终确定, 如果是人为错误, 就一直在确定的路上;
  3. 每个节点由于不掌握全局信息, 只能按照自己已知的信息来回复client;
  4. 其实slot的迁移直接可以通过cluster setslot完成, 其中的数据迁移依赖外部的处理, 至于迁移过程中client的访问结果则看server的状态;
  5. 总体来看, 整个过程耦合非常松散, 手动操作容易出错, 运维时得务必小心;

集群缩容

  1. 确认目标节点是否有负责的slot;
  2. 如果有负责的slot, 则需要将其迁移到其他节点上, 数据迁移过程可参考集群扩容;
  3. 数据迁移完毕后, 通知其他master忘记该节点;
  4. 当所有节点都忘记该节点后, 即可下线;

3. 请求路由

从运行时来看, slotId与master节点的映射关系是动态的。因此每次请求都要先确定映射关系, 这就是请求路由。

client端

  1. 连接集群中任意一个host缓存其映射关系快照;
  2. 后续实际访问的过程中更新本地缓存;
  3. 每次操作key之前先读取本地缓存确定目标实例;

server端

ask命令: 如果slot在迁移过程中, 则重定向到源节点或者目标节点确认;
moved命令: 如果slot已经移动完毕, 则返回moved;

migrating节点的读写

当某个节点的状态置为migrating后,表示对应的slot正在导出,为保证该slot数据的一致性,节点此时提供的写服务和通常状态下有所区别。
a. 对于某个迁移中的slot, 如果Client访问的key尚未迁出,则正常的处理该key;
b. 对于某个迁移中的slot, 如果key已经迁出或者key不存在,则回复Client ASK信息让其跳转到importing节点处理;

importing节点的读写

当节点状态变成importing后,表示对应的slot正在导入。此时的读写服务和通常情况下有所区别。
a. 当Client的访问不是从ask跳转的,说明Client还不知道迁移。有可能操作了尚未迁移完成的,处于源节点上面的key,如果这个key在源节点上被修改了,则后续会产生冲突。所以对于该slot上所有非ask跳转的操作, 导入节点不会进行操作,而是通过moved让Client跳转至导出节点执行。
b. 这样的状态控制,保证了同一个key在迁移之前总是在源节点执行,迁移后总是在目标节点执行, 从而杜绝了双写的冲突;
c. 迁移过程中,新增加的key会在目标节点执行,源节点不会新增key, 使得迁移key趋向于收敛, 最终在某个时刻结束。

关于salve节点

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

4. 迁移小结

  1. 关于slot迁移, 其中存量key的完整性由发起迁移的client保证, 增量key的完整性由Redis Cluster本身保证;
  2. 关于migrate原子性的实现, 个人YY是基于Redis单线程命令执行。当执行用户读写命令时, key存在则执行操作, key不存在则返回ask。migrate操作读取源数据, 写入目标节点, 确认成功后删除源数据的操作, 有点儿类似于同时在migrating和importing节点做操作, 结果一边删除key而另一边增加key。显然, 如果读写是并发执行的, 可能需要额外的协调机制;

四、Failover

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

1. 状态变迁

  1. 故障发现:当某个master 宕机时,宕机时间如何被集群其他节点感知。
  2. 故障确认:多个节点就某个master 是否宕机如何达成一致。
  3. slave选举:集群确认了某个master 宕机后,如何将它的slave 升级成新的master;如果有多个slave,如何选择升级。
  4. 集群结构变更:成功选举成为master后,如何让整个集群知道,以更新Cluster 结构信息。

2. 故障发现

单节点感知

Redis Cluster 节点间通过Redis Cluster Bus 两两周期性的PING/PONG 交互。当某个节点宕机时,其他Node 发出的PING消息没有收到响应,并且超过一定时间(NODE_TIMEOUT)未收到,则认为该节点故障,将其置为PFAIL状态(Possible Fail)。后续通过Gossip 发出的PING/PONG消息中,这个节点的PFAIL 状态会传播到集群的其他节点。

网络的不确定性

Redis Cluster的节点两两保持TCP连接,当对PING 无反馈时,可能是节点故障,也可能是TCP链接断开。如果是TCP 断开导致的误报,虽然误报消息会因为其他节点的正常连接被忽略,但是也可以通过一定的方式减少误报。Redis Cluster 通过预重试机制排除此类误报:当 NODE_TIMEOUT/2 过去了,但是还未收到响应,则重新连接重发PING消息,如果对端正常则在很短的时间内就会有响应。同样如果是TCP连接断开, 也会对连接有效性做一次检测, 最终可以得出已确认的网络不可达。

3. 故障确认

对于网络分隔的情况,假设集群有4个节点(A,A1,B,B1),B并没有故障, 然而和B1无法连接,同时可以和A,A1可以正常联通。此时只会有B1将B标记为PFAIL状态,其他节点认为B正常,此时Redis Cluster通过故障确认协议达成一致。

集群中每个节点都是Gossip的接收者, B1也会接收到来自其他节点的GOSSIP消息,被告知B是否处于PFAIL状态。当B1收到来气其他master节点对于B的PFAIL达到一定数量后,会将B的PFAIL状态升级为FAIL状态, 表示B已经确认为故障态。后面会发起master选举流程。

4. slave选举

  1. 如果一个节点B有多个slave(1/2/3)都认知到B处于FAIL状态了,那么可能会同时发起竞选。当B的slave个数 >= 3时,很有可能产生多轮竞选失败。为了减少冲突的出现,优先级高的slave 更有可能发起竞选,从而提升成功的可能性。这里的优先级是slave的数据最新的程度,数据越新的(最完整的)优先级越高。

  2. slave 通过向其他master发送FAILVOER_AUTH_REQUEST 消息发起竞选,master收到后回复FAILOVER_AUTH_ACK消息告知是否同意。slave 发送FAILOVER_AUTH_REQUEST 前会将currentEpoch自增,并将最新的Epoch带入到FAILOVER_AUTH_REQUEST消息中,如果自己未投过票,则回复同意,否则回复拒绝。

5. 最终变更同步

当slave 收到过半的master 同意时,会替代B成为新的master。此时会以最新的Epoch 通过PONG 消息广播自己成为master,让Cluster 的其他节点尽快的更新拓扑结构。
当B恢复可用之后,它仍然认为自己是master,但逐渐的通过Gossip 协议得知某个slave已经替代了自己,然后主动降级为新master的slave。

6. Failover小结

  1. 从整个过程来看, 对于一组主从, 从节点发现主节点断开, 需要借助其他节点来帮助完成故障确认。
  2. 最终, 也是某个slave最先将master标记为Fail。一旦完成对master的Fail标记, slave节点就会发起选举(毕竟最具条件, 时刻准备谋权篡位)。
  3. 在选举成功后, 原来的master也要为新master让步。

总结

本文介绍了Redis Cluster模式集群的搭建、数据分区的迁移以及故障迁移过程, 希望能帮助你对Redis Cluster模式有更进一步的认识和理解, 感谢您的阅读。

相关文章:

Redis Cluster

文章目录 一、集群搭建1 节点规划2 集群启动 二、配置一致性1 基本分工2 更新规则 三、Sharding1 数据分片分片实现分片特点 2 slot迁移迁移原因迁移支持集群扩容迁移错误背景现象问题分析验证猜想 集群缩容 3. 请求路由client端server端migrating节点的读写importing节点的读写…...

Pandas常用指令

astype astype的作用是转换数据类型,astype是没办法直接在原df上进行修改的,只能通过赋值的形式将原有的df进行覆盖,即df df.astype(dtype) astype的基本语法 DataFrame.astype(dtype, copyTrue, errorsraise) dtype参数指定将数据类型转换…...

FPGA实战小项目3

基于FPGA的波形发生器 基于FPGA的波形发生器 基于FPGA的beep音乐播放器设计 基于FPGA的beep音乐播放器设计 基于FPGA的cordic算法实现DDS sin和cosine波形的产生 基于FPGA的cordic算法实现DDS sin和cosine波形的产生...

mysql创建用户

创建用户 创建 -- 创建用户 itcast , localhost只能够在当前主机localhost访问, 密码123456; create user test01localhost identified by 123456;使用命令show databases;命令,只显示一个数据库,因为没有权限 -- 创建用户 test02, 可以在任意主机访问…...

程序员写好简历的5个关键点

程序员就业竞争大?找不到工作?也许,从简历开始你就被淘汰了.... 在很多的公司中,HR的招聘压力是很大的,浏览每个人的简历的时间可能只有20几秒,所以即使你的工作能力十分的强,但如果你没有在简…...

Vue:关于如何配置一级路由和二级路由的方法

路由的嵌套配置 文章目录 路由的嵌套配置配置一级路由 配置一级路由 创建router文件夹,里面添加index.js文件配置以下代码: import Vue from vue import VueRouter from "vue-router"; import Layout from /views/Layout import ArticleDeta…...

【论文绘图】seaborn分类数据绘图

参考:https://seaborn.pydata.org/tutorial/categorical.html 分类变量关系图中的catplot类似于连续变量中的relplot,默认是stripplot。 分类变量图种类 分类散点图 stripplotswarmplot (kind‘swarm’) 类别分布图 boxplotviolinplotboxenplot …...

KubeSphere Namespace 数据删除事故分析与解决全记录

作者:宇轩辞白,运维研发工程师,目前专注于云原生、Kubernetes、容器、Linux、运维自动化等领域。 前言 2023 年 7 月 23 日在项目上线前夕,K8s 生产环境出现故障,经过紧急修复之后,K8s 环境恢复正常&#…...

mysql场景题:最近7天连续3天登陆用户,字段,id,date(已去重)

1.最近7天连续3天登陆用户,字段,id,date(已去重) 思路: lag对时间开窗(注意时间得转换为时间戳(int类型才可以添加后续条件),跳行为2(连续3天&am…...

华为OD机试 - 最差产品奖 - 双端队列 deque(Java 2023 B卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…...

【校招VIP】前端算法考察之链表算法

考点介绍: 链表是一种物理存储结构上非连续的数据结构,数据的逻辑顺序是通过链表中的指针链接次序实现相互勾连。链表相对数组而言有很多不同之处,在特定场景下能发挥独特的优势。例如链表的插入和删除操作比数组效率高,数组需要改变其他元素的位置,而链表只需要改变…...

uni-app之android离线自定义基座

一 为什么要自定义基座 1,基座其实就是一个app,然后新开发的页面可以直接在手机上面显示,查看效果。 2,默认的基座就是uniapp帮我们打包好的基座app,然后我们可以进行页面的调试。 3,自定义基座主要用来…...

【AWS】实操-保护 Amazon S3 VPC 终端节点通信

文章目录 实验概览目标实验环境任务 1:探索并启动实验环境任务 1.1:探索 Amazon VPC 资源任务 1.2:探索 Amazon EC2 资源任务 1.3:创建 Amazon VPC 终端节点任务 1.4:连接私有 EC2 实例任务 1.5:探索 Amazo…...

C# Color颜色RGB对照表

序号Color色系颜色RGB图例1Color.AliceBlue蓝色艾丽丝蓝240,248,2552Color.AntiqueWhite白色古典白色250,235,2153Color.Aqua,Color.Cyan青色浅蓝色,蓝绿色,青色0,255,255 C# Color颜色RGB对照表_旭东怪的博客-CSDN博客 C#颜色和名称样式对照…...

Thread中几个常用的api详解join,interrupt

1.join() join方法可以在多线程中帮我们实现调用线程的同步效果,比如,现在有三个线程,a,b,c a中启动了b和c线程异步去执行一件事,但是a希望他们做完以后再继续往下执行,那么就可以在调用b和c启…...

Golang项目实战(三)

Golang项目实战(三) 该项目是使用grpcgin来构建的一个电商微服务项目,使用consul来注册和发现微服务。 项目简介创建项目架构创建货币服务创建货币微服务处理器将货币微服务注册到consul下载安装consul并发布服务创建商品微服务准备商品数据…...

TSUMU58CDT9-1显示器芯片方案

TSUMU58CDT9-1是用于LCD显示器的整体解决方案图形处理IC,面板分辨率高达WUXGA。它配置了高速集成三adc /PLL、集成DVI/HDMI接收器、高质量显示处理引擎、集成微控制器和支持LVDS面板接口格式的输出显示接口。TSUMU58CDT9-1支持一个灵活的可配置数字输入接口&#xf…...

React 安装使用 Less(详细流程,包含 webpack、craco 方式)

一、简介 React 项目开发中可能会使用到 Less、Sass 等样式预处理器,create-react-app 创建的 React 项目,默认就是支持 Sass 的。如果需要使用 Less 则需要额外手动安装配置。 二、方式一:webpack.config.js 配置(不推荐&#…...

力扣(LeetCode)算法_C++—— 快乐数

编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果这个过程 结果为 1&#xff0…...

滴滴笔试——算式转移

题目:给出一个仅包含加减乘除四种运算符的算式(不含括号),如12*3/4,在保持运算符顺序不变的情况下,现在你可以进行若干次如下操作:如果交换相邻的两个数,表达式值不变,那么你就可以交换这两个数…...

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

【机器视觉】单目测距——运动结构恢复

ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛&#xf…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...