Redis学习【11】之分布式系统

news2024/11/19 3:45:20

文章目录

  • 一 数据分区算法
    • 1.1 顺序分区
      • 1.1.1 轮询分区算法
      • 1.1.2 时间片轮转分区算法
      • 1.1.3 数据块分区算法
      • 1.1.4 业务主题分区算法
    • 1.2 哈希分区
      • 1.2.1 节点取模分区算法
      • 1.2.2 一致性哈希分区算法
      • 1.2.3 虚拟槽分区算法
  • 二 分布式系统环境搭建与运行
    • 2.1 系统搭建
      • 2.1.1 系统架构
      • 2.1.2 删除持久化文件
      • 2.1.3 创建目录
      • 2.1.4 复制 2 个配置文件
      • 2.1.5 修改 redis.conf
      • 2.1.6 修改 redis6380.conf
      • 2.1.7 复制 5 个配置文件
      • 2.1.8 修改 5 个配置文件
    • 2.2 系统启动与关闭
      • 2.2.1 启动节点
      • 2.2.2 创建分布式系统
      • 2.2.3 测试系统
      • 2.2.4 关闭系统
  • 三 集群操作
    • 3.1 连接集群
    • 3.2 写入数据
      • 3.2.1 key 单个写入&批量操作
    • 3.3 集群查询
      • 3.3.1 查询 key 的 slot
      • 3.3.2 查询 slot 中 key 的数量
      • 3.3.3 查询 slot 中的 key
    • 3.4 故障转移
      • 3.4.1 故障转移
      • 3.4.2 全覆盖需求
  • 四 分布式系统的限制

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

一 数据分区算法

  • 分布式数据库系统会根据不同的数据分区算法,将数据分散存储到不同的数据库服务器节点上,每个节点管理着整个数据集合中的一个子集。
    在这里插入图片描述

1.1 顺序分区

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

1.1.1 轮询分区算法

  • 每产生一个数据,就依次分配到不同的节点。该算法适合于数据问题不确定的场景。
  • 优点:在数据总量非常庞大的情况下,每个节点中数据是很平均的
  • 缺点:生产者与数据节点间的连接要长时间保持

1.1.2 时间片轮转分区算法

  • 在某固定长度的时间片内的数据都会分配到一个节点。时间片结束,再产生的数据就会被分配到下一个节点。这些节点会被依次轮转分配数据。
  • 优点:生产者与节点间的连接只需占用当前正在使用的,其它连接使用完毕后就立即释放。
  • 缺点:该算法可能会出现节点数据不平均的情况(因为每个时间片内产生的数据量可能是不同的)。

1.1.3 数据块分区算法

  • 在整体数据总量确定的情况下,根据各个节点的存储能力,可以将连接的某一整块数据分配到某一节点

1.1.4 业务主题分区算法

  • 数据可根据不同的业务主题,分配到不同的节点

1.2 哈希分区

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

1.2.1 节点取模分区算法

  • 该算法的前提是,每个节点都已分配好了一个唯一序号,对于 N N N 个节点的分布式系统,其序号范围为 [ 0 , N − 1 ] [0, N-1] [0,N1]。然后选取数据本身或可以代表数据特征的数据的一部分作为 k e y key key,计算 h a s h ( k e y ) hash(key) hash(key)与节点数量 N N N的模,该计算结果即为该数据的存储节点的序号。
  • 该算法最大的优点是简单,但缺点是其也存在较严重的不足。如果分布式系统扩容或缩容,已经存储过的数据需要根据新的节点数量 N N N进行数据迁移,否则用户根据 key 是无法再找到原来的数据的。生产中扩容一般采用翻倍扩容方式,以减少扩容时数据迁移的比例。

1.2.2 一致性哈希分区算法

  • 一致性 h a s h hash hash 算法通过一个叫作一致性 h a s h hash hash环的数据结构实现。这个环的起点是 0 0 0,终点是 2 3 2 − 1 2^32-1 2321,并且起点与终点重合。环中间的整数按逆/顺时针分布,故这个环的整数分布范围是 [ 0 , 2 3 2 − 1 ] [0, 2^32-1] [0,2321]
    在这里插入图片描述
    在这里插入图片描述

  • 上图中存在四个对象 o 1 、 o 2 、 o 3 、 o 4 o1、o2、o3、o4 o1o2o3o4,分别代表四个待分配的数据,红色方块是这四个数据的 h a s h ( o ) hash(o) hash(o)在 Hash 环中的落点。同时,图上还存在三个节点 m 0 、 m 1 、 m 2 m_0、m_1、m_2 m0m1m2的主机结点,绿色圆圈是这三节点的 h a s h ( m ) hash(m) hash(m)在 Hash 环中的落点。

  • 现在要为数据分配其要存储的节点。该数据对象的 hash(o) 按照逆/顺时针方向距离哪个节点的 hash(m)最近,就将该数据存储在哪个节点。这样就会形成上图所示的分配结果。

  • 该算法的优点是:节点的扩容与缩容,仅对按照逆/顺时针方向距离该节点最近的节点有影响,对其它节点无影响。

    • 如下图:在原来的基础上添加 m 3 m_3 m3的主机结点,对 o 3 o_3 o3的数据进行迁移
      在这里插入图片描述
  • 当节点数量较少时,容易形成数据倾斜问题,且节点变化影响的节点数量占比较大,即影响的数据量较大。所以该方式不适合数据节点较少的场景。
    在这里插入图片描述

1.2.3 虚拟槽分区算法

  • 该算法首先虚拟出一个固定数量的整数集合,该集合中的每个整数称为一个 slot 槽。这个槽的数量一般是远远大于节点数量的,然后再将所有 slot 槽平均映射到各个节点之上。Redis 分布式系统中共虚拟了 16384 16384 16384 个 slot 槽,其范围为 [ 0 , 16383 ] [0, 16383] [0,16383]
  • 例如,假设共有 3 个节点,那么 slot 槽与节点间的映射关系如下图所示:
    在这里插入图片描述
  • 而数据只与 slot 槽有关系,与节点没有直接关系。数据只通过其 key 的 hash(key)映射到slot 槽: s l o t = h a s h ( k e y ) % s l o t N u m s slot=hash(key) \% slotNums slot=hash(key)%slotNums。该算法的一个优点,解耦了数据与节点,客户端无需维护节点,只需维护与 slot 槽的关系即可。
  • Redis 数据分区采用的就是该算法。其计算槽点的公式为: s l o t = C R C 16 ( k e y ) % 16384 slot = CRC16(key) \% 16384 slot=CRC16(key)%16384 C R C 16 ( ) CRC16() CRC16()是一种带有校验功能的、具有良好分散功能的、特殊的 hash 算法函数。
  • 其实 Redis中计算槽点的公式不是上面的那个,而是:KaTeX parse error: Expected 'EOF', got '&' at position 19: …t = CRC16(key) &̲16383。若要计算 a % b a\%b a%b,如果 b 是 2 的整数次幂,那么 KaTeX parse error: Expected 'EOF', got '&' at position 12: a \% b = a &̲ (b-1)

二 分布式系统环境搭建与运行

2.1 系统搭建

  • 这部分的内容,作者主要讲解操作和原理,所以对代码及操作的的实际操作结果展示内容会减少,但主要的步骤还是会保留下来!

2.1.1 系统架构

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

2.1.2 删除持久化文件

  • 先将之前“Redis 主从集群”中在 Redis 安装目录下生成的 RDB 持久化文件 dump638*.confAOF 持久化文件删除。因为 Redis 分布式系统要求创建在一个空的数据库之上。注意,AOF持久化文件全部在 appendonlydir 目录中。
# 在目录redis下操作
rm -rf dump638*.rdb appendonlydir

2.1.3 创建目录

  • 在 Redis 安装目录中 mkdir 一个新的目录 cluster-dis,用作分布式系统的工作目录。
# 在目录redis下操作
mkdir cluster-dis

2.1.4 复制 2 个配置文件

  • 将 cluster 目录中的 redis.conf redis6380.conf 文件复制到 cluster-dis 目录
# 在cluster-dis的操作命令
cp ../cluster/redisconf ./
cp ../cluster/redis6380.conf ./

2.1.5 修改 redis.conf

  • 对于 redis.conf 配置文件,主要涉及到以下三个四个属性:
  1. dir
    在这里插入图片描述
    • 指定工作目录为前面创建的 cluster-dis 目录。持久化文件、节点配置文件将来都会在工作目录中自动生成。
  2. cluster-enabled
    在这里插入图片描述
    • 该属性用于开启 Redis 的集群模式
  3. cluster-config-file
    在这里插入图片描述
    • 该属性用于指定“集群节点”的配置文件。该文件会在第一次节点启动时自动生成,其生成的路径是在 dir 属性指定的工作目录中。在集群节点信息发生变化后(如节点下线、故障转移等),节点会自动将集群状态信息保存到该配置文件中。
  4. cluster-node-timeout
    在这里插入图片描述
    • 用于指定“集群节点”间通信的超时时间阈值,单位毫秒

2.1.6 修改 redis6380.conf

include redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump6380.rdb
appendfilename appendonly6380.aof
replica-priority 90
cluster-config-file nodes-6380.conf

2.1.7 复制 5 个配置文件

  • 使用 redis6380.conf 复制出 5 个配置文件 redis6381.conf、redis6382.conf、redis6383.conf、redis6384.conf、redis6385.conf
cp redis6380.conf redis6381.conf
cp redis6380.conf redis6382.conf
cp redis6380.conf redis6383.conf
cp redis6380.conf redis6384.conf
cp redis6380.conf redis6385.conf

2.1.8 修改 5 个配置文件

  • 修改 5 个配置文件 redis6381.conf、redis6382.conf、redis6383.conf、redis6384.conf、redis6385.conf 的内容,将其中所有涉及的端口号全部替换为当前文件名称中的端口号。

2.2 系统启动与关闭

2.2.1 启动节点

  • 第一种方式:手动启动
    • 启动所有 Redis 节点
    redis-server redis6380.conf
    redis-server redis6381.conf
    redis-server redis6382.conf
    redis-server redis6383.conf
    redis-server redis6384.conf
    redis-server redis6385.conf
    
  • 第二种:编写脚本文件启动【该方法在伪集群中使用方便,真实生产环境不适用】
    1. 在cluster-dis中,创建文件start-redis-cluster.sh
    vim start-redis-cluster.sh
    
      2. 编写内容如下
    
    #!/bin/bash
    rm -rf dump638*.rdb
    rm -rf appendonlydir
    rm -rf nodes-638*.conf
    redis-server redis6380.conf
    redis-server redis6381.conf
    redis-server redis6382.conf
    redis-server redis6383.conf
    redis-server redis6384.conf
    redis-server redis6385.conf
    
    1. 修改文件的权限
    chmod 755 start-redis-cluster.sh
    
    1. 运行文件
    ./start-redis-cluster.sh
    

2.2.2 创建分布式系统

  • 6 个节点启动后,它们仍是 6 个独立的 Redis,通过 redis-cli --cluster create 命令可将 6个节点创建了一个分布式系统。
    在这里插入图片描述
  • 该命令用于将指定的 6 个节点连接为一个分布式系统。--cluster replicas 1 指定每个master 会带有一个 slave 作为副本。
    在这里插入图片描述
  • 输入 yes 后回车,系统就会将以上显示的动态配置信息真正的应用到节点上,然后就可可看到如下日志
    在这里插入图片描述

2.2.3 测试系统

  • 通过 cluster nodes 命令可以查看到系统中各节点的关系及连接情况。能看到每个节点给出 connected,就说明分布式系统已经成功搭建。
redis-cli -c -p 6380 cluster nodes
  • 对于客户端连接命令 redis-cli,需要注意两点:
    • redis-cli 带有-c 参数,表示这是要连接一个“集群”,而非是一个节点。
    • 端口号可以使用 6 个中的任意一个。

2.2.4 关闭系统

  • 对于分布式系统的关闭,只需将各个节点 shutdown 即可
  • 方法一:手动关闭
redis-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 shutdown
  • 方法二:配置文件关闭
    1. 创建执行文件shutdown-redis-cluster.sh
    2. 编写一下内容
    #!/bin/bash
    redis-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 shutdown
    # 查看关闭的效果指令
    ps aux|grep redis
    
    1. 修改文件权限
    chmode 755 shutdown-redis-cluster.sh
    

三 集群操作

3.1 连接集群

  • 与之前单机连接相比的唯一区别就是增加了参数-c。
    redis-cli -c -p 6380
    

3.2 写入数据

3.2.1 key 单个写入&批量操作

  • 无论 value 类型为 String 还是 List、Set 等集合类型,只要写入时操作的是一个 key,那么在分布式系统中就没有问题。
  • 对一次写入多个 key 的操作,由于多个 key 会计算出多个 slot,多个 slot 可能会对应多个节点。而由于一次只能写入一个节点,所以该操作会报错。系统提供了一种对批量 key 的操作方案,为这些 key 指定一个统一的 group,让这个 group 作为计算 slot 的唯一值。
    • 如:
    mset name{emp} ming game{emp} kissking 
    

3.3 集群查询

3.3.1 查询 key 的 slot

  • 通过 cluster keyslot 可以查询指定 key 的slot
    cluster keyslot xxx
    

3.3.2 查询 slot 中 key 的数量

  • 通过cluster countkeysinslot命令可以查看到指定slot所包含的 key 的个数
cluster countkeysinslot xxx

3.3.3 查询 slot 中的 key

  • 通过 cluster getkeysinslot 命令可以查看到指定 slot 所包含的 key
cluster getkeysinslot xxx num

3.4 故障转移

3.4.1 故障转移

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

3.4.2 全覆盖需求

  • 如果某 slot 范围对应节点的 master 与 slave 全部宕机,那么整个分布式系统是否还可以对外提供读服务,就取决于属性 cluster-require-full-coverage 的设置。
    在这里插入图片描述
  • 该属性有两种取值:
    • yes:默认值。要求所有 slot 节点必须全覆盖的情况下系统才能运行。
    • no:slot 节点不全的情况下系统也可以提供查询服务。

四 分布式系统的限制

  • Redis 的分布式系统存在一些使用限制:
    • 仅支持 0 号数据库
    • 批量 key 操作支持有限:需要指定GROUP不能跨槽存放
    • 分区仅限于 key:即使VALUE是集合,也不能存放到不同的机器上。
    • 事务支持有限:在一个主机上有作用,槽点分到不同主机上不起作用。
    • 不支持分级管理:不支持分极管理,只有 masterslave

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

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

相关文章

物理层的概述(可以说是对王道计算机网络的笔记)

目录前言物理层概述基本概念数据通信基础知识数据通信相关术语三种通信方式两种传输方式码元,速率、波特、带宽**练习题**奈氏准则和香农定理奈氏准则(奈奎斯特定理)香浓定理结尾前言 本章内容讲述了物理层的概念,也是我上个星期上课的内容&…

现代检测技术-期末复习

文章目录差动结构的优点偏差/零位/微差法的应用偏差法测量零位法测量微差法测量格罗布斯准则(作业题)最小二乘法自相关/互相关算法的应用(教材和课件案例)自相关性分析互相关分析:电子计数器测频法(作业题&…

第53章 短信验证服务和登录的前端定义实现

1 向src\router\index.js添加定义 { path: /LoginSms, name: 手机号登录, component: () > import(../views/LoginSmsView.vue) }, { path: /Users/Register, name: 用户注册, component: () > import(../views/Users/RegisterView.vue), }, 2 向src\common\http.api.js添…

Javascript借用原型对象继承父类型方法

借用原型对象继承父类型方法 目的: 儿子继承父类属性和方法,父类之后新增的方法不会被儿子继承。 前言: 先理解一个问题: Son.prototype Father.prototype; 这一操作相当于把Son的原型对象指向Father。 意味着Son的prototype的地址与Fa…

Vue基础学习 v-指令(2) 本地应用(记事本)

v-bind 设置元素的属性&#xff08;比如&#xff1a;src&#xff0c;title&#xff0c;class&#xff09; v-bind:属性名值 <div id"app"><img v-bind:src"imgSrc" alt"" v-bind:title"imgTitle"></div><scrip…

数学建模(一):LP 问题

文章目录数学建模&#xff08;一&#xff09;&#xff1a;LP 问题一、 MATLAB求解二、 Python 求解数学建模&#xff08;一&#xff09;&#xff1a;LP 问题 在人们的生产实践中&#xff0c;经常会遇到如何利用现有资源来安排生产&#xff0c;以取得最大经济效益的问题。此类问…

关于分布式事务的理解

关于分布式事务的理解 分布式事务之前先简单介绍下介于本地事务和分布式事务之间的两个事务&#xff1a;全局事务&#xff08;Global Transactions&#xff09;和共享事务&#xff08;Share Transactions&#xff09;的原理与实现。 先给全局事务做个限定&#xff1a;一种适用…

JVM运行时数据区划分

Java内存空间 内存是非常重要的系统资源&#xff0c;是硬盘和cpu的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM内存布局规定了JAVA在运行过程中内存申请、分配、管理的策略&#xff0c;保证了JVM的高效稳定运行。不同的jvm对于内存的划分方式和管理机…

使用secure crt连接ensp中虚拟设备

0 前言 ensp中虚拟设备如路由器、防火墙等本质上是 virtualbox中运行的虚机&#xff0c;因此可通过 telnet 连接 127.0.0.1 及对应端口方式连接到ensp中设备&#xff1b; 1 连接方法 1.1 查看设备所监听端口 设备图标上&#xff0c;右键 设置 点击 配置&#xff0c;可查看到…

UGUI 上使用 Particle System 支持 Sorting Layer 排序渲染

UGUI 上使用 Particle System 支持 Sorting Layer 排序渲染 Unity 中 Particle System 在 UGUI 上是可以根据 Sorting Layer 以及 Order in Layer 和 UI 组件(Image、Text等) 排序渲染的 Layer 值高的能够遮挡 Layer 值低的 组件 开发中会有这样的需求&#xff1a;要求 Part…

CAD异形图形的绘制

这个CAD图形的难点在于如何画角度98长165的斜线&#xff0c;剩下的图形就很好画了&#xff0c;那么用到的命令有圆、直线、导圆角、偏移等多个CAD命令的结合 目标对象 操作步骤 1.先使用直线命令画相交于A点的两条辅助线段&#xff0c;然后以A点为圆心画半径47.5和直径65的圆…

Java -数据结构,【优先级队列 / 堆】

一、二叉树的顺序存储 在前面我们已经讲了二叉树的链式存储&#xff0c;就是一棵树的左孩子和右孩子 而现在讲的是&#xff1a;顺序存储一棵二叉树。 1.1、存储方式 使用数组保存二叉树结构&#xff0c;方式即将二叉树用层序遍历方式放入数组中。 一般只适合表示完全二叉树&a…

真实需求和梦想实现满足

多少的时光和岁月中都不曾认真系统的深度思考自己的真实需求和欲望之间是否一致&#xff0c;随着时间的流逝才发现自己追求的是一场空&#xff0c;自己的真实需求并不是苦苦追求的东西&#xff0c;这也是当梦想照进现实&#xff01;欲望是无善无恶的&#xff0c;不必为了满足自…

性能测试——LoadRunner: virtual user generator的使用

LoadRunner 在安装时取消勾选指定LoadRunner代理将要使用的证书&#xff0c;安装完成后会显示下面三个软件 Vitual User Generator&#xff1a;生成性能测试脚本Controller&#xff1a;创建测试场景&#xff0c;运行测试脚本&#xff0c;监控运行&#xff0c;收集到运行的数…

Spring——AOP是什么?如何使用?

一、什么是AOP&#xff1f;在不修改源代码的情况下 增加功能二、底层是什么&#xff1f;动态代理aop是IOC的一个扩展功能&#xff0c;现有IOC&#xff0c;再有AOP&#xff0c;只是在IOC的整个流程中新增的一个扩展点而已&#xff1a;BeanPostProcessorbean的创建过程中有一个步…

【JAVA】List接口

&#x1f3c6;今日学习目标&#xff1a;List接口 &#x1f603;创作者&#xff1a;颜颜yan_ ✨个人主页&#xff1a;颜颜yan_的个人主页 ⏰本期期数&#xff1a;第四期 &#x1f389;专栏系列&#xff1a;JAVA List接口一、ArrayList二、LinkedList总结一、ArrayList ArrayLis…

python完美实现一个自己的音乐服务器

最近发现&#xff0c;经常用的网易云音乐&#xff0c;有很多歌曲下架了&#xff0c;能听的越来越少了&#xff1b;歌单里的一些歌曲&#xff0c;现在要开通 VIP 才能听了。其实自己常听的歌曲不是很多&#xff0c;现在却有很多听不了了。怎么办呢&#xff0c;付费吗&#xff1f…

Python进阶-----面对对象5.0(面对对象三大特征之--多态)

目录 前言&#xff1a; 多态 习题 前言&#xff1a; 上一期讲了Python面对对象中的继承&#xff0c;而今天讲的是多态&#xff0c;其实多态跟继承是紧密相关的&#xff0c;换句话说多态是继承的一种表现形式&#xff0c;下面就一起来看看吧&#xff01;&#xff08;上一期链…

性价比高的骨传导蓝牙耳机,推荐几款性能高的骨传导耳机

​骨传导耳机&#xff0c;顾名思义是一种声音传递方式&#xff0c;利用头骨作为震动传导发声。不像一般耳机那样通过外耳或内耳传递声音。声音由耳部传播到头后产生振动刺激颅脑内听觉中枢引起听觉。因此是一种非入耳式的声音传播方式。而在选购过程中&#xff0c;对于价格、功…

自动驾驶目标检测项目实战(二)—基于Faster-RCNN的交通标志检测

自动驾驶目标检测项目实战——基于Faster-RCNN的交通标志检测 目前目标检测算法有很多&#xff0c;流行的就有faster-rnn和yolov&#xff0c;本文使用了faster-rnn框架进行训练&#xff0c;效果还不错&#xff0c;准确率&#xff0c;当然也可以使用更高版本的Yolov进行实战。本…