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

Redis 分布式集群方案 Cluster

引言

相比于Codis,Redis Cluster是Redis官方提供的解决方案。相比于Codis的不同,他是去中心化的,如图所示,该集群有三个Redis节点组成,每个节点负责整个集群的一部分数据,每个节点负责的数据多少可能不一样。三个节点相互连接组成一个对等的集群,他们之间通过一种特殊的二进制协议(Gossip)相互交互集群信息
在这里插入图片描述

Redis Cluster 将所有数据划分成16384个slots,相比Codis的1024个槽划分的更为精细,每个节点负责其中一部分槽位。槽位的信息存储于每个节点中,他不像Codis,他不需要另外的分布式存储来存储节点槽位信息

当Redis Cluster的客户端来连接集群时,他也会得到一份集群的槽位配置信息。这样当客户端要查找某个key时,可以直接定位到目标节点。

槽位定位算法

Cluster默认会对key值使用crc32算法进行hash得到一个整数值,然后用这个整数值对16384进行取模来得到具体槽位。

跳转

当客户端向一个错误的节点发出了指令,该节点会发现指令的key所在的槽位并不归自己管理,这时他会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。

Get x - MOVED 3999 127.0.0.1:6381

MOVED 指令的第一个参数3999 是key对应的槽位编号,后面是目标节点地址。
MOVED 前面有一个 - , 表示该指令是一个错误消息。

客户端收到MOVED指令后,会立即纠正本地的槽位映射表。后续所有key将使用新的槽位映射表。

迁移

迁移过程

在这里插入图片描述
Redis迁移单位是槽,Redis是一个槽一个槽进行迁移,当一个槽正在迁移时,这个槽就处于中间过渡状态。这个槽在原节点的状态为migrating,在目标节点的状态为importing,表示数据正在从源流向目标。

迁移工具redis-trib首先 1. 会在源和目标节点设置好中间过渡状态,然后 2. 一次性获取源节点槽位的所有key列表(keysinslot指令,可以部分获取),在挨个key进行迁移。每个key的迁移过程是以原节点作为目标节点的客户端。3. 原节点对当前的key执行dump指令得到序列化的内容,然后向目标节点发送指令restore携带序列化的内容作为参数,目标节点在进行反序列化就可以将内容恢复到目标节点的内存中4. 原节点收到目标节点的ok响应后就把当前节点的key删除掉就完成了单个key迁移的整个过程

从源节点获取内容 => 存到目标节点 => 从源节点删除内容

这里的迁移过程是同步的,在目标节点执行restore指令到原节点删除key之间,原节点的主线程会处于阻塞状态,直到key删除成功。

如果迁移过程中突然出现网络故障,整个slot的迁移只进行了一半,这时两个节点依旧处于中间过渡状态,待下一次迁移工具重新连上时,会继续进行迁移。

在迁移过程中,如果每个key的内容都很小,migrate指令执行会很快,就不会影响客户端的正常访问。如果key的内容很大,因为migrate指令是阻塞指令会同时导致原节点和目标节点卡顿,影响集群稳定性。所以 在集群环境下业务逻辑要尽可能避免大key的产生。

Asking

在迁移过程中,客户端访问的流程会有很大的变化。

首先新旧两个节点对应的槽位都存在部分key数据,客户端先尝试访问旧节点,如果对应得数据还在旧节点里面,那么旧节点正常处理。如果对应的数据不在旧节点里面,那么有两种可能,要么该数据在新节点里,要么根本不存在。旧节点不知道属于哪种情况,所以他会向客户端返回一个-ASK targetNodeAddr重定向指令,客户端收到这个重定向指令后,先向目标节点执行一个不带任何参数的asking指令,然后在目标节点在重新执行原先的操作指令。

容错

Redis Cluster可以为每个主节点设置若干个从节点,单主节点故障时,集群会自动将其中某个从节点提升为主节点。如果某个主节点没有从节点,那么当他发生故障时,集群将完全处于不可用状态。

网络抖动

Redis Cluster提供了一种选项 cluster-node-timeout,表示当某个节点持续timeout的时间失联时,才可以认定该节点出现故障,需要进行主从切换。如果没有这个选项,网络抖动会导致主从频繁切换。

可能下线与确定下线

因为Redis Cluster是去中心化的,一个节点认为某个节点失联了并不代表所有节点都认为他失联。所以集群还得经过一次协商的过程,只有当大多数节点都认定了某个节点失联了,集群才认为该节点需要进行主从切换来容错。

Redis集群节点采用Gossip协议来广播自己的状态以及自己对整个集群认知的改变。比如一个节点发现某个节点失联了,他会将这条信息向整个集群广播,其他节点也就可以收到这条失联信息。如果一个节点收到了某个节点失联的数量已经达到了集群的大多数,就可以标记该节点为确定下线状态,然后向整个集群广播,强迫其他节点也接受该节点已经下线的事实,并立即对该失联节点进行主从切换。

槽位迁移感知

如果Cluster中某个槽位正在迁移或者已经迁移完了,client如何能感知到槽位的变化?客户端保存了槽位和节点的映射关系表,他需要即时得到更新,才可以正常的将某条指令发到正确的节点中。

前面所述两个特殊的error指令,一个是moved一个是asking。

第一个moved是用来纠正槽位的,如果我们将指令发送到了错误的节点,该节点发现对应的指令槽位不归自己管理,就会将目标节点的地址随同moved指令回复给客户端通知客户端去目标节点去访问。这个时候客户端就会刷新自己的槽位关系表,然后重试指令,后续所有打在该槽位的指令都会转到目标节点。

第二个asking指令和moved不一样,他是用来临时纠正槽位的。如果当前槽位正处于迁移中,指令会先被发送到槽位所在的旧节点,如果旧节点存在数据,那就直接返回结果,如果不存在,那么他可能真的不存在也可能被迁移到其他节点上。所以旧节点会通知客户端去新节点尝试拿数据,看看新节点有没有,这时候就会给客户端返回一个asking error携带上目标节点的地址。客户端收到这个asking error后,就会去目标节点尝试,客户端不会刷新槽位映射关系表,因为他只是临时纠正该指令的槽位信息。

集群变更感知

当服务器节点变更时,客户端应该及时得到通知以实时刷新自己的节点关系表。客户端如何得到通知,需要分成以下2种情况

  • 目标节点挂掉了:客户端会抛出一个ConnectionError,紧接着会随机挑一个节点来重试,这时被重试的节点会通过moved error告知目标槽位被分配到的新的节点地址。

  • 运维手动修改了配置信息,将master切换到其他节点,并将旧的master移除集群。这时打在旧节点上的指令会收到一个ClusterDown的错误,告知当前节点所在集群不可用。这时客户端会关闭所有连接,清空槽位映射关系表,然后向上层抛出错误。待下一条指令过来时,就会重新尝试初始化节点信息。

相关文章:

Redis 分布式集群方案 Cluster

引言 相比于Codis,Redis Cluster是Redis官方提供的解决方案。相比于Codis的不同,他是去中心化的,如图所示,该集群有三个Redis节点组成,每个节点负责整个集群的一部分数据,每个节点负责的数据多少可能不一样…...

Redis的两种持久化方案

Redis 提供了多种持久化机制来保证数据在发生意外情况下(如断电或服务器崩溃)不丢失。以下是几种主要的 Redis 持久化方案及其特点: 1. RDB (Redis Database Backup) RDB 是 Redis 创建的数据库快照,它可以将数据集快照以二进制…...

Spring中常见知识点及使用

Spring Framework 是 Java 生态系统中最流行的开源框架之一,它提供了一系列强大的功能,用于构建企业级应用。以下是一些常见的 Spring 知识点及其使用方法: 1. 依赖注入(Dependency Injection) 依赖注入是 Spring 的…...

Excel 宏录制与VBA编程 ——VBA编程技巧篇二 (合并内容相同连续单元格、取消合并单元格并在每个单元格中保留内容)

1、合并内容相同的连续单元格 如果需要合并如图所示的工作表中B列中部门相同的连续单元格 VBA代码: Sub Mergerng()Dim IntRow As IntegerDim i As IntegerApplication.DisplayAlerts FalseWith Sheet1IntRow .Range("A65536").End(xlUp).RowFor i In…...

理解和应用工业设备字典文件:一篇详细指南

理解和应用工业设备字典文件:一篇详细指南 在工业自动化领域,设备和模块的配置和管理是一个复杂而重要的任务。为了简化这个过程,字典文件被广泛应用于描述离线对象字典。本文将详细解释字典文件的用途、格式,并举例说明如何引用…...

Python酷库之旅-第三方库Pandas(010)

目录 一、用法精讲 22、pandas.read_hdf函数 22-1、语法 22-2、参数 22-3、功能 22-4、返回值 22-5、说明 22-6、用法 22-6-1、数据准备 22-6-2、代码示例 22-6-3、结果输出 23、pandas.HDFStore.put方法 23-1、语法 23-2、参数 23-3、功能 23-4、返回值 23-5…...

海康威视监控web实时预览解决方案

海康威视摄像头都试rtsp流,web页面无法加载播放,所以就得转换成web页面可以播放的hls、rtmp等数据流来播放。 一:萤石云 使用萤石云平台,把rtsp转化成ezopen协议,然后使用组件UIKit 最佳实践 萤石开放平台API文档 …...

ubuntu运行qq音乐闪退

ubuntu运行qq音乐闪退 修改/usr/share/applications中的qqmusic.desktop,在Exec后加上 --no-sandbox,如下图所示: 该文件有可能是只读,权限不够的话用sudo vim qqmusic.desktop...

人脸检测(Python)

目录 环境: 初始化摄像头: 初始化FaceDetector对象: 获取摄像头帧: 获取数据: 绘制数据: 显示图像: 完整代码: 环境: cvzone库:cvzone是一个基于…...

Offer150-23:链表中环的入口节点

题目描述:如果一个链表中包含环,找了环的入口节点。例如,在下图所示的链表中,环的入口节点是节点4。 分析:第一步需要确定一个链表中是否包含环,可以用快慢指针来解决这个问题。定义两个指针,同时从链表的头…...

【linux】服务器创建RAID1

【linux】服务器创建RAID1 文章目录 【linux】服务器创建RAID1一、配置介绍raid介绍raid类型RAID 0:RAID 1:RAID 5:RAID 6:二、配置RAID硬件RAID:软件RAID:三、软件配置RAID1(以linux为例)1.先进入管理员模式2.安装mdadm工具3.创建raid1数组4.查看RAID数组状态5.格式化和挂载…...

记录自己Ubuntu加Nvidia驱动从入门到入土的一天

前言 记录一下自己这波澜壮阔的一天,遇到了很多问题,解决了很多问题,但是还有很多问题,终于在晚上的零点彻底放弃,重启windows。 安装乌班图 1.安装虚拟机 我开始什么操作系统的基础都没有,网上随便搜了…...

基于现有Docker镜像构建新的Docker镜像

1.拉取ubuntu 22.04的系统镜像 docker pull ubuntu:22.04 拉取成功后在DockerDesktop中可发现该镜像 2.启动刚才接取的ubuntu镜像 docker run --name Ubuntu22.04 -it -d -p 22:22 -p 80:80 -p 443:443 340d9b015b194dc6e2a13938944e0d016e57b9679963fdeb9ce021daac430221 启…...

Java 静态变量、静态代码块、普通代码块、构造方法的执行顺序

今天碰到这个问题,看了课程以及资料,做出解答。这是我自己绘制的图,按从上到下,从左到右的顺序执行。如有问题请联系我修正。 要点: 1、执行顺序分为两步,类加载和初始化阶段。 2、因为静态变量和静态代码块…...

计算机网络性能指标概述:速率、带宽、时延等

在计算机网络中,性能指标是衡量网络效率和质量的重要参数。本文将综合三篇关于计算机网络性能指标的文章,详细介绍速率、带宽、吞吐量、时延、时延带宽积、往返时延(RTT) 和利用率的概念及其在网络中的应用。 1. 速率(…...

众所周知沃尔玛1P是怎么运营?

​​沃尔玛的1P模式,即第一方供应商模式,是其独特的采购策略。在这种模式下,供应商先将商品卖给沃尔玛,由沃尔玛负责库存管理和销售。沃尔玛通过强大的采购和物流能力控制库存,确保商品品质,为客户提供更加…...

【Linux】静态库的制作和使用详解

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …...

2.贪心算法.基础

2.贪心算法.基础 基础知识题目1.分发饼干2.摆动序列2.1.思路二:动态规划法 3.最大子序和4.买股票的最佳时机24.1.思路二:动态规划法4.2.买股票的最佳时机 5.跳跃游戏5.1.跳跃游戏2 6.K次取反后最大化的数组和7.加油站8.分发糖果 总结 基础知识 什么是贪…...

用Python轻松转换PDF为CSV

数据的可访问性和可操作性是数据管理的核心要素。PDF格式因其跨平台兼容性和版面固定性,在文档分享和打印方面表现出色,尤其适用于报表、调查结果等数据的存储。然而,PDF的非结构化特性限制了其在数据分析领域的应用。相比之下,CS…...

关于微信支付-商户平台:查询订单提示“查询失败:操作失败,请稍候重试”的分析

目录 引子 分析 应对 小结 引子 在开发和实施微信 JSAPI 支付的应用后,我们遇到了一些问题,订单的状态更新不正常,当然我们首先需要从自身寻找原因和完善解决问题的办法和方案。在支付的过程中,客户会给我们一些反馈&#xf…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...

boost::filesystem::path文件路径使用详解和示例

boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类&#xff0c;封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解&#xff0c;包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...

如何通过git命令查看项目连接的仓库地址?

要通过 Git 命令查看项目连接的仓库地址&#xff0c;您可以使用以下几种方法&#xff1a; 1. 查看所有远程仓库地址 使用 git remote -v 命令&#xff0c;它会显示项目中配置的所有远程仓库及其对应的 URL&#xff1a; git remote -v输出示例&#xff1a; origin https://…...