面试官:如何搭建Redis集群?

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: **Redis Cluster** 是从 Redis 3.0 开始引入的集群解决方案,它分散数据以减少对单个主节点的依赖,提升读写性能。16384 个槽位分配给节点,客户端通过槽位信息直接路由请求。集群是无代理、去中心化的,多数命令直接由节点处理,保持高性能。通过 `create-cluster` 工具快速搭建集群,但适用于测试环境。在生产环境,需手动配置文件,启动节点,然后使用 `redis-cli --cluster create` 分配槽位和从节点。集群动态添加删除节点、数据重新分片及故障转移涉及复杂操作,包括主从切换和槽位迁移。

Redis 集群(Redis Cluster)是 Redis 3.0 版本推出的 Redis 集群方案,它将数据分布在不同的服务区上,以此来降低系统对单主节点的依赖,并且可以大大的提高 Redis 服务的读写性能。

Redis 将所有的数据分为 16384 个 slots(槽),每个节点负责其中的一部分槽位,当有 Redis 客户端连接集群时,会得到一份集群的槽位配置信息,这样它就可以直接把请求命令发送给对应的节点进行处理。

Redis Cluster 是无代理模式去中心化的运行模式,客户端发送的绝大数命令会直接交给相关节点执行,这样大部分情况请求命令无需转发,或仅转发一次的情况下就能完成请求与响应,所以集群单个节点的性能与单机 Redis 服务器的性能是非常接近的,因此在理论情况下,当水平扩展一倍的主节点就相当于请求处理的性能也提高了一倍,所以 Redis Cluster 的性能是非常高的。

Redis Cluster 架构图如下所示:
image.png

搭建Redis集群

Redis Cluster 的搭建方式有两种:

  1. 使用 Redis 源码中提供的 create-cluster 工具快速的搭建 Redis 集群环境。
  2. 通过配置文件的方式手动搭建 Redis 集群环境。

具体实现如下。

1.快速搭建Redis集群

create-cluster 工具在 utils/create-cluster 目录下,如下图所示:
image.png
使用命令 ./create-cluster start 就可以急速创建一个 Redis 集群,执行如下:

$ ./create-cluster start # 创建集群
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006

接下来我们需要把以上创建的 6 个节点通过 create 命令组成一个集群,执行如下:

[@iZ2ze0nc5n41zomzyqtksmZ:create-cluster]$ ./create-cluster create # 组建集群
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:30005 to 127.0.0.1:30001
Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 445f2a86fe36d397613839d8cc1ae6702c976593 127.0.0.1:30001
   slots:[0-5460] (5461 slots) master
M: 63bb14023c0bf58926738cbf857ea304bff8eb50 127.0.0.1:30002
   slots:[5461-10922] (5462 slots) master
M: 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc 127.0.0.1:30003
   slots:[10923-16383] (5461 slots) master
S: 64828ab44566fc5ad656e831fd33de87be1387a0 127.0.0.1:30004
   replicates 445f2a86fe36d397613839d8cc1ae6702c976593
S: 0b17b00542706343583aa73149ec5ff63419f140 127.0.0.1:30005
   replicates 63bb14023c0bf58926738cbf857ea304bff8eb50
S: e35f06ca9b700073472d72001a39ea4dfcb541cd 127.0.0.1:30006
   replicates 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc
Can I set the above configuration? (type 'yes' to accept): 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 127.0.0.1:30001)
M: 445f2a86fe36d397613839d8cc1ae6702c976593 127.0.0.1:30001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc 127.0.0.1:30003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: e35f06ca9b700073472d72001a39ea4dfcb541cd 127.0.0.1:30006
   slots: (0 slots) slave
   replicates 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc
S: 0b17b00542706343583aa73149ec5ff63419f140 127.0.0.1:30005
   slots: (0 slots) slave
   replicates 63bb14023c0bf58926738cbf857ea304bff8eb50
M: 63bb14023c0bf58926738cbf857ea304bff8eb50 127.0.0.1:30002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 64828ab44566fc5ad656e831fd33de87be1387a0 127.0.0.1:30004
   slots: (0 slots) slave
   replicates 445f2a86fe36d397613839d8cc1ae6702c976593
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

在执行的过程中会询问你是否通过把 30001、30002、30003 作为主节点,把 30004、30005、30006 作为它们的从节点,输入 yes 后会执行完成。
我们可以先使用 redis-cli 连接到集群,命令如下:

$ redis-cli -c -p 30001

在使用 nodes 命令来查看集群的节点信息,命令如下:

127.0.0.1:30001> cluster nodes
864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc 127.0.0.1:30003@40003 master - 0 1585125835078 3 connected 10923-16383
e35f06ca9b700073472d72001a39ea4dfcb541cd 127.0.0.1:30006@40006 slave 864d4dfe32e3e0b81a64cec8b393bbd26a65cbcc 0 1585125835078 6 connected
0b17b00542706343583aa73149ec5ff63419f140 127.0.0.1:30005@40005 slave 63bb14023c0bf58926738cbf857ea304bff8eb50 0 1585125835078 5 connected
63bb14023c0bf58926738cbf857ea304bff8eb50 127.0.0.1:30002@40002 master - 0 1585125834175 2 connected 5461-10922
445f2a86fe36d397613839d8cc1ae6702c976593 127.0.0.1:30001@40001 myself,master - 0 1585125835000 1 connected 0-5460
64828ab44566fc5ad656e831fd33de87be1387a0 127.0.0.1:30004@40004 slave 445f2a86fe36d397613839d8cc1ae6702c976593 0 1585125835000 4 connected

可以看出 30001、30002、30003 都为主节点,30001 对应的槽位是 0-5460,30002 对应的槽位是 5461-10922,30003 对应的槽位是 10923-16383,总共有槽位 16384 个 (0 ~ 16383)。

create-cluster 搭建的方式虽然速度很快,但是该方式搭建的集群主从节点数量固定以及槽位分配模式固定,并且安装在同一台服务器上,所以只能用于测试环境。

我们测试完成之后,可以使用以下命令,关闭并清理集群

$ ./create-cluster stop # 关闭集群
Stopping 30001
Stopping 30002
Stopping 30003
Stopping 30004
Stopping 30005
Stopping 30006
$ ./create-cluster clean # 清理集群

2.手动搭建Redis集群

由于 create-cluster 本身的限制,在实际生产环境中我们需要使用手动添加配置的方式搭建 Redis 集群,为此我们先要把 Redis 安装包复制到 node1 到 node6 文件中,因为我们要安装 6 个节点,3 主 3 从,如下图所示:
image.png
image.png
接下来我们进行配置并启动 Redis 集群。

2.1 设置配置文件

我们需要修改每个节点内的 redis.conf 文件,设置 cluster-enabled yes 表示开启集群模式,并且修改各自的端口,我们继续使用 30001 到 30006,通过 port 3000X 设置。

2.2 启动各个节点

redis.conf 配置好之后,我们就可以启动所有的节点了,命令如下:

cd /usr/local/soft/mycluster/node1 
./src/redis-server redis.conf

2.3 创建集群并分配槽位

之前我们已经启动了 6 个节点,但这些节点都在各自的集群之内并未互联互通,因此接下来我们需要把这些节点串连成一个集群,并为它们指定对应的槽位,执行命令如下:

redis-cli --cluster create 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 --cluster-replicas 1

其中 create 后面跟多个节点,表示把这些节点作为整个集群的节点,而 cluster-replicas 表示给集群中的主节点指定从节点的数量,1 表示为每个主节点设置一个从节点。

在执行了 create 命令之后,系统会为我们指定节点的角色和槽位分配计划,如下所示:

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:30005 to 127.0.0.1:30001
Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30001
   slots:[0-5460] (5461 slots) master
M: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30002
   slots:[5461-10922] (5462 slots) master
M: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30003
   slots:[10923-16383] (5461 slots) master
S: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30004
   replicates bdd1c913f87eacbdfeabc71befd0d06c913c891c
S: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30005
   replicates bdd1c913f87eacbdfeabc71befd0d06c913c891c
S: bdd1c913f87eacbdfeabc71befd0d06c913c891c 127.0.0.1:30006
   replicates bdd1c913f87eacbdfeabc71befd0d06c913c891c
Can I set the above configuration? (type 'yes' to accept):

从以上信息可以看出,Redis 打算把 30001、30002、30003 设置为主节点,并为他们分配的槽位,30001 对应的槽位是 0-5460,30002 对应的槽位是 5461-10922,30003 对应的槽位是 10923-16383,并且把 30005 设置为 30001 的从节点、30006 设置为 30002 的从节点、30004 设置为 30003 的从节点,我们只需要输入 yes 即可确认并执行分配,如下所示:

Can I set the above configuration? (type 'yes' to accept): 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 127.0.0.1:30001)
M: 887397e6fefe8ad19ea7569e99f5eb8a803e3785 127.0.0.1:30001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: abec9f98f9c01208ba77346959bc35e8e274b6a3 127.0.0.1:30005
   slots: (0 slots) slave
   replicates 887397e6fefe8ad19ea7569e99f5eb8a803e3785
S: 1a324d828430f61be6eaca7eb2a90728dd5049de 127.0.0.1:30004
   slots: (0 slots) slave
   replicates f5958382af41d4e1f5b0217c1413fe19f390b55f
S: dc0702625743c48c75ea935c87813c4060547cef 127.0.0.1:30006
   slots: (0 slots) slave
   replicates 3da35c40c43b457a113b539259f17e7ed616d13d
M: 3da35c40c43b457a113b539259f17e7ed616d13d 127.0.0.1:30002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: f5958382af41d4e1f5b0217c1413fe19f390b55f 127.0.0.1:30003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

显示 OK 表示整个集群就已经成功启动了。

接下来,我们使用 redis-cli 连接并测试一下集群的运行状态,代码如下:

$ redis-cli -c -p 30001 # 连接到集群
127.0.0.1:30001> cluster info # 查看集群信息
cluster_state:ok # 状态正常
cluster_slots_assigned:16384 # 槽位数
cluster_slots_ok:16384 # 正常的槽位数
cluster_slots_pfail:0 
cluster_slots_fail:0
cluster_known_nodes:6 # 集群的节点数
cluster_size:3 # 集群主节点数
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:130
cluster_stats_messages_pong_sent:127
cluster_stats_messages_sent:257
cluster_stats_messages_ping_received:122
cluster_stats_messages_pong_received:130
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:257

相关字段的说明已经标识在上述的代码中了,这里就不再赘述。

课后思考

通过以上方式我们已经可以搭建 Redis 集群了,那么如何给集群动态添加和删除节点呢?Redis 集群中如何实现数据重新分片呢?Redis 故障转移的流程是啥?Redis 如何选择主节点的?

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
3月前
|
存储 缓存 NoSQL
Redis常见面试题(二):redis分布式锁、redisson、主从一致性、Redlock红锁;Redis集群、主从复制,哨兵模式,分片集群;Redis为什么这么快,I/O多路复用模型
redis分布式锁、redisson、可重入、主从一致性、WatchDog、Redlock红锁、zookeeper;Redis集群、主从复制,全量同步、增量同步;哨兵,分片集群,Redis为什么这么快,I/O多路复用模型——用户空间和内核空间、阻塞IO、非阻塞IO、IO多路复用,Redis网络模型
Redis常见面试题(二):redis分布式锁、redisson、主从一致性、Redlock红锁;Redis集群、主从复制,哨兵模式,分片集群;Redis为什么这么快,I/O多路复用模型
|
2月前
|
监控 NoSQL Redis
看完这篇就能弄懂Redis的集群的原理了
看完这篇就能弄懂Redis的集群的原理了
56 0
|
22天前
|
存储 缓存 NoSQL
【Java面试题汇总】Redis篇(2023版)
Redis的数据类型、zset底层实现、持久化策略、分布式锁、缓存穿透、击穿、雪崩的区别、双写一致性、主从同步机制、单线程架构、高可用、缓存淘汰策略、Redis事务是否满足ACID、如何排查Redis中的慢查询
【Java面试题汇总】Redis篇(2023版)
|
13天前
|
缓存 监控 NoSQL
阿里面试让聊一聊Redis 的内存淘汰(驱逐)策略
大家好,我是 V 哥。粉丝小 A 面试阿里时被问到 Redis 的内存淘汰策略问题,特此整理了一份详细笔记供参考。Redis 的内存淘汰策略决定了在内存达到上限时如何移除数据。希望这份笔记对你有所帮助!欢迎关注“威哥爱编程”,一起学习与成长。
|
2月前
|
存储 消息中间件 NoSQL
Redis总结篇(附Redis常见面试题)
本文是对Redis系列文章的总结,涵盖了Redis的数据结构、主从复制、哨兵模式、Cluster分片方案等关键知识点,并附带了一些常见的Redis面试题。
Redis总结篇(附Redis常见面试题)
|
3月前
|
存储 NoSQL 算法
Redis 集群模式搭建
Redis 集群模式搭建
69 5
|
2月前
|
缓存 NoSQL Redis
redis常见面试题总结(上)
Redis 提升读写性能,减少 MySQL 请求。优点包括:内存存储加速数据获取,支持多样数据结构如哈希和有序集合,事务确保操作原子性,具备队列、主从复制及持久化功能。相较于 Memcache,Redis 数据类型更丰富,支持数据持久化与恢复,单值大小可达 512MB。其单线程设计基于 C 语言实现,使用非阻塞 IO 复用来高效处理请求。主从同步机制确保数据一致性,首次同步需生成 RDB 文件。事务虽保证命令序列化执行但不支持回滚。Bigkey 会增加网络负载并可能导致内存不平衡。缓存雪崩、穿透等问题可通过分散过期时间和布隆过滤器解决。缓存预热则预先填充热点数据。
23 0
|
2月前
|
NoSQL Redis
Redis——单机迁移cluster集群如何快速迁移
Redis——单机迁移cluster集群如何快速迁移
49 0
下一篇
无影云桌面