Redis从入门到精通(十五)Redis分布式缓存(三)Redis分片集群的搭建和原理分析

文章目录

    • 前言
    • 5.4 分片集群
      • 5.4.1 搭建分片集群
      • 5.4.2 散列插槽
      • 5.4.3 集群伸缩
        • 5.4.3.1 需求分析
        • 5.4.3.2 创建新的Redis实例
        • 5.4.3.3 添加新节点到Redis集群
        • 5.4.3.4 转移插槽
      • 5.4.4 故障转移
        • 5.4.4.1 自动故障转移
        • 5.4.4.2 手动故障转移
      • 5.4.5 RedisTemplate
    • 5.5 小结

前言

Redis分布式缓存系列文章:

Redis从入门到精通(十三)Redis分布式缓存(一)RDB和AOF持久化、Redis主从集群的搭建与原理分析
Redis从入门到精通(十四)Redis分布式缓存(二)Redis哨兵集群的搭建和原理分析

5.4 分片集群

主从和哨兵可以解决高可用、高并发读的问题,但是依然有两个问题没有解决:海量数据存储问题、高并发写的问题。这两个问题可以通过分片集群来解决。

5.4.1 搭建分片集群

分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含1个slave节点,实际上master节点及其slave节点的数量可以更多。其结构如下:

在同一台虚拟机开启6个Redis实例,模拟分片集群,其信息如下:

IP端口角色
192.168.146.1288001master
192.168.146.1288002master
192.168.146.1288003master
192.168.146.1289001slave
192.168.146.1289002slave
192.168.146.1289003slave

搭建步骤如下:

  • 1)在/usr/local/redis_sharding中创建6个目录,名字分别是8001、8002、8003、9001、9002、9003:

  • 2)在6个目录下分别创建配置文件redis.conf,其内容如下(以8001为例,其余端口应与所在目录一致):
# /usr/local/redis_sharding/8001/redis.conf# 端口
port 8001
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /usr/local/redis_sharding/8001/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /usr/local/redis_sharding/8001
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.146.128
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /usr/local/redis_sharding/8001/run.log
  • 3)在6个目录下分别启动服务
/usr/local/bin/redis-server /usr/local/redis_sharding/8001/redis.conf
/usr/local/bin/redis-server /usr/local/redis_sharding/8002/redis.conf
/usr/local/bin/redis-server /usr/local/redis_sharding/8003/redis.conf
/usr/local/bin/redis-server /usr/local/redis_sharding/9001/redis.conf
/usr/local/bin/redis-server /usr/local/redis_sharding/9002/redis.conf
/usr/local/bin/redis-server /usr/local/redis_sharding/9003/redis.conf

6个实例启动后,其进程如下:

  • 4)创建集群

虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联,还需要执行命令来创建集群。

Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。案例使用的是Redis7.2.4版本,集群管理已经集成到了redis-cli中,格式如下:

redis-cli --cluster create --cluster-replicas 1 192.168.146.128:8001 192.168.146.128:8002 192.168.146.128:8003 192.168.146.128:9001 192.168.146.128:9002 192.168.146.128:
9003

命令说明:

  • redis-cli --cluster:集群操作命令

  • create:创建集群

  • --cluster-replicas 1:指定集群中每个master的slave节点个数为1,那么节点总数÷(replicas + 1)得到的就是master的数量。

    本例中即6÷(1 + 1)=3,因此上述命令列出的节点列表中的前3个就是master节点(8001、8002、8003),其他节点都是slave节点,随机分配到不同的master。

命令执行后:

可见,9002分配给了8001,9003分配给了8002,9001分配给了8003。输入yes继续执行:

集群创建完成。通过以下命令查看集群状态:

redis-cli -p 8001 cluster nodes

  • 5)测试

尝试连接8001节点,并存储一个数据:

redis-cli -p 8001127.0.0.1:8001> set age 21
OK
127.0.0.1:8001> get age
"21"
127.0.0.1:8001> set name aaa
(error) MOVED 5798 192.168.146.128:8002

可以发现,测试过程中出现了错误,提示我们要去8002节点操作。

实际上在进行集群操作时,需要给redis-cli命令加上-c参数:

127.0.0.1:8001> set name aaaaaa
-> Redirected to slot [5798] located at 192.168.146.128:8002
OK
192.168.146.128:8002> get name
"aaaaaa"

5.4.2 散列插槽

Redis会把每一个master节点映射到0~16383共16384个插槽上,在创建集群时就可以看到具体的分配情况:

Redis会根据Key值的有效部分计算插槽值(利用CRC16算法得到一个hash值,然后对16384取余,得到的结果就是插槽值),然后将数据存到插槽值对应的master节点上。 Key值的有效部分分两种情况:

  • Key中包含"{}",且“{}”中至少包含1个字符,则“{}”中的部分是有效部分;
  • key中不包含“{}”,整个key都是有效部分。

例如:

127.0.0.1:8001> set test aaa
-> Redirected to slot [6918] located at 192.168.146.128:8002
OK

在8001节点上执行set test aaa时,对test进行插槽值计算得到的结果是6918,因此要存储到8002节点上。

127.0.0.1:8003> get test
-> Redirected to slot [6918] located at 192.168.146.128:8002
"aaa"

在8003节点上执行get test时,也要根据插槽值去8002节点上查找。

5.4.3 集群伸缩

Redis提供了很多操作集群的命令,可以通过redis-cli --cluster help命令查看具体有哪些。

5.4.3.1 需求分析

现在有一个需求:向集群中添加一个新的master节点,并向其中存储test=bbb。

换句话说,就是添加一个新的master节点到集群中,并将部分插槽分配到给新的master节点。

5.4.3.2 创建新的Redis实例

/usr/local/redis_sharding目录下创建文件夹8004,并拷贝配置文件redis.conf,将其中的端口、目录等配置修改为8004:

启动8004节点:

/usr/local/bin/redis-server /usr/local/redis_sharding/8004/redis.conf

5.4.3.3 添加新节点到Redis集群

执行以下命令:

redis-cli --cluster add-node 192.168.146.128:8004 192.168.146.128:8001

查看集群状态:

redis-cli -p 8001 cluster nodes

如图,8004节点加入了集群,并且是一个master节点,但是其插槽数量为0,因此没有任何数据可以保存到8004节点上。

5.4.3.4 转移插槽

由前面的测试可知,Key值为"test"时其插槽值为6918,我们可以将5461~7461共2000个插槽由8002转移到8004,其命令格式为:

具体的操作步骤如下:

执行以下命令:

redis-cli --cluster reshard 192.168.146.128:8001

得到如下反馈:

询问要移动多少个插槽,我们计划是2000个:

询问要使用哪个节点来接收这些插槽,我们计划是8004节点,因此这里输入8004节点的ID:

询问要从哪个节点移动这些插槽,我们计划是8002节点,因此这里输入8002节点的ID:

如果这里没有输入8002节点的ID,而是输入all,则代表从全部master节点中各移动一部分。

然后再输入done,完成插槽移动的准备工作:

询问是否确认转移,输入yes,开始执行插槽的移动。移动完成后,再次查看集群的状态:

可见,插槽5461~7460以从8002节点移动到了8004节点。

下面进行测试:

127.0.0.1:8001> set test bbb
-> Redirected to slot [6918] located at 192.168.146.128:8004
OK

可见,数据已成功保存到8004节点,需求成功实现。

5.4.4 故障转移

目前,8001、8002、8003、8004都是master节点,如果其中一个实例宕机,会发生什么呢?

5.4.4.1 自动故障转移

执行以下命令,停止8002实例:

redis-cli -p 8002 shutdown

再查询集群状态,集群已识别到8002宕机,并把9001实例提升为master:

当8002再次启动时,自动成为slave节点:

5.4.4.2 手动故障转移

在某个slave节点上执行cluster failover命令,可以手动让集群中的某个master节点宕机,然后自己提升为master节点,实现无感知的数据迁移。

例如,在进行自动故障转移时,8002节点成为了slave节点。我们可以在8002节点上执行cluster failover命令,就可以重新夺回master的地位。

127.0.0.1:8002> cluster failover
OK

查看集群状态:

可见,8002节点重新夺回master地位,9001节点降为slave节点。

5.4.5 RedisTemplate

RedisTemplate底层同样基于lettuce实现了对Redis分片集群的支持,使用步骤与主从集群基本一致,只是在配置文件application.yml中略有差异:

# src/main/resources/application.ymlspring:redis:cluster:nodes:- 192.168.146.128:8001- 192.168.146.128:8002- 192.168.146.128:8003- 192.168.146.128:8004- 192.168.146.128:9001- 192.168.146.128:9002- 192.168.146.128:9003

下面做个简单的测试:调用/redis/set/test/ccc接口,由日志可知写操作由master节点8004实例完成,这个之前的测试结果是一致的:

5.5 小结

第5章到此就学习完毕了,本章的主题是:Redis分布式缓存。回顾一下本章的学习的内容:

(十三)RDB、AOF持久化的原理;Redis主从复制集群的搭建和原理分析。
(十四)Redis哨兵集群的搭建和原理分析。
(十五)Redis分片集群的搭建和原理分析。

更多内容请查阅分类专栏:Redis从入门到精通

感兴趣的读者还可以查阅我的另外几个专栏:

  • SpringBoot源码解读与原理分析(已完结)
  • MyBatis3源码深度解析(已完结)
  • 再探Java为面试赋能(持续更新中…)

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

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

相关文章

kali工具----枚举工具

一、枚举工具 枚举是一类程序,它允许用户从一个网络中收集某一类的所有相关信息。本节将介绍DNS枚举和SNMP枚举技术。DNS枚举可以收集本地所有DNS服务和相关条目。DNS枚举可以帮助用户收集目标组织的关键信息,如用户名、计算机名和IP地址等,…

【Qt】界面优化

目录 一、QSS 1.1 基本语法 1.2 QSS设置方法 1.2.1 指定控件样式设置 1.2.2 全局样式设置 1.2.3 从文件加载样式表 1.2.4 使用Qt Designer编辑样式 1.3 选择器 1.3.1 介绍 1.3.2 子控件选择器 1.3.3 伪类选择器 1.4 样式属性(盒模型) 1.5 代码示例(登录界面) 二、…

OSCP靶场--Banzai

OSCP靶场–Banzai 考点(ftp爆破 webshell上传web1访问403web2可以访问webshell反弹mysql udf提权) 1.nmap扫描 ## nmap扫描一定要使用 -p- 否则容易扫不全端口 ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC 192.168.158.56 -Pn -p- --min-rate 2500Starting Nmap 7.…

机器学习前导——PyCharm PyTorch Python3 机器学习

机器学习前导——PyCharm & pytorch & Python3 & 机器学习 文章目录 前言PyCharmPyTorchPython3机器学习联系 前言 这学期选了《机器学习》,第一次接触,对一些专有名词很陌生。 PyCharm PyCharm是一款由JetBrains开发的软件&#xff0c…

STM32 串口接收定长,不定长数据

本文为大家介绍如何使用 串口 接收定长 和 不定长 的数据。 文章目录 前言一、串口接收定长数据1. 函数介绍2.代码实现 二、串口接收不定长数据1.函数介绍2. 代码实现 三,两者回调函数的区别比较四,空闲中断的介绍总结 前言 一、串口接收定长数据 1. 函…

SpringBoot3 + Vue3 + Uniapp + uView + Elenment 实现动态二级分类以及二级分类的管理

SpringBoot3 Vue3 Uniapp uView Elenment 实现动态二级分类以及二级分类的管理 1. 效果展示1.1 前端显示效果1.2 后台管理一级分类1.3 后台管理二级分类 2. 后端代码2.1 GoodsCategoryController.java2.2.1 GoodsCategoryMapper.java2.2.2 GoodsCategorySonMapper.java2.3.…

Zookeeper的集群搭建和ZAB协议详解

Zookeeper的集群搭建 1)zk集群中的角色 Zookeeper集群中的节点有三个角色: Leader:处理集群的所有事务请求,集群中只有一个LeaderFollwoer:只能处理读请求,参与Leader选举Observer:只能处理读…

数仓维度建模

维度建模 数仓建模方法1. 范式建模法(Third Normal Form,3NF)2. 维度建模法(Dimensional Modeling)3. 实体建模法(Entity Modeling) 维度建模1. 事实表事实表种类事务事实表周期快照事实表累计快…

强大的数据分析计算软件:Stata 15 for Mac 激活版

Stata 15 for Mac是一款高级统计分析软件,具有强大的数据管理和数据提取工具。以下是其功能和特点的详细介绍: 软件下载:Stata 15 for Mac 激活版版下载 数据管理:Stata 15 for Mac支持多种数据库、数据格式和计算机语言&#xff…

如何在淘~宝接单和解决别人问题-java开发

如下这是一个连接:https://s.tb.cn/c.0vDtL3https://s.tb.cn/c.0vDtL3 解决各种问题。可付费咨询

【JAVA基础篇教学】第四篇:Java条件语句

博主打算从0-1讲解下java基础教学,今天教学第四篇: Java条件语句。 在Java中,条件语句用于根据不同的条件执行不同的代码块。Java提供了if、else if和else等关键字来实现条件判断。 一、if语句 if语句用于执行一个代码块,如果给…

TripoSR: Fast 3D Object Reconstruction from a Single Image 论文阅读

1 Abstract TripoSR的核心是一个基于变换器的架构,专为单图像3D重建设计。它接受单张RGB图像作为输入,并输出图像中物体的3D表示。TripoSR的核心包括:图像编码器、图像到三平面解码器和基于三平面的神经辐射场(NeRF)。…

【网络】服务器间FTP传输文件被限速问题的排查(未达最优解)

服务器间FTP传输文件被限速问题的排查 问题描述具体问题软硬件环境文件传输方式的2种策略FTP相关信息问题表现问题解决结论 发散探讨——基于此问题进行发散研究相关知识从FileZilla软件入手从Windows入手从Linux入手从协议入手Windows和Linux的文件共享,分别是使用…

状态模式:管理对象状态转换的动态策略

在软件开发中,状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式把与特定状态相关的行为局部化,并且将不同状态的行为分散到对应的状态类中,使得状态和行为可以独立变化。本文将详细介绍状态…

ORA-00600: internal error code, arguments: [krbcbp_9]

解决方案 1、清理过期 2、control_file_record_keep_time 修改 恢复时间窗口 RMAN (Recovery Manager) 是 Oracle 数据库的备份和恢复工具。在 RMAN 中,可以使用“恢复窗口”的概念来指定数据库可以恢复到的时间点。这个时间点是基于最近的完整备份或增量备份。 …

[Linux][进程控制][进程程序替换]详细解读

目录 1.进程创建1.fork函数初识2.fork函数返回值3.写时拷贝4.fork之后,父子进程代码共享5.fork常规用法6.fork调用失败的原因 2.进程终止0.进程终止时,操作系统做了什么?1.进程退出场景2.进程常见退出方法4 _exit函数(系统接口)4.exit函数(库…

html 引入vue Element ui 的方式

第一种&#xff1a;使用CDN的方式引入 <!--引入 element-ui 的样式&#xff0c;--> <link rel"stylesheet" href"https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 必须先引入vue&#xff0c; 后使用element-ui --> <…

【单片机毕业设计8-基于stm32c8t6的RFID校园门禁系统】

【单片机毕业设计8-基于stm32c8t6的RFID校园门禁系统】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇8基于stm32的RFID校园门禁系统 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功能介绍 -----------…

银行司库系统应用架构介绍

继国务院国资委印发了《关于推动中央企业加快司库体系建设进一步加强资金管理的意见》以及《关于中央企业加快建设世界一流财务管理体系的指导意见》&#xff0c;司库体系建设开始得到了更多重视。其中&#xff0c;作为改革风向标&#xff0c;央企数字化转型及司库建设对整个行…

Django Rest Framework的序列化和反序列化

DRF的序列化和反序列化 目录 DRF的序列化和反序列化Django传统序列化Django传统反序列化安装DRF序列化器serializers序列化反序列化反序列化保存instance和data CBV和APIView执行流程源码解析CBV源码分析APIView源码分析 DRF的Request解析魔法方法__getattr__ 什么是序列化&…