文章目录
- 一、概述
- 二、模拟配置说明
- 三、脚本方式创建 Redis Cluster
- 3.1 配置创建脚本
- 3.2 启动集群实例
- 3.3 创建集群
- 3.4 测试集群
- 3.5 停止集群实例
- 3.6 删除(清空)集群
- 四、手动创建集群 Redis Cluster
- 4.1 启动集群实例
- 4.2 手动创建集群
- 4.4 测试集群
- 五、集群管理
- 5.1 移动槽位
- 5.2 查看集群基本信息
- 5.3 查看集群详细信息
如果您对Redis的了解不够深入请关注本栏目,本栏目包括Redis安装,Redis配置文件说明,Redis命令和数据类型说明,Redis持久化配置,Redis主从复制和哨兵机制。
一、概述
- Redis 是一个开源的内存数据库,支持分布式部署。Redis Cluster (Redis 集群)是 Redis 的分布式解决方案,用于提供高可用性和可扩展性。Redis Cluster 通过分片(Sharding)和数据复制(Replication)来实现数据的分布和冗余,以提供高性能和容错能力。
- 集群的原理是数据分治,即将数据分散到多个节点以实现分布式存储和处理。然而,这种数据分散的方式可能在某些情况下导致聚合操作(例如事务)变得更加复杂。
- 在Redis应用中,要增强可用性可以使用主备模式和主从模式(请看Redis主从模式配置)。 这是一种全量的主从复制机制,从是主的一个镜像。但是这种方式并不能解决随着业务增加,导数据量增加的问题(因为他们是镜像,不能扩展容量),要解决容量问题那就么需要集群。
- Redis Cluster 是把业务数据通过逻辑规则分散到不同的主从节点,解决了单个主从节点的单点故障问题(相当于对主节点做了高可用配置)。他一方面提高了扩展性,别一方面也提高了可用性(因为数据不在同一个主从节点,那么一般就不会出现所有数据同时失效的问题)。
- 如果没有Redis集群,我们手动实现数据分治的逻辑一般如下:
- 根据业务场景进行分割。如按功能分割:用户、订单、产品等分配到不同Redis主从节点。
- 如果按业务拆分后还不能满足要求,还可以按优先级、逻辑再拆分(如每10000个ID一个Redis主从节点)。
- 而默认的 Redis Cluster 使用了Hash Ring(哈希环)的概念来分片和管理数据。哈希环是一种数据结构,将数据节点(Redis 实例)映射到一个环形空间上。在 Redis Cluster 中,每个节点被分配一个槽位(slot),共有 16384 个槽位。数据根据键的哈希值被映射到对应的槽位上。假设有三个主从Redis 做了集群,槽位分布如下:
- Redis Cluster 使用一种称为 Hash Slot Sharding 的分片策略。每个节点负责管理一部分槽位和对应槽位上的数据。当客户端发送命令到 Redis Cluster 时,首先根据命令中的键计算哈希值,并根据哈希值确定对应的槽位。然后,客户端将命令发送到负责该槽位的节点上,完成数据操作(所以他是一种无主模式集群,即没有那个主从节点是主节点,而是根据槽位计算)。这样,数据被均匀地分布在整个集群中的各个节点上。
- 哈希环的使用使得 Redis Cluster 具备了分布式的能力,同时保证了高可用性和可扩展性。当节点加入或离开集群时,Redis Cluster 会自动进行槽位的重新分配,以保持数据的平衡和一致性。这种分片方式使得 Redis Cluster 能够水平扩展,支持处理大规模的数据和负载。
二、模拟配置说明
- 下面我们使用三个主从Redis构成一个Redis Cluster(官方说一个Redis Cluster至少需要三个主从Redis,Redis主从模式配置请看这里)。默认创建的Redis Cluster的端口是30001、30002、30003、30004、30005、30006,如下示意图(集群实际端口与你们不一定能对上,但是思路是这样的):
三、脚本方式创建 Redis Cluster
- 首先我们使用Redis官方自带的脚本创建 Redis Cluster 看看效果。使用Redis官方脚本有个好处是方便,因为他会自动做我们创建三个主从R edis,然后根据三个主从Redis再创建集群。
3.1 配置创建脚本
- 在Redis源码的 utils/create-cluster/ 目录下有一个 create-cluster 脚本,打开这个脚本修改一下配置(不修改的话,有些是创建9个Redis实例,且主机地址是127.0.0.1。不如果你嫌麻烦也可以不修改,创建后按默认的配置访问即可,我这里了演示方便修改一下)。有关Redis源码编译安装请看这里。
cd utils/create-cluster/
vi create-cluster
- 修改 create-cluster 脚本的主要内容如下:
# 测试节点总数
NODES=6
# 从机数,这里相当于三主三从(master=total/slave+1)
REPLICAS=1
# 如果不是本机测试,则如下配置十分重要(具体可参考本栏目Redis配置文件说明)
# 配置集群主机信息,192.168.8.60 根据需要改您主机的IP。
CLUSTER_HOST=192.168.8.60
# 是否开启保护模式
PROTECTED_MODE=no
3.2 启动集群实例
- 在 utils/create-cluster/ 目录下使用 create-cluster 脚本加 start 参数启动集群实例。
./create-cluster start
[root@yiqifu-redis create-cluster]# ./create-cluster start
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006
- 因为要搭建一个Redis集群至少需要3个主节点。一般3主3从,所以最少需要6个节点。这里脚本直接帮我们创建了6个实例。
3.3 创建集群
- 在 utils/create-cluster/ 目录下使用 create-cluster 脚本加 create 参数将Redis实例创建为集群。
./create-cluster create
[root@yiqifu-redis 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: cf12868ca9b7049ba7b73757aed83cf56e3e6b09 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
M: f8521587351d126ee6618fee70bdc994c598fab0 127.0.0.1:30002
slots:[5461-10922] (5462 slots) master
M: 764d51f5a7a986f424cb218794a3fcbe493913b1 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
S: 46233ddb3462efcbf37b2d1e7229f9a54e36d9e8 127.0.0.1:30004
replicates f8521587351d126ee6618fee70bdc994c598fab0
S: 31d9d8aa6927509ec33b7534a3ddeb3e921ce171 127.0.0.1:30005
replicates 764d51f5a7a986f424cb218794a3fcbe493913b1
S: 89415c9c43b4515441f49ac285d2e0e1a80b4525 127.0.0.1:30006
replicates cf12868ca9b7049ba7b73757aed83cf56e3e6b09Can 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 joinPerforming Cluster Check (using node 127.0.0.1:30001)
M: cf12868ca9b7049ba7b73757aed83cf56e3e6b09 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 31d9d8aa6927509ec33b7534a3ddeb3e921ce171 127.0.0.1:30005
slots: (0 slots) slave
replicates 764d51f5a7a986f424cb218794a3fcbe493913b1
M: 764d51f5a7a986f424cb218794a3fcbe493913b1 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: f8521587351d126ee6618fee70bdc994c598fab0 127.0.0.1:30002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 46233ddb3462efcbf37b2d1e7229f9a54e36d9e8 127.0.0.1:30004
slots: (0 slots) slave
replicates f8521587351d126ee6618fee70bdc994c598fab0
S: 89415c9c43b4515441f49ac285d2e0e1a80b4525 127.0.0.1:30006
slots: (0 slots) slave
replicates cf12868ca9b7049ba7b73757aed83cf56e3e6b09
[OK] All nodes agree about slots configuration.
>>> Check for open slots…
>>> Check slots coverage…
[OK] All 16384 slots covered.
3.4 测试集群
- 使用 redis-cli 连接集群测试。由于Redis Cluster 是无主模式集群,我们创建的集群是三个主从。所以在连接时随便使用任何一个主的端口都可以(如:redis-cli -c -p 30001 、 redis-cli -c -p 30002 、 redis-cli -c -p 30003)。在使用时集群会根据键(key)的哈希(hash)计算槽位,然后定位到相应的主从上存取数据。如下测试示例
# -c 表示以集群的方式连接
# -p 指定端口
redis-cli -c -p 30001
[root@yiqifu-redis create-cluster]# redis-cli -c -p 30001
127.0.0.1:30001> set aaa 111
-> Redirected to slot [10439] located at 127.0.0.1:30002
OK
127.0.0.1:30002> set bbb 222
-> Redirected to slot [5287] located at 127.0.0.1:30001
OK
127.0.0.1:30001> set ccc 333
OK
127.0.0.1:30001> set {g1}aaa 111
-> Redirected to slot [13519] located at 127.0.0.1:30003
OK
127.0.0.1:30003> set {g1}bbb 222
OK
127.0.0.1:30003> set {g1}ccc 333
OK
127.0.0.1:30003> set {g1}ddd 444
OK
127.0.0.1:30003> set {g1}eee 555
OK127.0.0.1:30003> multi
OK
127.0.0.1:30003> set {g1}bbb 222222
QUEUED
127.0.0.1:30003> set {g1}ccc 333333
QUEUED
127.0.0.1:30003> exec1) OK
2) OK127.0.0.1:30003>
- 在使用时还可以使用“{组名}键”将不同的键(Key)分成一组放在同一个Redis主从中。在同一个Redis主从中就可以使用事务、监控等功能。如:这里使用"{g1}"作命名空间隔离,也就将带“{g1}”的key分到同一个redis中,这样才能方便在同一Redis中开启事务等操作。
- 通过上面测试可以发现,Redis Cluster 无主模式集群,他会根据您输入的key的值计算存储在那个主从Redis中,并会自动跳转到相应的主从Redis节点上。
3.5 停止集群实例
- 在 utils/create-cluster/ 目录下使用 create-cluster 脚本加 stop 参数将Redis Cluster 停止。
./create-cluster stop
[root@yiqifu-redis create-cluster]# ./create-cluster stop
Stopping 30001
Stopping 30002
Stopping 30003
Stopping 30004
Stopping 30005
Stopping 30006
3.6 删除(清空)集群
- 在 utils/create-cluster/ 目录下使用 create-cluster 脚本加 clean 参数将Redis Cluster 所有配置清除(回到原来状态)。
./create-cluster clean
四、手动创建集群 Redis Cluster
- 在实际生产环境中,Redis 主从实服务都是手动配置,Redis Cluster 也需要手动创建。下面演示手动创建Redis Cluster。
4.1 启动集群实例
- 这里测试时我还是使用了脚本先启动了6个实例(启动实例只是启动Redis服务,并未创建集群),在生产环境中这些Redis实例是您自己在不同的服务器上配置的。
- 我这里6台Redis实例的IP和端口分别如下: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。留意这个信息,后面有创建集群有用。
./create-cluster start
[root@yiqifu-redis create-cluster]# ./create-cluster start
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006
-
如果是自己配置 redis.conf 文件,我后通过 redis-server redis.conf 来启动实例,那么以下配置要正确修改才能创建集群。
# port 6391 cluster-enabled yes # 配置集群配置文件为 nodes.conf # nodes.conf 无需手动创建,集群启动时会自动创建。 cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes
4.2 手动创建集群
-
根据现有Redis服务实例(这些实例是您分布在不同主机的Redis服务),使用命令手动创建集群。
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
-
参数说明
- –cluster create 参数表示创建集群
- –cluster-replicas 1 指定了每个主从Redis下,从节点的个数。由此可以推算出Redis集群中主从个数=节点总数 / (每个主从模式下从节点个数 + 1) = 6 / (1+1) = 3 个主从Redis。
4.4 测试集群
- 同脚本创建方式,请自己测试
# -c 表示以集群的方式连接
redis-cli -c -p 30001
五、集群管理
5.1 移动槽位
-
为什么要移动槽位?我想到以下几中情况:
- 假设您添加了一个新的Redis主从,则您需要把原集群的某些槽位均分到这个新的Redis主从上。
- 假设您集群中某个Redis主从坏了,则您需要把这个坏掉的槽位均分到集群中其他Redis主从上。
- 假设您某个Redis主从的硬件配置较低,别一个Redis主从的硬件配置较高,则您可以把硬件配置较低槽位分配一些到这个硬件配置较高的Redis主从上。
-
在 Redis 中,槽(Slots)是用于分片数据的概念。Redis Cluster使用槽位来将数据分布到多个节点,以实现水平扩展和提高系统的可伸缩性和可用性。每个 Redis Cluster 包含16384个槽,这些槽可以用于分配数据。
-
在创建集群的时候有这样一些信息,他说明了每个主从节点所分配的槽位信息。这里如Master[0]的槽位信息是 0 ~ 5460。和每个主从节点的ID和所属关系。如下,留意这些信息,后面会用到。
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383M: fc253a3c9f2c301f7c5f6e72b47a338237b3447d 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
M: ab3db8a2ed5fc4066c3257344618d02059e88648 127.0.0.1:30002
slots:[5461-10922] (5462 slots) master
M: 5d4d3f51cf968ca13718e378b5ffd68452d70479 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
S: a82a0b7c77addee864259f02a6c38f47745c5da0 127.0.0.1:30004
replicates 5d4d3f51cf968ca13718e378b5ffd68452d70479
S: b2944e78407304948150003bc395de9165354010 127.0.0.1:30005
replicates fc253a3c9f2c301f7c5f6e72b47a338237b3447d
S: 934fc2185bd12ff361fd40ae1b26bd0355bdf6e3 127.0.0.1:30006
replicates ab3db8a2ed5fc4066c3257344618d02059e88648
-
移动槽位命令语法:redis-cli --cluster reshard 集群任何一个主节点
- –cluster reshard 参数表示移动槽位
-
如下,我们将主机( 127.0.0.1:30001) 的2000个槽位移动到主机( 127.0.0.1:30002) 的过程。
过程要查看集群中主从的ID,如果前没有记录,可以先看5.3节看命令。
# 进入集群移动槽位命令(在我的配置环境下,以下任何一条命令都可以)
redis-cli --cluster reshard 127.0.0.1:30001
# redis-cli --cluster reshard 127.0.0.1:30002
# redis-cli --cluster reshard 127.0.0.1:30003
- 执行上面命令后会提示“How many slots do you want to move (from 1 to 16384)?”
- 意思是“你想移动多少个槽位(取值范围是1~16384)?”,但通过日志可以看到实际是(0 - 5460),比如我填:2000。
- 然后会提示“What is the receiving node ID?”
- 意思是“集群中那个主从节点接受这个2000个槽位信息?”,通过日志可以看到主机( 127.0.0.1:30002)的ID,比如我移动到第二个节点填:ab3db8a2ed5fc4066c3257344618d02059e88648
- 然后提示“ Source node #1:”
- 意思是“从那个节点移出这2000个槽位”,通过日志可以看到主机( 127.0.0.1:30001)的ID,比如我选择第一个节点,填:fc253a3c9f2c301f7c5f6e72b47a338237b3447d
- 然后提示“ Source node #2:” 时输入“done”。然后一路都填 yes 完成
5.2 查看集群基本信息
- 基本语法:redis-cli --cluster info 集群任何一个主节点
redis-cli --cluster info 127.0.0.1:30001
[root@yiqifu-redis create-cluster]# redis-cli --cluster info 127.0.0.1:30001
127.0.0.1:30001 (fc253a3c…) -> 0 keys | 3461 slots | 1 slaves.
127.0.0.1:30003 (5d4d3f51…) -> 0 keys | 7461 slots | 1 slaves.
127.0.0.1:30002 (ab3db8a2…) -> 0 keys | 5462 slots | 1 slaves.
- 这里可以看到集群基本信息和槽位总数。
5.3 查看集群详细信息
- 基本语法:redis-cli --cluster check 集群任何一个主节点
redis-cli --cluster check 127.0.0.1:30001
[root@yiqifu-redis create-cluster]# redis-cli --cluster check 127.0.0.1:30001
127.0.0.1:30001 (fc253a3c…) -> 0 keys | 3461 slots | 1 slaves.
127.0.0.1:30003 (5d4d3f51…) -> 0 keys | 7461 slots | 1 slaves.
127.0.0.1:30002 (ab3db8a2…) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 127.0.0.1:30001)
M: fc253a3c9f2c301f7c5f6e72b47a338237b3447d 127.0.0.1:30001
slots:[2000-5460] (3461 slots) master
1 additional replica(s)
M: 5d4d3f51cf968ca13718e378b5ffd68452d70479 127.0.0.1:30003
slots:[0-1999],[10923-16383] (7461 slots) master
1 additional replica(s)
S: 934fc2185bd12ff361fd40ae1b26bd0355bdf6e3 127.0.0.1:30006
slots: (0 slots) slave
replicates ab3db8a2ed5fc4066c3257344618d02059e88648
M: ab3db8a2ed5fc4066c3257344618d02059e88648 127.0.0.1:30002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: a82a0b7c77addee864259f02a6c38f47745c5da0 127.0.0.1:30004
slots: (0 slots) slave
replicates 5d4d3f51cf968ca13718e378b5ffd68452d70479
S: b2944e78407304948150003bc395de9165354010 127.0.0.1:30005
slots: (0 slots) slave
replicates fc253a3c9f2c301f7c5f6e72b47a338237b3447d
[OK] All nodes agree about slots configuration.
>>> Check for open slots…
>>> Check slots coverage…
[OK] All 16384 slots covered.
- 这里可以看到集群详细信息。每个主从槽位的具体范围,如:slots:[0-1999],[10923-16383] (7461 slots) master