Redis高可用架构—Redis集群(Redis Cluster)详细介绍
mhr18 2024-10-28 16:19 33 浏览 0 评论
前面文章Redis高可用方案—主从(masterslave)架构中我们了解了redis主从复制架构,知道了该模式的工作模式为提供多台redis服务,选择其中的一台作为master节点向外提供读写服务,剩下的作为slave节点从master节点复制数据,只向外提供读服务。并且在Redis高可用架构—哨兵(sentinel)机制详细介绍中引入了Redis哨兵,实现了对所有redis节点的监控和master的自动故障转移。一般情况下来说,上面两种方式结合起来使用已经可以满足大部分的redis高可用场景,但它有一个很明显的缺点:只有一台master节点向外提供写服务,其他的slave节点只能提供读服务。所以,当写操作并发量很大的时候,无法缓解写操作的压力。针对这种场景,Redis在3.0版本中引入了Redis集群的部署架构。
什么是Redis集群
Redis集群是一个提供在多个Redis节点之间共享数据的程序集。它并不像Redis主从复制模式那样只提供一个master节点提供写服务,而是会提供多个master节点提供写服务,每个master节点中存储的数据都不一样,这些数据通过数据分片的方式被自动分割到不同的master节点上。
为了保证集群的高可用,每个master节点下面还需要添加至少1个slave节点,这样当某个master节点发生故障后,可以从它的slave节点中选举一个作为新的master节点继续提供服务。不过当某个master节点和它下面所有的slave节点都发生故障时,整个集群就不可用了。这样就组成了下图中的结构模式:
Redis集群中的哈希槽
Redis集群中引入了哈希槽的概念,Redis集群有16384个哈希槽,进行set操作时,每个key会通过CRC16校验后再对16384取模来决定放置在哪个槽,搭建Redis集群时会先给集群中每个master节点分配一部分哈希槽。比如当前集群有3个master节点,master1节点包含0~5500号哈希槽,master2节点包含5501~11000号哈希槽,master3节点包含11001~16384号哈希槽,当我们执行“set key value”时,假如 CRC16(key) % 16384 = 777,那么这个key就会被分配到master1节点上,如下图:
Redis集群中节点的通信
既然Redis集群中的数据是通过哈希槽的方式分开存储的,那么集群中每个节点都需要知道其他所有节点的状态信息,包括当前集群状态、集群中各节点负责的哈希槽、集群中各节点的master-slave状态、集群中各节点的存活状态等。Redis集群中,节点之间通过建立TCP连接,使用gossip协议来传播集群的信息。如下图:
所谓gossip协议,指的是一种消息传播的机制,类似人们传递八卦消息似的,一传十,十传百,直至所有人都知道这条八卦内容。Redis集群中各节点之间传递消息就是基于gossip协议,最终达到所有节点都会知道整个集群完整的信息。gossip协议有4种常用的消息类型:PING、PONG、MEET、FAIL。
● MEET:当需要向集群中加入新节点时,需要集群中的某个节点发送MEET消息到新节点,通知新节点加入集群。新节点收到MEET消息后,会回复PONG命令给发送者。
● PING:集群内每个节点每秒会向其他节点发送PING消息,用来检测其他节点是否正常工作,并交换彼此的状态信息。PING消息中会包括自身节点的状态数据和其他部分节点的状态数据。
● PONG:当接收到PING消息和MEET消息时,会向发送发回复PONG消息,PONG消息中包括自身节点的状态数据。节点也可以通过广播的方式发送自身的PONG消息来通知整个集群对自身状态的更新。
● FAIL:当一个节点判定另一个节点下线时,会向集群内广播一个FAIL消息,其他节点接收到FAIL消息之后,把对应节点更新为下线状态。
Redis集群的MOVED重定向
Redis客户端可以向Redis集群中的任意master节点发送操作指令,可以向所有节点(包括slave节点)发送查询指令。当Redis节点接收到相关指令时,会先计算key落在哪个哈希槽上(对key进行CRC16校验后再对16384取模),如果key计算出的哈希槽恰好在自己节点上,那么就直接处理指令并返回结果,如果key计算出的哈希槽不在自己节点上,那么当前节点就会查看它内部维护的哈希槽与节点ID之间的映射关系,然后给客户端返回一个MOVED错误:MOVED [哈希槽] [节点IP:端口]。这个错误包含操作的key所属的哈希槽和能处理这个请求的Redis节点的IP和端口号,例如“MOVED 3999 127.0.0.1:6379”,客户端需要根据这个信息重新发送查询指令到给定的IP和端口的Redis节点。
Redis集群的搭建及使用
要让集群正常运作至少需要3个master节点,为了高可用,每个master节点至少要有一个slave节点,所以我们就用3个master节点+3个slave节点来搭建集群。
首先准备三台虚拟机,并在每台虚拟机上安装好redis。我本地的三台虚拟机为:192.168. 31.77、192.168. 31.78、192.168. 31.79。如果本地还未安装过虚拟机,可以根据我之前的教程配置安装:VMware Workstation 14安装教程 、虚拟机环境搭建(VMware Workstation14 + centos7.0)、VMware+CentOS7 网络及静态IP配置、 Linux安装Redis 。
以192.168.31.77这台虚拟机操作演示,拷贝出两份单独的redis配置文件,其中一个作为master节点的配置,一个作为slave节点的配置。
修改这两个配置文件,下面是一个集群需要的最少选项配置:
基于这两个配置文件分别启动一个redis实例:
另外两台虚拟机执行同样的步骤启动好各自的两台redis实例。此时,我们就有了6台运行中的redis实例:
接下来我们需要使用这些实例来创建集群。在Redis3.x版本中,只能用redis-trib.rb程序来创建集群,redis-trib.rb是一个Ruby程序,使用前需要先配置Ruby环境。创建集群命令如下:
其中,--replicas 1 表示为集群中的每个master节点创建一个slave节点。Redis4.x版本后,Redis提供了另一种创建集群的方式,即使用 redis-cli 命令,该命令多了一个可以认证集群密码的功能,所以后来Redis就推荐使用 redis-cli 的方式来创建集群,命令如下:
其中,--cluster-replicas 1 表示为集群中的每个master节点创建一个slave节点。我们在任意一台虚拟机上执行上面的命令:
可以看到创建的集群信息,包括master节点及其哈希槽信息、slave节点信息。输入“yes”确认信息,即可看到集群创建成功:
至此,我们的集群就创建好了,接下来就可以测试一下集群是否正常。在任意一台虚拟机上测试都可以,比如我们在192.168.31.77的master节点上添加一条数据,执行以下命令:
向Redis集群中添加新节点
如果我们要向上面运行的Redis集群中添加一个新节点,分两种情况:添加一个master节点,添加一个slave节点。这两种情况的第一步都是要新启动一个Redis实例,启动使用的配置文件与上面集群中的各节点的配置文件一致,只需要改一下port、cluster-config-file、pidfile三个选项的配置。此处,我们先在192.168.31.79虚拟机上启动一个端口号为7006的Redis实例。
●添加一个master节点:如果要添加一个master节点到集群中,需要执行以下命令:
./bin/redis-cli --cluster add-node 192.168.31.79:7006 192.168.31.77:7000
其中,第一个参数是新的Redis节点的IP和端口,第二个参数是任意一个已经存在的Redis节点的IP和端口。执行之后效果如下:
上面命令执行成功之后,新的节点就已经添加到集群中了,可以通过cluster nodes命令查看:
但此时,这个新的master节点上是没有分配任何哈希槽的,我们还需要使用下面命令重新分配master节点的哈希槽:
redis-cli --cluster reshard 192.168.31.79:7006 --cluster-from 已有节点id,多个id之间使用半角逗号分隔 --cluster-to 新节点id --cluster-slots 新节点的哈希槽数量
其中,节点id可以从cluster nodes结果中查看:
此处,我们需要将之前已存在的3个master节点上的部分哈希槽重新分配给新的节点,执行后结果如下:
输入yes确认后,结果如下,可以看到哪些哈希槽被分配到了新节点:
此时,就可以用该节点操作数据了:
点关注不迷路,跟我一起学技术!
./bin/redis-cli --cluster add-node --slave 192.168.31.79:7007 192.168.31.77:7000 --cluster-master-id 0a55dba682340a513cce51a626e81c1789423249
其中,--slave表示添加的是slave节点,192.168.31.79:7007是要添加的新节点,192.168.31.77:7000是集群中任意一个节点,--cluster-master-id后面跟的是新的slave节点要添加到哪个master节点下面,此处,我们将新的slave节点添加到192.168.31.79:7006这台master节点下。执行结果如下:
并且,使用新的节点也可以正常查询数据:
从Redis集群中移除节点
移除集群中某个节点也分两种情况:移除master节点和移除slave节点。
●移除master节点:由于master节点上分配的有哈希槽,所以当移除某个master节点之前,需要先将该节点上的哈希槽分配到其他节点上,然后在移除该节点。
首先通过下面命令重新分配哈希槽:
redis-cli --cluster reshard 192.168.31.79:7006
其中,192.168.31.79:7006表示要删除的master节点地址和端口。
然后,执行下面命令移除该节点:
redis-cli --cluster del-node 192.168.31.79:7006 节点id。
●移除slave节点:移除slave节点比较简单,直接执行下面命令移除即可:
redis-cli --cluster del-node 192.168.31.79:7007 节点id
其中,192.168.31.79:7007表示要删除的slave节点地址和端口,节点id表示该节点的id。
点关注不迷路,跟我一起学技术!
关注同名微信公众号【Java架构成长之路】获取更多文章~
相关推荐
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
-
在企业级运维、故障排查和性能调优过程中,准确了解服务器的运行环境至关重要。无论是物理机还是虚拟机,都存在各自的优势与限制。在很多场景下,尤其是当你继承一台服务器而不清楚底层硬件细节时,如何快速辨识它是...
- 第四节 Windows 系统 Docker 安装全指南
-
一、Docker在Windows上的运行原理(一)架构限制说明Docker本质上依赖Linux内核特性(如Namespaces、Cgroups等),因此在Windows系统上无法直...
- C++ std:shared_ptr自定义allocator引入内存池
-
当C++项目里做了大量的动态内存分配与释放,可能会导致内存碎片,使系统性能降低。当动态内存分配的开销变得不容忽视时,一种解决办法是一次从操作系统分配一块大的静态内存作为内存池进行手动管理,堆对象内存分...
- Activiti 8.0.0 发布,业务流程管理与工作流系统
-
Activiti8.0.0现已发布。Activiti是一个业务流程管理(BPM)和工作流系统,适用于开发人员和系统管理员。其核心是超快速、稳定的BPMN2流程引擎。Activiti可以...
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
-
MyBatis动态SQL在日常开发中频繁使用,但大多数开发者仅掌握基础标签。本文将介绍五种高阶技巧,助你解锁更灵活的SQL控制能力。一、智能修剪(Trim标签)应用场景:动态处理字段更新,替代<...
- Springboot数据访问(整合Mybatis Plus)
-
Springboot整合MybatisPlus1、创建数据表2、引入maven依赖mybatis-plus-boot-starter主要引入这个依赖,其他相关的依赖在这里就不写了。3、项目结构目录h...
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
-
见证了两个月前勇士与猛龙那个史诗般的系列赛后,甲骨文球馆正式成为了历史。那个大大的红色标志被一个字母一个字母地移除,在周四,一切都成为了过去式。然而这座,别名为“Roaracle”(译注:Roar怒吼...
- Mybatis入门看这一篇就够了(mybatis快速入门)
-
什么是MyBatisMyBatis本是apache的一个开源项目iBatis,2010年这个项目由apachesoftwarefoundation迁移到了googlecode,并且改名为M...
- Springboot数据访问(整合druid数据源)
-
Springboot整合druid数据源基本概念SpringBoot默认的数据源是:2.0之前:org.apache.tomcat.jdbc.pool.DataSource2.0及之后:com.z...
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
-
什么是/etc/profile.d/目录?/etc/profile.d/目录是Linux系统不可或缺的一部分保留配置脚本。它与/etc/profile文件相关联,这是一个启动脚本,该脚...
- 企业数据库安全管理规范(企业数据库安全管理规范最新版)
-
1.目的为规范数据库系统安全使用活动,降低因使用不当而带来的安全风险,保障数据库系统及相关应用系统的安全,特制定本数据库安全管理规范。2.适用范围本规范中所定义的数据管理内容,特指存放在信息系统数据库...
- Oracle 伪列!这些隐藏用法你都知道吗?
-
在Oracle数据库中,有几位特殊的“成员”——伪列,它们虽然不是表中真实存在的物理列,但却能在数据查询、处理过程中发挥出意想不到的强大作用。今天给大家分享Oracle伪列的使用技巧,无论...
- Oracle 高效处理数据的隐藏神器:临时表妙用
-
各位数据库搬砖人,在Oracle的代码世界里闯荡,处理复杂业务时,是不是总被数据“搅得头大”?今天给大家安利一个超实用的隐藏神器——临时表!当你需要临时存储中间计算结果,又不想污染正式数据表...
- Oracle 数据库查询:多表查询(oracle多表关联查询)
-
一、多表查询基础1.JOIN操作-INNERJOIN:返回两个表中满足连接条件的匹配行,不保留未匹配数据。SELECTa.emp_id,b.dept_nameFROMempl...
- 一文掌握怎么利用Shell+Python实现多数据源的异地备份程序
-
简介:在信息化时代,数据安全和业务连续性已成为企业和个人用户关注的焦点。无论是网站数据、数据库、日志文件,还是用户上传的文档、图片等,数据一旦丢失,损失难以估量。尤其是当数据分布在多个不同的目录、服务...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
- 第四节 Windows 系统 Docker 安装全指南
- C++ std:shared_ptr自定义allocator引入内存池
- Activiti 8.0.0 发布,业务流程管理与工作流系统
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
- Springboot数据访问(整合Mybatis Plus)
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
- Mybatis入门看这一篇就够了(mybatis快速入门)
- Springboot数据访问(整合druid数据源)
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
- 标签列表
-
- oracle位图索引 (74)
- oracle基目录 (50)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (53)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)