缓存中间件Redis内置集群模式

举报
tea_year 发表于 2025/10/30 22:01:03 2025/10/30
【摘要】 在Redis中,集群模式(也称为Redis Cluster)是一种提供高可用性和数据分片的方法。它允许多个Redis节点通过网络连接协同工作,形成一个单一的大型数据库。这种模式特别适用于需要高可用性、可扩展性和数据分片的场景。是 Redis 官方提供的分布式解决方案,通过数据分片(Sharding)和高可用(High Availability)机制,实现水平扩展和故障自动转移。一、Redis...

在Redis中,集群模式(也称为Redis Cluster)是一种提供高可用性和数据分片的方法。它允许多个Redis节点通过网络连接协同工作,形成一个单一的大型数据库。这种模式特别适用于需要高可用性、可扩展性和数据分片的场景。是 Redis 官方提供的分布式解决方案,通过数据分片(Sharding)和高可用(High Availability)机制,实现水平扩展和故障自动转移。

一、Redis cluster介绍

Redis Cluster是Redis的内置集群,在Redis3.0推出的实现方案。在Redis3.0之前是没有这个内置集群的。Redis Cluster是无中心节点的集群架构,依靠Gossip协议协同自动化修复集群的状态。

Redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。

Redis cluster集群架构图如下:

5.png

二、 哈希槽方式分配数据

需要注意的是,这种集群模式下集群中每个节点保存的数据并不是所有的数据,而只是一部分数据。那么数据是如何合理的分配到不同的节点上的呢?

Redis 集群是采用一种叫做哈希槽 (hash slot)的方式来分配数据的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384

假设现在有3个节点已经组成了集群,分别是:A, B, C 三个节点,它们可以是一台机器上的三个端口,也可以是三台不同的服务器。那么,采用哈希槽 (hash slot)的方式来分配16384个slot 的话,它们三个节点分别承担的slot 区间是:

  • 节点A覆盖0-5460

  • 节点B覆盖5461-10922

  • 节点C覆盖10923-16383

那么,现在要设置一个key ,比如叫my_name:

set my_name itcast

按照redis cluster的哈希槽算法:CRC16('my_name')%16384 = 2412。 那么就会把这个key 的存储分配到 节点A 上了。

三、 Redis cluster的主从模式

redis cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会在这些从节点中选取一个来充当主节点,从而保证集群不会挂掉。

redis cluster加入了主从模式后的效果如下:

6.png

四、 Redis cluster搭建

4.1 准备Redis节点

为了保证可以进行投票,需要至少3个主节点。

每个主节点都需要至少一个从节点,所以需要至少3个从节点。

一共需要6台redis服务器,我们这里使用6个redis实例,端口号为7001~7006。


先准备一个干净的redis环境,复制原来的bin文件夹,清理后作为第一个redis节点,具体命令如下:

# 进入redis安装目录
cd /usr/local/redis
# 复制redis
mkdir cluster
cp -R bin/ cluster/node1
# 删除持久化文件
cd cluster/node1
rm -rf dump.rdb
rm -rf appendonly.aof
# 删除原来的配置文件
rm -rf redis.conf
# 复制新的配置文件
cp /root/redis-4.0.14/redis.conf ./
# 修改配置文件
vi redis.conf

集群环境redis节点的配置文件如下:

# 不能设置密码,否则集群启动时会连接不上
# Redis服务器可以跨网络访问
bind 0.0.0.0
# 修改端口号
port 7001
# Redis后台启动
daemonize yes
# 开启aof持久化
appendonly yes
# 开启集群
cluster-enabled yes
# 集群的配置 配置文件首次启动自动生成
cluster-config-file nodes.conf
# 请求超时
cluster-node-timeout 5000

第一个redis节点node1准备好之后,再分别复制5份,

cp -R node1/ node2

修改六个节点的端口号为7001~7006,修改redis.conf配置文件即可

编写启动节点的脚本:

vi start-all.sh

内容为:

cd node1
./redis-server redis.conf
cd ..
cd node2
./redis-server redis.conf
cd ..
cd node3
./redis-server redis.conf
cd ..
cd node4
./redis-server redis.conf
cd ..
cd node5
./redis-server redis.conf
cd ..
cd node6
./redis-server redis.conf
cd ..

设置脚本的权限,并启动:

chmod 744 start-all.sh
./start-all.sh

使用命令 ps -ef | grep redis 查看效果如下:

7.png

4.2 启动Redis集群

redis集群的管理工具使用的是ruby脚本语言,安装集群需要ruby环境,先安装ruby环境:

# 安装ruby
yum -y install ruby ruby-devel rubygems rpm-build

# 升级ruby版本,redis4.0.14集群环境需要2.2.2以上的ruby版本
yum install centos-release-scl-rh
yum install rh-ruby23  -y
scl enable rh-ruby23 bash

# 查看ruby版本
ruby -v


下载符合环境要求的gem,下载地址如下:

https://rubygems.org/gems/redis/versions/4.1.0

课程资料中已经提供了redis-4.1.0.gem,直接上传安装即可,安装命令:

gem install redis-4.1.0.gem


进入redis安装目录,使用redis自带的集群管理脚本,执行命令:

# 进入redis安装包
cd /root/redis-4.0.14/src/
# 查看集群管理脚本
ll *.rb
# 使用集群管理脚本启动集群,下面命令中的1表示为每个主节点创建1个从节点
./redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 \
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006

效果如下:

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.200.129:7001
192.168.200.129:7002
192.168.200.129:7003
Adding replica 192.168.200.129:7005 to 192.168.200.129:7001
Adding replica 192.168.200.129:7006 to 192.168.200.129:7002
Adding replica 192.168.200.129:7004 to 192.168.200.129:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: f0094f14b59c023acd38098336e2adcd3d434497 192.168.200.129:7001
  slots:0-5460 (5461 slots) master
M: 0eba44418d7e88f4d819f89f90da2e6e0be9c680 192.168.200.129:7002
  slots:5461-10922 (5462 slots) master
M: ac16c5545d9b099348085ad8b3253145912ee985 192.168.200.129:7003
  slots:10923-16383 (5461 slots) master
S: edc7a799e1cfd75e4d80767958930d86516ffc9b 192.168.200.129:7004
  replicates ac16c5545d9b099348085ad8b3253145912ee985
S: cbd415973b3e85d6f3ad967441f6bcb5b7da506a 192.168.200.129:7005
  replicates f0094f14b59c023acd38098336e2adcd3d434497
S: 40fdde45b16e1ac85c8a4c84db75b43978d1e4d2 192.168.200.129:7006
  replicates 0eba44418d7e88f4d819f89f90da2e6e0be9c680
Can I set the above configuration? (type 'yes' to accept): yes #注意选择为yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join..
>>> Performing Cluster Check (using node 192.168.200.129:7001)
M: f0094f14b59c023acd38098336e2adcd3d434497 192.168.200.129:7001
  slots:0-5460 (5461 slots) master
  1 additional replica(s)
M: ac16c5545d9b099348085ad8b3253145912ee985 192.168.200.129:7003
  slots:10923-16383 (5461 slots) master
  1 additional replica(s)
S: cbd415973b3e85d6f3ad967441f6bcb5b7da506a 192.168.200.129:7005
  slots: (0 slots) slave
  replicates f0094f14b59c023acd38098336e2adcd3d434497
S: 40fdde45b16e1ac85c8a4c84db75b43978d1e4d2 192.168.200.129:7006
  slots: (0 slots) slave
  replicates 0eba44418d7e88f4d819f89f90da2e6e0be9c680
M: 0eba44418d7e88f4d819f89f90da2e6e0be9c680 192.168.200.129:7002
  slots:5461-10922 (5462 slots) master
  1 additional replica(s)
S: edc7a799e1cfd75e4d80767958930d86516ffc9b 192.168.200.129:7004
  slots: (0 slots) slave
  replicates ac16c5545d9b099348085ad8b3253145912ee985
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.


五、使用Redis集群

按照redis cluster的特点,它是去中心化的,每个节点都是对等的,所以连接哪个节点都可以获取和设置数据。

使用redis的客户端连接redis集群,命令如下:

./redis-cli -h 192.168.200.129 -p 7001 -c

其中-c 一定要加,这个是redis集群连接时,进行节点跳转的参数。

连接到集群后可以设置一些值,可以看到这些值根据前面提到的哈希槽方式分散存储在不同的节点上了。

小结

总结来说,使用 redis-cli -p 6001 -c 连接Redis集群并新增键通常不会报错,因为它能够应对键可能分布在不同节点的情况,自动处理重定向。而使用 redis-cli -p 6001(无 -c 参数)连接时,由于客户端不具备集群模式的支持,遇到需要重定向的情况会直接报告错误,无法完成新增键的操作。因此,在与Redis集群交互时,尤其是在进行写入操作时,务必使用 -c 参数以确保命令能够正确执行。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。