09 Redis之分布式系统(数据分区算法 + 系统搭建与集群操作)

6 分布式系统

Redis 分布式系统,官方称为 Redis Cluster,Redis 集群,其是 Redis 3.0 开始推出的分布式解决方案。其可以很好地解决不同 Redis 节点存放不同数据,并将用户请求方便地路由到不同 Redis 的问题。

什么是分布式系统?
每个集群中存储的数据不一致, 但又都为同一个系统服务.

在这里插入图片描述

6.1 数据分区算法

常见的数据分区规则有两大类:顺序分区与哈希分区。

6.1.1 顺序分区

顺序分区规则可以将数据按照某种顺序平均分配到不同的节点。不同的顺序方式,产生了不同的分区算法。例如,轮询分区算法、时间片轮转分区算法、数据块分区算法、业务主题分区算法等。
这些算法都比较简单

6.1.1.1 轮询分区算法

每产生一个数据,就依次分配到不同的节点。该算法适合于数据问题不确定的场景。

在数据总量非常庞大的情况下,每个节点中数据是很平均的。但生产者与数据节点间的连接要长时间保持。

6.1.1.2 时间片轮转分区算法

在某人固定长度的时间片内的数据都会分配到一个节点。时间片结束,再产生的数据就会被分配到下一个节点。这些节点会被依次轮转分配数据。

该算法可能会出现节点数据不平均的情况(因为每个时间片内产生的数据量可能是不同的)。但生产者与节点间的连接只需占用当前正在使用的这个就可以,其它连接使用完毕后就立即释放。

6.1.1.2 数据块分区算法

该算法要求提前确定整体数据总量

根据各个节点的存储能力,提前安排将某一块数据放置于某一节点。

6.1.2 哈希分区算法

哈希分区规则是充分利用数据的哈希值来完成分配,对数据哈希值的不同使用方式产生
了不同的哈希分区算法。
哈希分区算法相对较复杂

6.1.2.1 节点取模分区算法

该算法的前提是,每个节点都已分配好了一个唯一序号,对于 N 个节点的分布式系统,其序号范围为[0, N-1]。然后选取数据本身或可以代表数据特征的数据的一部分作为 key,先计算key的哈希值为hash(key) , 再用hash(key)与节点数量 N 取模,该计算结果即为该数据的存储节点的序号。

该算法最大的优点是简单,但其也存在较严重的不足。如果分布式系统扩容或缩容,已经存储过的数据需要根据新的节点数量 N 进行数据迁移,否则用户根据 key 是无法再找到原来的数据的。

生产中扩容一般采用翻倍扩容方式,以减少扩容时数据迁移的比例。

6.1.2.2 一致性哈希分区算法

在这里插入图片描述

6.1.2.3 虚拟槽分区算法

该算法首先虚拟出一个固定数量的整数集合,该集合中的每个整数称为一个 slot 槽。这个槽的数量一般是远远大于节点数量的。然后再将所有 slot 槽平均映射到各个节点之上。

例如,Redis 分布式系统中共虚拟了 16384 个 slot 槽,其范围为[0, 16383]。假设共有 3 个节点,那么 slot 槽与节点间的映射关系如下图所示:
在这里插入图片描述
而数据只与 slot 槽有关系,与节点没有直接关系。数据只通过其 key 的 hash(key)映射到slot 槽:slot = hash(key) % slotNums。

这也是该算法的一个优点,解耦了数据与节点,客户端无需维护节点,只需维护与 slot 槽的关系即可。 并且支持了负载均衡

Redis 数据分区采用的就是该算法。其计算槽点的公式为:slot = CRC16(key) &16383。其中即位与位之间"与运算" , CRC16()是一种带有校验功能的、具有良好分散功能的、特殊的 hash 算法函数。

我们都知道取模符号是% , 即原本公式应为 :slot = CRC16(key) % 16384


若要计算 a % b,且 b 是 2 的整数次幂,那么 a % b = a & (b-1) ,而位运算明显更快, 因此Redis中采用取模运算.


6.2 分布式系统搭建与运行

6.2.1 系统搭建

6.2.1.1 系统架构

下面要搭建的 Redis 分布式系统由 6 个节点构成,这 6 个节点的地址及角色分别如下表所示。一个 master 配备一个 slave,不过 master 与 slave 的配对关系,在系统搭建成功后会自动分配。
在这里插入图片描述

6.2.1.2 删除持久化文件

先将之前“Redis 主从集群”中在 Redis 安装目录下生成的 RDB 持久化文件 dump638*.conf与 AOF 持久化文件删除。

因为 Redis 分布式系统要求创建在一个空的数据库之上。
在这里插入图片描述

6.2.1.3 创建公共conf和各自的conf
  1. 先在 Redis 安装目录中 mkdir 一个新的目录 cluster-dis,用作分布式系统的工作目录。

  2. 再复制 2 个配置文件, 即原先 cluster 目录中的 redis.conf 与 redis6380.conf

在这里插入图片描述

  1. 修改公共conf文件
    A、 dir
    指定工作目录为前面创建的 cluster-dis 目录。持久化文件、节点配置文件将来都会在工作目录中自动生成。
    在这里插入图片描述
    B、 cluster-enabled
    该属性用于开启 Redis 的集群模式。
    在这里插入图片描述
    C、 cluster-config-file
    该属性用于指定“集群节点”的配置文件。该文件会在第一次节点启动时自动生成,其
    生成的路径是在 dir 属性指定的工作目录中。在集群节点信息发生变化后(如节点下线、故障转移等),节点会自动将集群状态信息保存到该配置文件中。
    不过,该属性在这里仍保持注释状态。在后面的每个节点单独的配置文件中配置它。
    在这里插入图片描述
    D、 cluster-node-timeout
    用于指定“集群节点”间通信的超时时间阈值,单位毫秒。
    在这里插入图片描述

  2. 修改单独的6380conf
    指定节点配置文件名 , 集群中节点发生变化时, 例如某个节点下线了, 故障转移, 都会记录到该文件中.
    在这里插入图片描述

  3. 复制剩余5个单独的conf文件
    使用 redis6380.conf 复制出 5 个配置文件 redis6381.conf、redis6382.conf、redis6383.conf、 redis6384.conf、redis6385.conf。
    在这里插入图片描述

  4. 修改 5 个配置文件
    修改 5 个配置文件 redis6381.conf、redis6382.conf、redis6383.conf、redis6384.conf、 redis6385.conf 的内容,将其中所有涉及的端口号全部替换为当前文件名称中的端口号。例如,下面的是 redis6381.conf 的配置文件内容。
    在这里插入图片描述

6.2.2 系统的启动和关闭

6.2.2.0 启停脚本

启动和停止的有点复杂, 不如直接做成一个脚本

需要注意的是, 该脚本仅用于学习, 因为生产环境下不会像现在一样搭建伪集群

在redis715/cluster-dis中新建这两个脚本
并且注意, 编写完成后还要增加权限 chmod 755 start-redis-cluster.sh

#!/bin/bash
rm -rf dump638*.rdb
rm -rf appendonlydir
rm -rf nodes-638*.confredis-server redis6380.conf
redis-server redis6381.conf
redis-server redis6382.conf
redis-server redis6383.conf
redis-server redis6384.conf
redis-server redis6385.confredis-cli --cluster create --cluster-replicas 1 192.168.177.129:6380 192.168.177.129:6381 192.168.177.129:6382 192.168.177.129:6383 192.168.177.129:6384 192.168.177.129:6385ps aux | grep redis
#!/bin/bashredis-cli -p 6380 shutdown
redis-cli -p 6381 shutdown
redis-cli -p 6382 shutdown
redis-cli -p 6383 shutdown
redis-cli -p 6384 shutdown
redis-cli -p 6385 shutdownps aux | grep redis
6.2.2.1 启动

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
第一部分: 已经使用虚拟槽分区算法进行数据分区
第二部分: 已为每一个master分配一个slave
第三部分: 三主三从redis的动态id/主机号端口号/槽分配/角色

在这里插入图片描述
在这里插入图片描述

6.2.2.2 关闭

对于分布式系统的关闭, 只需要逐个shutdown即可

在这里插入图片描述

6.3 集群操作

6.3.1 连接集群

在这里插入图片描述

6.3.2 写入数据

正常写入中, 限制一次只能为一个key, 但value不限

6.3.2.1 key单个写入

无论value 类型为String 还是List、Set 等集合类型,只要只有一个key , 那么在分布式系统中就没有问题。例如,

在这里插入图片描述

6.3.2.2 key批量操作

对一次写入多个 key 的操作,多个 key 会计算出多个 slot,多个 slot 可能会对应多个节点。

而由于一次只能写入一个节点,所以该操作会报错。

不过,系统也提供了一种对批量 key 的操作方案,为这些 key 指定一个统一的 group,让这个 group 作为计算 slot 的唯一值。
在这里插入图片描述

6.3.3 集群查询

在这里插入图片描述

6.3.4 故障转移

分布式系统中的某个 master 如果出现宕机,那么其相应的 slave 就会自动晋升为master。
如果原 master 又重新启动了,那么原 master 会自动变为新 master 的 slave。

6.3.4.1 模拟故障

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

6.3.4.2 故障服务能力

如果某 slot 范围对应节点的 master 与 slave 全部宕机,那么整个分布式系统是否还可以对外提供读服务,就取决于属性 cluster-require-full-coverage 的设置。
在这里插入图片描述

6.3.5 集群扩容

目标, 在原有系统的基础上, 在正在运行的分布式系统中添加两个新的节点:端口号为 6386 的节点为 master节点,其下会有一个端口号为 6387 的 slave 节点。

6.3.5.1 复制并修改两个单独的conf文件

使用 redis6380.conf 复制出 2 个配置文件 redis6386.conf 与 redis6387.conf,并修改其中的各处端口号为相应端口号,为集群扩容做前期准备。

6.3.5.2 启动系统与 2 个节点

在这里插入图片描述

6.3.5.3 添加master节点

在这里插入图片描述
在这里插入图片描述

6.3.5.4 分配slot

在这里插入图片描述
在这里插入图片描述
在QA交互中, 一共问了四个问题

  • 准备移动多少 slot?
  • 准备由谁来接收移动的 slot?
  • 选择要移动 slot 的源节点。
    有两种方案。
    A. 如果选择键入 all,则所有已存在 slot 的节点都将作为 slot 源节点,即该方案将进行一次 slot 全局大分配。
    B. 也可以选择其它部分节点作为 slot 源节点。此时将源节点的动态 ID 复制到这里,每个 ID 键入完毕后回车,然后再复制下一个 slot 源节点动态 ID,直至最后一个键入完毕回车后再键入 done。
    这里键入的是 all,进行全局大分配。
    在这里插入图片描述
    在这里插入图片描述
6.3.5.5 添加slave节点

在这里插入图片描述
在这里插入图片描述

6.3.6 集群缩容

对于缩容 , 删除master和slave的操作是不一样的.

下面要将 slave 节点 6387 与 master 节点 6386 从分布式系统中删除。
总体上分为三步

  1. 删除slave节点
  2. 处理master分配到的slot
  3. 删除master
6.3.6.1 删除slave节点

在这里插入图片描述

6.3.6.2 移除master节点所分配到的slot

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.3.6.3 删除master节点

在这里插入图片描述


6.4 分布式系统的限制

  • 仅支持 0 号数据库
  • 批量 key 操作支持有限
  • 分区仅限于 key
  • 事务支持有限
  • 不支持分级管理

6.5 Sentinel高可用集群启停脚本

上述都是演示普通的主从集群, 现在演示带有Sentinel的集群, 并且将启动和停止命令写入脚本

本示例采用三台Sentinel, 三台redis(一主两从)

bak是什么? 为什么要有bak?
之前演示Sentinel集群的时候看过, 只要一启动redis , 六台redis的conf文件就会多很多自动添加的内容, 但是这些内容的存在会导致下一次启动集群报错, 因此我们提前复制一份conf为conf.bak , 每次启动集群时都用conf.bak覆盖conf, 达到将conf文件复原的目的

然后再编写start-redis-sentinel脚本
在这里插入图片描述
不要忘了chmod

并且检查一下daemonsize为yes

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2809680.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

unity发布webGL压缩方式的gzip,使用nginx作为web服务器时的配置文件

unity发布webGL压缩方式的gzip,使用nginx作为web服务器时的配置文件 Unity版本是:2021.3 nginx的版本是:nginx-1.25.4 Unity发布webgl时的测试 设置压缩方式是gzip nginx配置文件 worker_processes 1;events {worker_connections 102…

Open CASCADE学习|提取面的内外环线

在Open CASCADE中,区分内环和外环主要基于面的参数域内环线方向的定义。具体来说,在面的参数域内,沿着环线正方向前进时,如果左侧为面内、右侧为面外,那么该环线被视为外环;反之,如果左侧为面外…

k8s Pod基础(概念,容器功能及分类,镜像拉取和容器重启策略)

目录 pod概念 Kubernetes设计Pod概念和特殊组成结构的用意 Pod内部结构: 网络共享: 存储共享: pause容器主要功能 pod创建方式 pod使用方式 pod分类 pod的容器分类 基础容器(infrastructure container)&…

【文生视频】Diffusion Transformer:OpenAI Sora 原理、Stable Diffusion 3 同源技术

文生视频 Diffusion Transformer:Sora 核心架构、Stable Diffusion 3 同源技术 提出背景输入输出生成流程变换器的引入Diffusion Transformer (DiT)架构Diffusion Transformer (DiT)总结 OpenAI Sora 设计思路阶段1: 数据准备和预处理阶段2: 架构设计阶段3: 输入数据…

Spring定时任务--手动执行定时任务(替代@Scheduled)

原文网址:Spring定时任务--手动执行定时任务(替代Scheduled) 简介 本文介绍SpringBoot如何手动执行定时任务。 之前此文已经介绍过,直接用Scheduled即可使用Spring的定时任务,但有时需要手动去提交定时任务&#xf…

springboot项目打成含crud操作的sdk集成到springboot启动引擎项目

一 sdk配置操作 1.1 结构 sdk项目目录中只有基础的service类以及mybatis操作数据库的相关文件,service类中包含查询数据库的方法。 说明: 1.2 sdk的pom打包配置 作为公共项目打成jar供其他项目引用,注意被引入的项目不能使用默认的maven…

随机分布模型

目录 前言 一、离散型随机变量 1.1 0-1分布 1.2 二项分布 1.3 帕斯卡分布 1.4 几何分布 1.5 超几何分布 1.6 泊松分布 二、连续型随机变量 2.1 均匀分布 2.2 指数分布 2.3 高斯分布/正态分布 2.4 分布(抽样分布) 2.5 t分布(抽样…

Vue | (六)使用Vue脚手架(下)| 尚硅谷Vue2.0+Vue3.0全套教程

文章目录 📚Vue 中的自定义事件🐇使用方法🐇案例练习🐇TodoList案例优化 📚全局事件总线🐇使用方法🐇案例练习🐇TodoList案例优化 📚消息订阅与发布🐇使用方法…

React18源码: Fiber树的初次创建过程图文详解

fiber树构造(初次创建) fiber树构造的2种情况: 1.初次创建 在React应用首次启动时,界面还没有渲染此时并不会进入对比过程,相当于直接构造一棵全新的树 2.对比更新 React应用启动后,界面已经渲染如果再次发…

微信小程序 --- 分包加载

分包加载 1. 什么是分包加载 什么是分包加载 ❓ 小程序的代码通常是由许多页面、组件以及资源等组成,随着小程序功能的增加,代码量也会逐渐增加,体积过大就会导致用户打开速度变慢,影响用户的使用体验。 分包加载是一种小程序…

遗传算法(Genetic Algorithm,GA)求解不闭合多旅行商问题(提供MATLAB代码)

一、遗传算法(GA)介绍 遗传算法(Genetic Algorithm,GA)是一种模拟自然界生物进化过程的优化算法。它通过模拟生物的遗传、变异和选择等机制,来搜索问题的最优解。 遗传算法的基本思想是通过对候选解进行编…

stable diffusion学习笔记 手部修复

图片手部修复原理 某张图片在生成后,仅有手部表现不符合预期(多指,畸形等)。这种情况下我们通常使用【局部重绘】的方式对该图片的手部进行【图生图】操作,重新绘制手部区域。 但是仅采用重绘的方式也很难保证生成的…

笔记本如何录屏?很简单,我来告诉你

“最近遇到了一些工作上的问题,需要录制一些会议和讨论的内容,以便于后续的整理和回顾。但是,我没有使用过笔记本进行录屏,不知道该如何操作。大家有没有简单易懂的笔记本录屏指南,教教我!” 在当今数字化…

选择VR全景行业,需要了解哪些内容?

近年来,随着虚拟现实、增强现实等技术的持续发展,VR全景消费市场得以稳步扩张。其次,元宇宙行业的高速发展,也在进一步拉动VR全景技术的持续进步,带动VR产业的高质量发展。作为一种战略性的新兴产业,国家和…

多重网格(Multigrid Method)-4

代数多重网格法简介(Algebraic Multigrid) 可以理解为对细网格上的方程,先使用光滑方法(Gm)进行迭代得到一个初始解,然后将这个初始解的残差乘限制算子转化到粗网格上得到粗网格的右端向量,再在…

流浪动物救助平台:Java开发的实践与思考

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…

03_第三章 JavaScript(数据类型和运算符,流程控制和函数,JS的对象和JSON,事件的绑定,BOM编程,DOM编程,正则表达式)

文章目录 第三章 JavaScript一 JS简介1.1 JS起源JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。但是面向对象的三大特性:『封装』、『继承』、『多态』中,JavaScript能够实现封装,可以模…

第十篇【传奇开心果系列】Python的文本和语音相互转换库技术点案例示例:Microsoft Azure开发语音翻译应用程序经典案例

传奇开心果博文系列 系列博文目录Python的文本和语音相互转换库技术点案例示例系列 博文目录前言一、雏形示例代码二、扩展思路介绍三、Azure多语种支持示例代码四、Azure实时对话模式示例代码五、Azure自定义翻译模型示例代码六、Azure语音合成示例代码七、Azure用户界面优化示…

多输入回归预测|WOA-CNN|鲸鱼算法优化的卷积神经网络回归预测(Matlab)

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、部分程序: 四、完整程序数据下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matalb平台编译…

【摸鱼日常】使用Docker部署2048小游戏

一、本次实践介绍 ​1. 本次实践简介 本次实践部署环境为个人测试环境,快速使用docker部署2048小游戏。 rootWellDone:/home/goodjob# uname -aLinux WellDone 6.5.0-14-generic #14~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon Nov 20 18:15:30 UTC 2 x86_64 x86_64…