【Redis】Redis分片集群
【Redis】Redis分片集群
文章目录
- 【Redis】Redis分片集群
- 1. 搭建分片集群
- 1.1 分片集群结构
- 1.2 搭建分片集群
- 1.2.1 集群结构
- 1.2.2 准备实例和配置
- 1.2.3 启动
- 1.2.4 创建集群
- 1.2.5 测试
- 2. 散列插槽
- 2.1 总结
- 3. 集群伸缩
- 4. 故障转移
- 4.1 数据迁移
- 5. RedisTemplate访问分片集群
1. 搭建分片集群
1.1 分片集群结构
主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:
- 海量数据存储问题
- 高并发写的问题
使用分片集群可以解决上述问题,分片集群特征:
- 集群中有多个master,每个master保存不同数据
- 每个master都可以有多个slave节点
- master之间通过ping监测彼此健康状态
- 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

1.2 搭建分片集群
1.2.1 集群结构
分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点,结构如下:

这里我们会在同一台虚拟机中开启6个redis实例,模拟分片集群,信息如下:
| IP | PORT | 角色 |
|---|---|---|
| 192.168.150.101 | 7001 | master |
| 192.168.150.101 | 7002 | master |
| 192.168.150.101 | 7003 | master |
| 192.168.150.101 | 8001 | slave |
| 192.168.150.101 | 8002 | slave |
| 192.168.150.101 | 8003 | slave |
1.2.2 准备实例和配置
删除之前的7001、7002、7003这几个目录,重新创建出7001、7002、7003、8001、8002、8003目录:
# 进入/tmp目录
cd /tmp
# 删除旧的,避免配置干扰
rm -rf 7001 7002 7003
# 创建目录
mkdir 7001 7002 7003 8001 8002 8003
在/tmp下准备一个新的redis.conf文件,内容如下:
port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.150.101
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log
将这个文件拷贝到每个目录下:
# 进入/tmp目录
cd /tmp
# 执行拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf
修改每个目录下的redis.conf,将其中的6379修改为与所在目录一致:
# 进入/tmp目录
cd /tmp
# 修改配置文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf
1.2.3 启动
因为已经配置了后台启动模式,所以可以直接启动服务:
# 进入/tmp目录
cd /tmp
# 一键启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
通过ps查看状态:
ps -ef | grep redis
发现服务都已经正常启动:

如果要关闭所有进程,可以执行命令:
ps -ef | grep redis | awk '{print $2}' | xargs kill
或者(推荐这种方式):
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown
1.2.4 创建集群
虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。
我们需要执行命令来创建集群,在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中。
1)Redis5.0之前
Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。
# 安装依赖
yum -y install zlib ruby rubygems
gem install redis
然后通过命令来管理集群:
# 进入redis的src目录
cd /tmp/redis-6.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003
2)Redis5.0以后
我们使用的是Redis6.2.4版本,集群管理以及集成到了redis-cli中,格式如下:
redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003
命令说明:
redis-cli --cluster或者./redis-trib.rb:代表集群操作命令create:代表是创建集群--replicas 1或者--cluster-replicas 1:指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1)得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master
运行后的样子:

这里输入yes,则集群开始创建:

通过命令可以查看集群状态:
redis-cli -p 7001 cluster nodes

1.2.5 测试
尝试连接7001节点,存储一个数据:
# 连接
redis-cli -p 7001
# 存储数据
set num 123
# 读取数据
get num
# 再次存储
set a 1
结果悲剧了:

集群操作时,需要给redis-cli加上-c参数才可以(表示集群模式):
redis-cli -c -p 7001
这次可以了:

2. 散列插槽
Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上,查看集群信息时就能看到:

数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:
- key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分
- key中不包含“{}”,整个key都是有效部分
例如:key是num,那么就根据num计算,如果是{itcast}num,则根据itcast计算。计算方式是利用CRC16算法得到一个hash值,然后对16384取余,得到的结果就是slot值。

注:一个插槽并不代表一个key,一个插槽可以存储多个key。
2.1 总结
Redis如何判断某个key应该在哪个实例?
- 将16384个插槽分配到不同的实例。
- 根据key的有效部分计算哈希值,对16384取余。
- 余数作为插槽,寻找插槽所在实例即可。
如何将同一类数据固定的保存在同一个Redis实例中?
- 这一类数据使用相同的有效部分,例如key都以{typeId}为前缀。
3. 集群伸缩
redis-cli --cluster提供了很多操作集群的命令,可以通过下面方式查看:

比如,添加节点的命令:

4. 故障转移
当集群中有一个master宕机会发生什么呢?
- 首先是该实例与其它实例失去连接
- 然后是疑似宕机

- 最后是确定下线,自动提升一个slave为新的master:

4.1 数据迁移
利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移。其流程如下:

手动的Failover支持三种不同模式:
- 缺省:默认的流程,如图1~6步
- force:省略了对offset的一致性校验
- takeover:直接执行第5步,忽略数据一致性,忽略master状态和其他master的意见
5. RedisTemplate访问分片集群
RedisTemplate底层同样基于lettuce实现了分片集群的支持,而使用的步骤与哨兵模式基本一致:
- 引入redis的starter依赖
- 配置分片集群地址
- 配置读写分离
1)引依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2)配置
spring:redis:cluster:nodes: # 指定分片集群的每一个节点信息- 192.168.150.101:7001- 192.168.150.101:7002- 192.168.150.101:7003 - 192.168.150.101:8001- 192.168.150.101:8002- 192.168.150.101:8003
3)配置读写分离
//配置读写分离
@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}
相关文章:
【Redis】Redis分片集群
【Redis】Redis分片集群 文章目录【Redis】Redis分片集群1. 搭建分片集群1.1 分片集群结构1.2 搭建分片集群1.2.1 集群结构1.2.2 准备实例和配置1.2.3 启动1.2.4 创建集群1.2.5 测试2. 散列插槽2.1 总结3. 集群伸缩4. 故障转移4.1 数据迁移5. RedisTemplate访问分片集群1. 搭建…...
【Android笔记81】Android之RxJava的介绍及其使用
这篇文章,主要介绍Android之RxJava及其使用。 目录 一、RxJava响应式编程 1.1、RxJava介绍 1.2、RxJava常用方法 (1)引入RxJava依赖...
Pr 定格拍照动画
哈喽,各位小伙伴!今天我们来学习一下如何制作定格拍照动画? 新建序列 新建一个1920*1080的序列,将视频拖入序列中 选择定格画面右键—插入帧定格分段中间部分就会变成一张图片(图片时长可伸缩) 复制素…...
放弃node-sass,启用sass
在下载一个新项目时运行:npm run install 发现报错 npm uninstall 异常 Error: Could not find any Visual Studio installation to use 或是 ------------------------- You need to install the latest version of Visual Studio npm ERR! gyp ERR! find VS incl…...
力扣旋转字符串
🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言初阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:介绍字符串旋转,左旋,右旋即旋转结果. 金句分享: ✨好好干&…...
Java 代码组织机制
包 使用任何语言进行编程都有一个相同的问题,就是命名冲突。 包类似于计算机中的文件夹,正如文件放在文件夹中,类和接口放在包中,为便于组织,文件夹一般是一个层次结构,包也类似。 包有包名,…...
【剧前爆米花--爪哇岛寻宝】MySQL中索引和事务
作者:困了电视剧 专栏:《MySQL数据库》 文章分布:这是一篇关于Java中异常类的文章,在本篇文章中详细讲解了异常的使用逻辑和底层的执行过程,如有疏漏,欢迎大佬指正! 目录 索引 用法 底层逻辑…...
C++ 线程库
文章目录thread 创建mutexmutexrecursive_mutextimed_mutexlock_guard原子操作atomic条件变量condition_variable其他线程安全问题shared_ptr单例模式C 线程库是 C11 标准中引入的一个特性,它使得 C 在语言级别上支持多线程编程,不需要依赖第三方库或操作…...
python字典和集合——笔记
一、介绍 1、泛映射类型 collections.abc模块中有Mapping和MutableMapping这两个抽象基类,它们的作用是为dict和其他类似的类型定义形式接口(在Python 2.6到Python 3.2的版本中,这些类还不属于collections.abc模块,而是隶属于coll…...
TEX:显示文本
文章目录字体选择字体fontspec宏包根据字体形状控制字体为不同的字体形状选择不同的特征为不同的字体大小状选择不同的特征中文字体选择xeCJK宏包字体选择与设置XELATEX字体名查找字体集与符号居中与缩进居中单边调整两边缩进诗歌缩进列表itemize样例enumerate样例description样…...
SS-ELM-AE与S2-BLS相关论文阅读记录
Broad learning system for semi-supervised learning 摘要:本文认为,原始BLS采用的稀疏自编码器来生成特征节点是一种无监督学习方法,这意味着忽略了标注数据的一些信息,并且难以保证同类样本之间的相似性和相邻性,同…...
ESP32设备驱动-MAX6675冷端补偿K热电偶数字转换器
MAX6675冷端补偿K热电偶数字转换器 1、MAX6675介绍 MAX6675执行冷端补偿并将来自K型热电偶的信号数字化。 数据以 12 位分辨率、SPI™ 兼容的只读格式输出。 该转换器可将温度解析为 0.25C,读数高达 +1024C,并且在 0C 至 +700C 的温度范围内具有 8 LSB 的热电偶精度。 MAX…...
Python基础知识汇总(字符串四)
目录 字母的大小写转换 lower()方法 upper()方法 删除字符串中的空格和特殊字符 strip()方法...
C语言学习笔记——指针(初阶)
前言 指针可以说是C语言基础语法中最难的理解的知识之一,很多新手(包括我)刚接触指针时都觉得很难。在我之前发布的笔记中都穿插运用了指针,但是我一直没有专门出一期指针的笔记,这是因为我确实还有些细节至今还不太清…...
阿赵的MaxScript学习笔记分享十二《获取和导出各种数据》
大家好,我是阿赵,周日的早上继续分享MaxScript学习笔记,这是第十二篇,获取和导出各种数据 1、导出数据的目的 使用3DsMax建立3D模型后,很多时候需要输出模型到别的引擎去使用,常用的格式有Obj、FBX、SLT等…...
react-draggable实现拖拽详解
react-draggable属性常用属性属性列表事件列表举例首先安装 react-draggable实现移动希望小编写的能够帮助到你😘属性 常用属性 属性默认值介绍axisxhandle拖动的方向,可选值 x ,y,bothhandle无指定拖动handle的classposition无handle的位置࿰…...
01.进程和线程的区别
进程和线程的区别进程和线程是计算机中的两个核心概念,它们都是用来实现并发执行的方式,但是它们在实现并发的方式和资源管理方面有一些重要的区别。进程是一个程序的运行实例。每个进程都有自己的内存空间、代码、数据和系统资源(如文件描述…...
逻辑优化-rewrite
简介 逻辑综合中的rewrite算法是一种常见的优化算法,其主要作用是通过对逻辑电路的布尔函数进行等效变换,从而达到优化电路面积、时序和功耗等目的。本文将对rewrite算法进行详细介绍,并附带Verilog代码示例。 一、算法原理 rewrite算法的…...
文件传输与聊天系统设计
技术:Java等摘要:本文介绍了一种基于TCP/IP协议使用Socket技术实现的聊天室系统,包括私聊功能和文件传输功能,对系统的主要模块进行了分析,并对系统实现过程中遇到的关键性技术进行了阐述,最后对系统进行了…...
蓝桥杯第十四届校内赛(第三期) C/C++ B组
一、填空题 (一)最小的十六进制 问题描述 请找到一个大于 2022 的最小数,这个数转换成十六进制之后,所有的数位(不含前导 0)都为字母(A 到 F)。 请将这个数的十进制形式作…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
