Redis集群(Cluster)

news2024/10/7 10:12:46

Redis集群(Cluster)

单台redis容量限制,如何进行扩容?继续加内存、加硬件么?单台redis并发写量太大有性能瓶颈,如何解决?redis3.0中提供了集群可以解决这些问题。

redis集群是对redis的水平扩容,即启动N个redis节点,将整个数据分布存储在这个N个节点中,每个节点存储总数据的1/N。

如下图:由3台master和3台slave组成的redis集群,每台master承接客户端三分之一请求和写入的数据,当master挂掉后,slave会自动替代master,做到高可用。

在这里插入图片描述

集群如何配置,示例演示

需求:配置3主3从集群

配置一个3主3从的集群,每个主下面挂一个slave,master挂掉后,slave会被提升为master。

为了方便,我们在一台机器上进行模拟,我的机器ip是:192.168.1.100,通过端口来区分6个不同的节点,配置信息如下:

在这里插入图片描述

创建案例工作目录:cluster

#创建/opt/cluster目录,本次所有操作,均在cluster目录进行。
# 方便演示,停止所有的redis
kill -9 redis的id
mkdir /opt/cluster
cd /opt/cluster/

将redis.conf复制到cluster目录

#我测试的Linux环境,redis.conf在/usr/local/redis/redis-6.2.1/中
cp /usr/local/redis/redis-6.2.1/redis.conf /opt/cluster/

创建master1的配置文件:redis-6379.conf

#在/opt/cluster目录创建redis-6379.conf文件,内容如下
#注意192.168.1.100是我测试机器的ip,大家需要替换为自己的
include /opt/cluster/redis.conf
daemonize yes
bind 192.168.1.100
dir /opt/cluster/
port 6379
dbfilename dump_6379.rdb
pidfile /var/run/redis_6379.pid
logfile "./6379.log"
cluster-enabled yes
cluster-config-file node-6379.conf
cluster-node-timeout 15000

创建master2的配置文件:redis-6380.conf

#在/opt/cluster目录创建redis-6380.conf文件,和上面master的类似,只是将6379换成6380了
include /opt/cluster/redis.conf
daemonize yes
bind 192.168.1.100
dir /opt/cluster/
port 6380
dbfilename dump_6380.rdb
pidfile /var/run/redis_6380.pid
logfile "./6380.log"
cluster-enabled yes
cluster-config-file node-6380.conf
cluster-node-timeout 15000

创建master3的配置文件:redis-6381.conf

#在/opt/cluster目录创建redis-6381.conf文件
include /opt/cluster/redis.conf
daemonize yes
bind 192.168.1.100
dir /opt/cluster/
port 6381
dbfilename dump_6381.rdb
pidfile /var/run/redis_6381.pid
logfile "./6381.log"
cluster-enabled yes
cluster-config-file node-6381.conf
cluster-node-timeout 15000

创建slave1的配置文件:redis-6389.conf

#在/opt/cluster目录创建redis-6389.conf文件,内容如下
include /opt/cluster/redis.conf
daemonize yes
bind 192.168.1.100
dir /opt/cluster/
port 6389
dbfilename dump_6389.rdb
pidfile /var/run/redis_6389.pid
logfile "./6389.log"
cluster-enabled yes
cluster-config-file node-6389.conf
cluster-node-timeout 15000

创建slave2的配置文件:redis-6390.conf

#在/opt/cluster目录创建redis-6390.conf文件,内容如下
include /opt/cluster/redis.conf
daemonize yes
bind 192.168.1.100
dir /opt/cluster/
port 6390
dbfilename dump_6390.rdb
pidfile /var/run/redis_6390.pid
logfile "./6390.log"
cluster-enabled yes
cluster-config-file node-6390.conf
cluster-node-timeout 15000

创建slave3的配置文件:redis-6391.conf

#在/opt/cluster目录创建redis-6391.conf文件,内容如下
include /opt/cluster/redis.conf
daemonize yes
bind 192.168.1.100
dir /opt/cluster/
port 6391
dbfilename dump_6391.rdb
pidfile /var/run/redis_6391.pid
logfile "./6391.log"
cluster-enabled yes
cluster-config-file node-6391.conf
cluster-node-timeout 15000

启动master、slave1、slave2

redis-server /opt/cluster/redis-6379.conf
redis-server /opt/cluster/redis-6380.conf
redis-server /opt/cluster/redis-6381.conf
redis-server /opt/cluster/redis-6389.conf
redis-server /opt/cluster/redis-6390.conf
redis-server /opt/cluster/redis-6391.conf
#可以通过    ps -ef | grep redis    查看启动情况
#ps -ef | grep redis信息省略

确保node-xxxx.conf文件已正常生成

稍后我们会将6个实例合并到一个集群,在组合之前,我们要确保6个redis实例启动后,nodes-xxxx.conf文件都生成正常,如下:

cd /opt/cluster/
ll
#可以通过上述命令,查看到/opt/cluster/目录下
#如果启动一切正常,会出现6个nodes-xxxx.conf文件
#nodes-xxxx.conf分别对应端口6379、6380、6381、6389、6390、6391的文件
#当然还可以看到相应的log文件和redis-xxxx.conf文件

将6个节点合成一个集群

#执行下面命令,将6个redis合体
#我测试的Linux环境,redis目录是/usr/local/redis/redis-6.2.1/
/usr/local/redis/redis-6.2.1/redis-6.2.1/src/redis-cli --cluster create --cluster-replicas 1 192.168.1.100:6379 192.168.1.100:6380 192.168.1.100:6381 192.168.1.100:6389 192.168.1.100:6390 192.168.1.100:6391
  • 合体的命令后面会跟上所有节点的ip:port列表,多个之间用空格隔开,注意ip不要写127.0.0.1,要写真实ip
  • --cluster-replicas 1:表示采用最简单的方式配置集群,即每个master配1个slave,6个节点就形成了3主3从

执行过程如下,期间会让我们确定是否同样这样的分配方式,输入:yes,然后等几秒,集群合体成功

#执行完合成集群命令省略
#中间会有确认环境
Can I set the above configuration? (type 'yes' to accept): 
#输入yes将继续执行
#等待执行完毕

连接集群节点,查看集群信息:cluster nodes

#需要使用redis-cli -c命令连接集群中6个节点中任何一个节点都可以
#注意和之前的连接参数有点不同redis-cli命令后面多了一个-c参数,表示采用集群的方式连接
#连上以后,然后使用cluster nodes可以查看集群节点信息,如下
192.168.1.100:6379> cluster nodes
#信息展示省略,执行完cluster nodes,按照之前的配置会出现6条信息

截图解释一下,如下:

在这里插入图片描述

集群中的每个节点都会生成一个ID,这个ID信息会被写到node-xxxx.conf文件中。因为节点的ip和端口可能会发生变化,但是节点的ID是不会变的,其他节点可以通过其他节点的ID来认识各个节点。

验证集群数据的读写操作

#连接6379这个节点,然后执行一个set操作(注意这里我用的是redis-cli -c命令)
redis-cli -c -h 192.168.1.100 -p 6379
192.168.1.100:6379> set name zhangsan
-> Redirected to slot [5798] located at 192.168.1.100:6380
OK
#在6379上操作的,但是请求被转发到了6380这个节点去处理了
#这里就是我们后面要说的slot的知识了,后面会提及

redis集群如何分配这6个节点

一个集群至少有3个主节点,因为新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,当其中一个挂了,是达不到选举新master的条件的。

选项--cluster-replicas 1表示我们希望为集群中的每个主节点创建一个从节点。

分配原则尽量保证每个主库运行在不同的ip,每个主库和从库不在一个ip上,这样才能做到高可用。

什么是slots(槽)

上面“将6个节点合成一个集群”的过程中:

在这里插入图片描述

Redis集群内部划分了16384个slots(插槽),合并的时候,会将每个slots映射到一个master上面,比如上面3个master和slots的关系如下:

redis主节点槽位范围
master1(端口:6379)[0-5460],插槽的位置从0开始的,0表示第1个插槽
master2(端口:6380)[5461-10922]
master3(端口:6381)[10923-16383]
slave1,slave2,slave3从节点没有槽位,slave是用来对master做替补的

而数据库中的每个key都属于16384个slots中的其中1个,当通过key读写数据的时候,redis需要先根据key计算出key对应的slots,然后根据slots和master的映射关系找到对应的redis节点,key对应的数据就在这个节点上面。

集群中使用公式CRC16(key)%16384计算key属于哪个槽

在集群中录入值

#在redis-cli每次录入、查询键值,redis都会计算key对应的插槽,如果不是当前redis节点的插槽,redis会报错,并告知应前往的redis实例地址和端口,效果如下
#我们连接了6379这个实例来操作k1,这个节点发现k1的槽位在6381上面,返回了错误信息,怎么办呢?
redis-cli -h 192.168.1.100 -p 6379
192.168.1.100:6379> set k1 v1
(error) MOVED 12706 192.168.1.100:6381


#使用redis-cli客户端提供了-c参数可以解决这个问题
#表示以集群方式执行,执行命令的时候当前节点处理不了的时候,会自动将请求重定向到目标节点,被重定向到6381了
redis-cli -c -h 192.168.1.100 -p 6379
192.168.1.100:6379> set k1 v1
-> Redirected to slot [12706] located at 192.168.1.100:6381
OK
192.168.1.100:6381>


#同样,执行get会被重定向
redis-cli -c -h 192.168.1.100 -p 6379
192.168.1.100:6379> get k1
-> Redirected to slot [12706] located at 192.168.1.100:6381
"v1"
192.168.1.100:6381>


#不在一个slot下面,不能使用mget、mset等多键操作
192.168.1.100:6381> mset k1 v1 k2 v2
(error) CROSSSLOT Keys in request don't hash to the same slot
192.168.1.100:6381> mget k1 k2
(error) CROSSSLOT Keys in request don't hash to the same slot


#可以通过{}来定义组的概念,从而使key中{}内相同的键值放到一个slot中去
192.168.1.100:6381> mset k1{g1} v1 k2{g1} v2 k3{g1} v3
OK
192.168.1.100:6381> mget k1{g1} k2{g1} k3{g1}
1) "v1"
2) "v2"
3) "v3"

slot相关的一些命令

  • cluster keyslot <key>:计算key对应的slot
  • cluster coutkeysinslot <slot>:获取slot槽位中key的个数
  • cluster getkeysinslot <slot> <count> 返回count个slot槽中的键
192.168.1.100:6381> cluster keyslot k1{g1}
(integer) 13519
192.168.1.100:6381> cluster countkeysinslot 13519
(integer) 3
192.168.1.100:6381> cluster getkeysinslot 13519 3
1) "k1{g1}"
2) "k2{g1}"
3) "k3{g1}"

故障恢复

如果主节点下线,从节点是否能够提升为主节点?(注意:要等10+秒

#连接master1,然后将master1停掉
redis-cli -c -h 192.168.1.100 -p 6379
192.168.1.100:6379> shutdown
not connected>

#连接master2,看下集群节点的信息
redis-cli -c -h 192.168.1.100 -p 6380
192.168.1.100:6380> cluster nodes

输出如下:

在这里插入图片描述

slave1(6389)确实变成master了,而它原来的master:master1(6379)下线了。

继续:

#启动6379
redis-server /opt/cluster/redis-6379.conf
#连接master1
redis-cli -c -h 192.168.1.100 -p 6379
192.168.1.100:6379> cluster nodes

执行结果如下:

在这里插入图片描述

6379变成slave了,挂在了6389下面了。

如果某一段插槽的主从都宕机了,redis服务是否还能继续?

这个时候要看cluster-require-full-coverage参数的值了:

  • yes(默认值):整个集群都都无法提供服务了
  • no:宕机的这部分槽位数据全部不能使用,其他槽位正常

SpringBoot整合redis集群

1)引入redis的maven配置

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.properties中配置redis cluster信息

spring.redis.cluster.nodes=192.168.1.100:6379,192.168.1.100:6380,192.168.1.100:6381,192.168.1.100:6389,192.168.1.100:6390,192.168.1.100:6391
spring.redis.timeout=60000

其它的操作,基本就差不多了,不多做阐述了。

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

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

相关文章

静态后台管理(9页)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 |学生管理系统网页设计 | OA管理系统 | 后台管理模板 | 智能停车系统 | 等网站的设计与制作 | HTML期末大学生网页设计作业&#xff0c;Web大学生网页 H…

C++ Visual Studio 2022 中的改进、行为更改和错误修复

目录 Visual Studio 2022 版本 17.4 中的一致性改进 作用域的基础类型没有固定类型enum 定义中没有固定基础类型的枚举器类型enum Visual Studio 2022 版本 17.3 中的一致性改进 改进了指针之间的修饰符兼容性检查 Visual Studio 2022 版本 17.2 中的一致性改进 未终止的双向…

【分隔结构】定从分离

形式 先行词 其他定语 定语从句先行词 状语 定语从句作主语的先行词 谓语 定语从句 练习一 他们从一部分人来说&#xff0c;是受到了 1998 年才获得的 DNA 证据的启发&#xff0c;这份 DNA 证据&#xff0c;几乎肯定的证明了 Thomas Jefferson 和 他的奴隶 Sally Hemin…

力扣(LeetCode)16. 最接近的三数之和(C++)

双指针 快排使 numsnumsnums 正序。 设置三个指针 iii 指向 numsnumsnums 第一个数&#xff0c;从前往后枚举 nums[i]nums[i]nums[i] &#xff0c; lll 从 nums[i1]nums[i1]nums[i1] 往后&#xff0c;指向第二个数&#xff0c;rrr 从 nums.size()−1nums.size()-1nums.size()…

【博客539】使用openssl手动为k8s集群签发证书

使用openssl手动为k8s集群签发证书 创建ca私钥和ca证书 1、生成ca私钥&#xff1a;生成一个 2048 位的 ca.key 文件 openssl genrsa -out ca.key 2048 2、基于ca私钥&#xff0c;生成根(root)证书&#xff1a;在 ca.key 文件的基础上&#xff0c;生成 ca.crt 文件 openssl re…

[MQ] 交换机与队列的介绍

✨✨个人主页:沫洺的主页 &#x1f4da;&#x1f4da;系列专栏: &#x1f4d6; JavaWeb专栏&#x1f4d6; JavaSE专栏 &#x1f4d6; Java基础专栏&#x1f4d6;vue3专栏 &#x1f4d6;MyBatis专栏&#x1f4d6;Spring专栏&#x1f4d6;SpringMVC专栏&#x1f4d6;SpringBoot专…

[Spring Cloud] Open Feign 使用

✨✨个人主页:沫洺的主页 &#x1f4da;&#x1f4da;系列专栏: &#x1f4d6; JavaWeb专栏&#x1f4d6; JavaSE专栏 &#x1f4d6; Java基础专栏&#x1f4d6;vue3专栏 &#x1f4d6;MyBatis专栏&#x1f4d6;Spring专栏&#x1f4d6;SpringMVC专栏&#x1f4d6;SpringBoot专…

机械设计基础试题3

一、判断题&#xff08;请在后面的括号中&#xff0c;正确的填√&#xff0c;错误的填&#xff09; &#xff08;20分&#xff09; 1. 如果机构的自由度F&#xff1d;2&#xff0c;则机构无确定性运动。 &#xff08; &#xff09; 2. 作相对运动的三个构件的三个瞬心不一定在一…

JavaEE 进阶:Spring 的创建和使用

文章目录前言一、创建 Spring 项⽬1、创建⼀个 Maven 项⽬2、添加 Spring 框架⽀持3、添加启动类二、存储 Bean 对象1、创建 Bean2、将 Bean 注册到容器三、获取并使⽤ Bean 对象1、创建 Spring 上下⽂① ApplicationContextⅠ 注意事项② BeanFactory③ ApplicationContext VS…

【浅学Java】Bean的作用域和生命周期

Bean的作用域和生命周期1. Bean的作用域1.1 什么是Bean的作用域1.2 Bean的6种作用域singleton——单例作用域prototype——多例作用域request——请求作用域session——会话作用域application——全局作用域(了解)websoccket——HTTP WebSocket作用域(了解)1.3 设置作用域2. Be…

计算机毕业设计node.js+vue+Element企业员工信息管理系统

项目介绍 随着Internet的发展,人们的日常生活已经离不开网络。未来人们的生活与工作将变得越来越数字化、网络化和电子化。本文以实际运用为开发背景,运用软件工程原理和开发方法,它主要是采用node框架和node来完成对系统的设计。整个开发过程首先对企业员工管理系统进行需求分…

LVS-NAT模式部署

目录 一、环境准备 1、准备三台centos服务器 2、实验拓扑 3、NAT模式介绍 二、LVS-NAT模式部署 1、给lvs服务器安装LVS 2、新建LVS集群 3、添加Real Server服务器节点 4、开启路由转发 5、给后端web服务器配置网关 6、效果测试 一、环境准备 1、准备三台centos服务器…

ctfhub-web-warmup

打开题目链接 是一张图 查看源代码 提示source.php 访问这个文件 得到源码 <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["source">"source.php","hint">"hint.php…

Java毕业设计项目_企业级实战全栈项目中信CRM

【教程、代码】文章底部 1.学习目标视频教程目录【教程、代码】文章底部2.CRM 系统概念与项目开发流程2.1. CRM基本概念 圈内存在这么一句话&#xff1a;“世上本来没有CRM&#xff0c;大家的生意越来越难做了&#xff0c;才有了CRM。”在同质化竞争时代&#xff0c;顾客资产尤…

[附源码]java毕业设计社区医院管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

RabbitMQ初步到精通-第六章-RabbitMQ之死信队列

目录 第六章-RabbitMQ之死信队列 1. 死信概念 2. 死信架构 3. 死信来源 3.1 消息 TTL 过期 3.2 队列达到最大长度&#xff08;队列满了&#xff0c;无法再添加数据到 mq 中&#xff09; 3.3 消息被拒绝&#xff08;basic.reject 或 basic.nack&#xff09;并且 requeuefa…

基于stm32单片机的智能恒温箱游泳池

资料编号&#xff1a;104 下面是相关功能视频演示&#xff1a; 104-基于stm32单片机的智能恒温箱游泳池控制系统Proteus仿真&#xff08;源码仿真全套资料&#xff09;功能介绍&#xff1a; 采用stm32单片机&#xff0c;程序可以设置最高值和最低值&#xff0c;当温度超过最高…

[笔记]vue从入门到入坟《五》vue-cli构建vue webpack项目

参考&#xff1a; 用vue-cli搭建vue项目 vue-cli 项目结构目录简介 文章目录前言一、Vue-cli介绍二、开始2.0 下载安装npm 以及gitnpm安装git安装2.1 全局安装 vue-cli2.2 创建项目目录介绍三、常见问题总结前言 一、Vue-cli介绍 官网 简单地说就是构建vue项目的工具包&#…

SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.1 缓存的作用

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇5 整合第三方技术5.1 缓存的作用5.1.1 缓存介绍5.1.2 小结5 整合第三…

【计算机组成原理Note】5.3 CPU数据通路(CPU内部总线+专用数据通路)

5.3.1 数据通路-CPU内部单总线方式 这是第一节的图&#xff0c;将其部件换到一边&#xff1a; 5.3.1.1 CPU内部单总线方式 内部总线是指同一部件&#xff0c;如CPU内部连接各寄存器及运算部件之间的总线; 系统总线是指同一台计算机系统的各部件&#xff0c;如CPU、内存、通道…