Redis 如何使用 RedisCluster 构建高可用集群架构?

Redis 如何使用 RedisCluster 构建高可用集群架构?

Redis 如何使用 Twemproxy 和 Sentinel 构建高可用集群架构? 篇中介绍了构建 Redis 集群的一种平替方案,但是 Twemproxy + Sentinel 方案有着其自身的缺点,其中最主要的是在节点的伸缩时,数据集的自动平衡是个比较棘手的问题。这篇文章介绍 Redis 官方提供的构建集群方案。通过本篇可以知道 Redis Cluster 如何构建、Redis 节点伸缩的操作方式。

什么是 Redis Cluster?

Redis Cluster 提供 Redis 的水平扩展的能力,采用去中心化的架构,集群中的每个节点保存独立的数据以及整个集群的相关状态。由于每个节点都和集群中的其他节点进行交互,客户端只要链接其中一个节点,就能感知整个集群节点。

哈希槽(hash slot)

Redis Cluster 对于节点数据的分片并没有采用传统的一致性哈希算法,而是采用了一种不同的分片方式,叫做哈希槽。具体就是在 Redis Cluster 中有 16384 个哈希槽,对一个给定的 key 进行操作时,会对该 key 应用 CRC16 算法然后与 16384 进行取模运算,进而判断该 key 位于哪个哈希槽上。

使用哈希槽设计有诸多好处:

  • 每个节点负责哈希槽的一部分子集。
  • 容易增加或者删除集群中的节点。
  • 在节点之间移动哈希槽不需要停止任何操作。
  • 通过 hash tag,Redis Cluster 能够支持所谓的 multiple key 的操作(多个操作在同一个命令或事务或Lua 脚本中)

一致性保证(consistency guarantees)

Redis Cluster 不保证强一致性的事务,由于 Cluster 的基础是异步复制,所以会有一个时间的窗口导致数据丢失。

如何构建 Redis Cluster?

以下图的拓扑结构为例,构建 Redis Cluster 集群。

在这里插入图片描述

配置环境

以下配置,仅仅表示我的配置环境,读者可以根据自己的环境进行配置。

注意:需要把主机的防火墙关闭或者把 6379,6380,16379,16380 端口对外放开。

  • 三台 Linux 主机(CentOS 7 版本),ip 分别为:10.211.55.6, 10.211.55.7, 10.211.55.8。
  • 在每台主机上安装 Redis(5.0.9 版本),需要通过源码进行安装。
  • 选择 10.211.55.6 主机作为节点 A,A1(A 为主节点,A1 为 A 的从节点)。
  • 选择 10.211.55.7 主机作为节点 B,B1(B 为主节点,B1 为 B 的从节点)。
  • 选择 10.211.55.8 主机作为节点 C,C1(C 为主节点,C1 为 C 的从节点)。

构建 A,A1 节点

安装 Redis

这里使用源码进行构建。

# 登陆 10.211.55.6 主机,安装 Redis
cd /opt
wget http://download.redis.io/releases/redis-5.0.9.tar.gz
tar -xvf redis-5.0.9.tar.gz
cd redis-5.0.9
make && make install
配置 A,A1 节点

使用如下命令进行构建。

# 配置 A 节点
# 在 /usr/local/etc 目录下创建 redis-cluster/redis-6379 目录,用来存放集群所需的配置文件
mkdir -p /usr/local/etc/redis-cluster/redis-6379

# 创建 redis.conf 文件,写入如下内容,保存退出
vim /usr/local/etc/redis-cluster/redis-6379/redis.conf

port 6379
bind 0.0.0.0
protected-mode no

cluster-enabled yes
dir /usr/local/etc/redis-cluster/redis-6379
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

# 启动 A 节点
nohup redis-server /usr/local/etc/redis-cluster/redis-6379/redis.conf > /dev/null 2>&1 &


# 配置 A1 节点
# 在 /usr/local/etc 目录下创建 redis-cluster/redis-6380 目录,用来存放集群所需的配置文件
mkdir -p /usr/local/etc/redis-cluster/redis-6380

# 创建 redis.conf 文件,写入如下内容,保存退出
vim /usr/local/etc/redis-cluster/redis-6380/redis.conf

port 6380
bind 0.0.0.0
protected-mode no

cluster-enabled yes
dir /usr/local/etc/redis-cluster/redis-6380
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

# 启动 A1 节点
nohup redis-server /usr/local/etc/redis-cluster/redis-6380/redis.conf > /dev/null 2>&1 &

构建 B,B1 节点

构建的方式同 A,A1,只是主机为 10.211.55.7,具体步骤不再赘述。

构建 C,C1 节点

构建的方式同 A,A1,只是主机为 10.211.55.8,具体步骤不再赘述。

构建 Cluster

redis-cli --cluster create 10.211.55.6:6379 10.211.55.7:6379 10.211.55.8:6379 --cluster-replicas 0


# 执行上面的命令,会输出类似如下内容
>>> Performing hash slots allocation on 3 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
M: 5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad 10.211.55.6:6379
   slots:[0-5460] (5461 slots) master
M: a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 10.211.55.7:6379
   slots:[5461-10922] (5462 slots) master
M: 35c17301dac6d01cdd06b01c449c895e1d5f6028 10.211.55.8:6379
   slots:[10923-16383] (5461 slots) master
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 10.211.55.6:6379)
M: 5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad 10.211.55.6:6379
   slots:[0-5460] (5461 slots) master
M: 35c17301dac6d01cdd06b01c449c895e1d5f6028 10.211.55.8:6379
   slots:[10923-16383] (5461 slots) master
M: a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 10.211.55.7:6379
   slots:[5461-10922] (5462 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

通过上面的输出,可以看到每个节点的哈希槽分配情况,分别是:

  • 10.211.55.6:6379 [0-5460]
  • 10.211.55.7:6379 [5461-10922]
  • 10.211.55.8:6379 [10923-16383]

查看集群节点状态

可以看到每个主节点的状态,包括 Node Id,地址以及端口,主/从节点标志,时间戳以及分配的哈希槽范围。

注意此处的 Node Id,这是自动生成的,在不同的服务器上面会有不同的值。

# 查看集群节点状态信息
redis-cli -p 6379 cluster nodes

# 输出
35c17301dac6d01cdd06b01c449c895e1d5f6028 10.211.55.8:6379@16379 master - 0 1681214336434 3 connected 10923-16383
a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 10.211.55.7:6379@16379 master - 0 1681214335403 2 connected 5461-10922
5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad 10.211.55.6:6379@16379 myself,master - 0 1681214336000 1 connected 0-5460

测试 Redis Cluster

可以看到在进行操作时,会重定向到实际的哈希槽上面。

# 客户端登陆
redis-cli -c -p 6379

# 进行 set 操作,观看哈希槽的重新定向
127.0.0.1:6379> set foo bar
-> Redirected to slot [12182] located at 10.211.55.8:6379
OK
10.211.55.8:6379> set hello world
-> Redirected to slot [866] located at 10.211.55.6:6379
OK

添加从节点

在上面创建集群时,没有把从节点加进去,可以采用如下命令,给每个主节点添加一个从节点。

# 将 10.211.55.6:6380 添加为 10.211.55.6:6379 的从节点,注意后面 cluster-master-id 是集群节点 10.211.55.6:6379 的 Node Id
redis-cli --cluster add-node 10.211.55.6:6380 10.211.55.6:6379 --cluster-slave --cluster-master-id 5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad

# 将 10.211.55.7:6380 添加为 10.211.55.7:6379 的从节点,注意后面 cluster-master-id 是集群节点 10.211.55.7:6379 的 Node Id
redis-cli --cluster add-node 10.211.55.7:6380 10.211.55.7:6379 --cluster-slave --cluster-master-id a1a7be53d2ebc9d54fb18c59f31171cf6d371f29

# 将 10.211.55.8:6380 添加为 10.211.55.8:6379 的从节点,注意后面 cluster-master-id 是集群节点 10.211.55.8:6379 的 Node Id
redis-cli --cluster add-node 10.211.55.8:6380 10.211.55.8:6379 --cluster-slave --cluster-master-id 35c17301dac6d01cdd06b01c449c895e1d5f6028

查看集群节点状态

通过如下的输出可以看到,每个主机上 6380 端口的 Redis 实例成为对应的 6379 端口的 Redis 实例的从节点。

redis-cli -p 6379 cluster nodes

# 输出
e667c40572bb7a34fae03ee407e0849728537497 10.211.55.8:6380@16380 slave 35c17301dac6d01cdd06b01c449c895e1d5f6028 0 1681215954316 3 connected
a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 10.211.55.7:6379@16379 master - 0 1681215953285 2 connected 5461-10922
35c17301dac6d01cdd06b01c449c895e1d5f6028 10.211.55.8:6379@16379 master - 0 1681215955346 3 connected 10923-16383
d070ed606c2067bca37f7a079971eed5d67b8841 10.211.55.6:6380@16380 slave 5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad 0 1681215954517 1 connected
32f44e3aab49194db8e5e819a1dc851a86a1b584 10.211.55.7:6380@16380 slave a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 0 1681215954000 2 connected
5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad 10.211.55.6:6379@16379 myself,master - 0 1681215954000 1 connected 0-5460

Redis Node 的重新分片(Reshard)

Redis 可以通过重新分片(Reshard)来动态伸缩节点。需要注意的是,在给集群增加节点时,需要进行哈希槽的重新分配,以便能够达到新的平衡;在给集群移除节点时,需要对移除的节点执行哈希槽的移动,使其成为一个空的主节点,再调用相关命令将该节点移除。

可以通过如下指令进行哈希槽的重新分片。

redis-cli --cluster reshard [new node ip]:[new node port] --cluster-from [from node id] --cluster-to [to node id] --cluster-slots [number of slots] --cluster-yes

例如,将 10.211.55.6:6379 的哈希槽全部转移到 10.211.55.7:6379 节点上,可以执行如下命令:

redis-cli --cluster reshard 10.211.55.6:6379 --cluster-from 5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad --cluster-to a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 --cluster-slots 5461 --cluster-yes


# 输出
...
Moving slot 5454 from 10.211.55.6:6379 to 10.211.55.7:6379:
Moving slot 5455 from 10.211.55.6:6379 to 10.211.55.7:6379:
Moving slot 5456 from 10.211.55.6:6379 to 10.211.55.7:6379:
Moving slot 5457 from 10.211.55.6:6379 to 10.211.55.7:6379:
Moving slot 5458 from 10.211.55.6:6379 to 10.211.55.7:6379:
Moving slot 5459 from 10.211.55.6:6379 to 10.211.55.7:6379:
Moving slot 5460 from 10.211.55.6:6379 to 10.211.55.7:6379:

# 观察现在 master 节点的哈希槽的分配情况
redis-cli -p 6379 cluster nodes

# 可以看到 10.211.55.6:6379 已经没有了哈希槽,而 10.211.55.7:6379 的哈希槽范围变成了 [0-10922]
e667c40572bb7a34fae03ee407e0849728537497 10.211.55.8:6380@16380 master - 0 1681222117588 11 connected 10923-16383
a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 10.211.55.7:6379@16379 master - 0 1681222117000 13 connected 0-10922
35c17301dac6d01cdd06b01c449c895e1d5f6028 10.211.55.8:6379@16379 slave e667c40572bb7a34fae03ee407e0849728537497 0 1681222117892 11 connected
d070ed606c2067bca37f7a079971eed5d67b8841 10.211.55.6:6380@16380 slave a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 0 1681222117000 13 connected
32f44e3aab49194db8e5e819a1dc851a86a1b584 10.211.55.7:6380@16380 slave a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 0 1681222116557 13 connected
5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad 10.211.55.6:6379@16379 myself,master - 0 1681222116000 8 connected

哈希槽的自动均衡操作

# 执行 rebalance 命令
redis-cli --cluster rebalance --cluster-use-empty-masters 10.211.55.6:6379

# 输出
>>> Performing Cluster Check (using node 10.211.55.6:6379)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Rebalancing across 3 nodes. Total weight = 3.00
Moving 5462 slots from 10.211.55.7:6379 to 10.211.55.6:6379
###########################################################
...
###########################################################

# 查看哈希槽节点分布情况
redis-cli -p 6379 cluster nodes

# 输出,可以看到 10.211.55.6:6379 的哈希槽范围现在是 [0-5461]
e667c40572bb7a34fae03ee407e0849728537497 10.211.55.8:6380@16380 master - 0 1681222393532 11 connected 10923-16383
a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 10.211.55.7:6379@16379 master - 0 1681222394571 13 connected 5462-10922
35c17301dac6d01cdd06b01c449c895e1d5f6028 10.211.55.8:6379@16379 slave e667c40572bb7a34fae03ee407e0849728537497 0 1681222394055 11 connected
d070ed606c2067bca37f7a079971eed5d67b8841 10.211.55.6:6380@16380 slave a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 0 1681222394256 13 connected
32f44e3aab49194db8e5e819a1dc851a86a1b584 10.211.55.7:6380@16380 slave 5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad 0 1681222393018 14 connected
5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad 10.211.55.6:6379@16379 myself,master - 0 1681222393000 14 connected 0-5461

常用的集群的操作命令

检查节点的健康状态

# 执行 check 命令,可以观察集群节点的健康状态
redis-cli --cluster check 10.211.55.6:6379

# 输出
10.211.55.6:6379 (5a54e2bb...) -> 1 keys | 5462 slots | 1 slaves.
10.211.55.8:6380 (e667c405...) -> 1 keys | 5461 slots | 1 slaves.
10.211.55.7:6379 (a1a7be53...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 2 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 10.211.55.6:6379)
M: 5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad 10.211.55.6:6379
   slots:[0-5461] (5462 slots) master
   1 additional replica(s)
M: e667c40572bb7a34fae03ee407e0849728537497 10.211.55.8:6380
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: a1a7be53d2ebc9d54fb18c59f31171cf6d371f29 10.211.55.7:6379
   slots:[5462-10922] (5461 slots) master
   1 additional replica(s)
S: 35c17301dac6d01cdd06b01c449c895e1d5f6028 10.211.55.8:6379
   slots: (0 slots) slave
   replicates e667c40572bb7a34fae03ee407e0849728537497
S: d070ed606c2067bca37f7a079971eed5d67b8841 10.211.55.6:6380
   slots: (0 slots) slave
   replicates a1a7be53d2ebc9d54fb18c59f31171cf6d371f29
S: 32f44e3aab49194db8e5e819a1dc851a86a1b584 10.211.55.7:6380
   slots: (0 slots) slave
   replicates 5a54e2bb5a897956d2d1a08893be62c5fb0ed5ad
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

添加一个节点

这里只提供相关命令,读者可以自行进行操作。

# 添加主节点
redis-cli --cluster add-node [new node ip]:[new node port] [one of master node ip]:[master node port]

# 添加从节点
redis-cli --cluster add-node [new node ip]:[new node port] [one of master node ip]:[master node port] --cluster-slave --cluster-master-id [masster-node-id]

# 重新分配哈希槽
# 可以执行自动分配
redis-cli --cluster rebalance --cluster-use-empty-masters [one of master node ip]:[master node port]

# 可以从指定的节点移动部分的哈希槽到新添加的节点
redis-cli --cluster reshard [one of master node ip]:[master node port] --cluster-from [from node id] --cluster-to [to node id] --cluster-slots [number of slots] --cluster-yes

删除一个节点

删除一个节点,首先需要把改节点的哈希槽移除。

# 移除改节点的哈希槽
redis-cli --cluster reshard [one of master node ip]:[master node port] --cluster-from [from node id] --cluster-to [to node id] --cluster-slots [the number of slots] --cluster-yes

# 删除该节点
redis-cli --cluster del-node [one of master node ip]:[master node port] [node-id]

Redis Cluster 的优点

  • 配置简单,官方提供完整的操作手册。
  • 系统的伸缩变得容易,解决大量数据的问题,数据的再平衡容易实现。
  • 每个主节点可配置从节点,可以做到每个主节点的失效救援。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GettingReal

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值