「进击 Redis」二十七、Redis cluster 集群搭建

34 篇文章 5 订阅
20 篇文章 0 订阅

前言

Redis 系列第二十七篇,也是Cluster 集群模式第二篇。 上篇我们已经通过画图与对比的方式将Cluster 虚拟槽寻址思路、取余hash一致性hash寻址的原理弄清楚了,还有不熟悉的好哥哥可以看你竟然还不知道 hash slot 这篇了解一下。这一篇的话主要是对Cluster 集群的搭建与使用,上一篇又说到分成两篇的,想想篇幅还是不要那么长,于是乎就有了一篇。

这一篇的话基本上都是一些实践性的内容,好哥哥们还是一样不要偷懒哦。有杠精好哥哥会说了,怎么哨兵模式的搭建你怎么不弄?有这么杠的好哥哥估计没有认真看图解 Redis 哨兵模式,在这一片总结的地方已经说了原因,好哥哥们别闹。
bienao

概述

图解 Redis 哨兵模式一文中有提到哨兵模式的一些局限性,比如说不支持主从复制、不能够支持超大数据量的存储。在 Redis 的 3.0 版本正式推出了 Cluster作为 Redis 的分布式解决方案。当遇到单机内存、并发、流量等瓶颈时,可以采用Cluster架构方案达到负载均衡的目的。

Cluster 非常优雅的解决了在哨兵或者主从复制两种模式下的一些问题,当然Cluster 中也存在主从复制的功能。在学习Cluster 集群模式前,我们需要把Cluster搭建起来,整个过程分为Redis实例准备节点握手分配槽空间。至于实例准备这个的话我们用的还是一台机器然后弄多个实例出来,下面让我们开始吧。

Redis 实例准备

分布图
Cluster 集群模式一般由多个主节点和多个从节点组成,节点数量至少为 6 个才能保证组成完整高可用的集群。解释一下为什么要六个节点,如上图,整个集群环境一共三台机器,假设服务器1.1宕掉了,这个时候集群环境还是可以继续跑的,因为在服务器1.3上面有一台M1的从节点S1。假设低于三台的话,那整个集群环境就会丢失某一部分数据,因为已经没有从节点可以切换到主节点了。

搭建Cluster 集群需要每个节点都开启配置cluster-enabled yes,然后的话所有节点的配置尽量放在统一的目录下,由于我们这边使用的是一台服务器,所以只能用名字加端口号来区分。一般划分为confdatalog三个目录,分别存放配置、数据和日志相关文件。主要配置如下:

# 节点端口
port 6379
#  开启集群模式
cluster-enabled yes
#  节点超时时间,单位毫秒
cluster-node-timeout 15000
#  集群内部配置文件
cluster-config-file "nodes-6379.conf"

其他配置和单机模式一致即可,配置文件命名规则redis-{port}.conf,准备好配置后启动所有节点,执行以下命令:

redis-server conf/redis-6379.conf
redis-server conf/redis-6380.conf
redis-server conf/redis-6381.conf
redis-server conf/redis-6382.conf
redis-server conf/redis-6383.conf
redis-server conf/redis-6384.conf

第一次启动时如果没有集群配置文件,会自动创建一份,文件名称采用cluster-config-file参数项控制,建议采用node-{port}.conf格式定义,通过使用端口号区分不同节点,防止同一机器下多个节点彼此覆盖,造成集群信息异常。如果启动时存在集群配置文件,节点会使用配置文件内容初始化集群信息。

集群模式的 Redis 除了原有的配置文件之外又加了一份集群配置文件。当集群内节点信息发生变化,如添加节点、节点下线、故障转移等。节点会自动保存集群状态到配置文件中。需要注意的是,Redis 自动维护集群配置文件,不要手动修改,防止节点重启时产生集群信息错乱。

首次启动后生成的配置文件内容如下:

#cat data/nodes-6379.conf
cfb28ef1deee4e0fa78da86abe5d24566744411e 127.0.0.1:6379 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0

文件内容记录了集群初始状态,这里最重要的是节点ID,它是一个4016进制字符串,用于唯一标识集群内一个节点,之后很多集群操作都要借助于节点ID来完成。需要注意是,节点ID不同于运行ID(runid)。节点ID在集群初始化时只创建一次,节点重启时会加载集群配置文件进行重用,而 Redis 的运行ID每次重启都会变化。执行cluster nodes命令获取6380集群节点状态:

127.0.0.1:6380>cluster nodes
8e41673d59c9568aa9d29fb174ce733345b3e8f1 127.0.0.1:6380 myself,master - 0 0 0 connected

由于没有将其余的几台实例连接成为一个集群,所以这里是没有节点的。

节点握手

节点握手是指一批运行在集群模式下的节点通过Gossip协议彼此通信,达到感知对方的过程。节点握手是集群彼此通信的第一步,由客户端发起命令: cluster meet{ip}{port}
meet
过程如下:

  1. 节点6379本地创建6380节点信息对象,并发送meet消息。
  2. 节点6380接受到meet消息后,保存6379节点信息并回复pong消息。
  3. 之后节点63796380彼此定期通过ping/pong消息进行正常的节点通信。

下面分别执行meet命令让其他节点加入到集群中:

127.0.0.1:6379>cluster meet 127.0.0.1 6381
127.0.0.1:6379>cluster meet 127.0.0.1 6382
127.0.0.1:6379>cluster meet 127.0.0.1 6383
127.0.0.1:6379>cluster meet 127.0.0.1 6384

我们只需要在集群内任意节点上执行cluster meet命令加入新节点,握手状态会通过消息在集群内传播,这样其他节点会自动发现新节点并发起握手流程。最后执行cluster nodes命令确认6个节点都彼此感知并组成集群:

127.0.0.1:6379> cluster nodes
4fa7eac4080f0b667ffeab9b87841da49b84a6e4 127.0.0.1:6384 master - 0 1468073975551
5 connected
cfb28ef1deee4e0fa78da86abe5d24566744411e 127.0.0.1:6379 myself,master - 0 0 0 connected
be9485a6a729fc98c5151374bc30277e89a461d8 127.0.0.1:6383 master - 0 1468073978579
4 connected
40622f9e7adc8ebd77fca0de9edfe691cb8a74fb 127.0.0.1:6382 master - 0 1468073980598
3 connected
8e41673d59c9568aa9d29fb174ce733345b3e8f1 127.0.0.1:6380 master - 0 1468073974541
1 connected
40b8d09d44294d2e23c7c768efc8fcd153446746 127.0.0.1:6381 master - 0 1468073979589
2 connected

然后,建立握手之后集群还不能正常工作的,这个时候的集群处于下线状态,所有的数据读写都被禁止。通过如下命令可以看到:

## 设置一个key到Redis
127.0.0.1:6379> set hello redis
(error) CLUSTERDOWN The cluster is down
## 查看集群状态
127.0.0.1:6379> cluster info
cluster_state:fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
.......

从输出内容可以看到,被分配的槽(cluster_slots_assigned)是0,由于目前所有的槽没有分配到节点,因此集群无法完成槽到节点的映射。只有当16384个槽全部分配给节点后,集群才进入在线状态。

分配槽空间

Redis 集群把所有的数据映射到16384个槽中。每个key会映射为一个固定的槽,只有当节点分配了槽,才能响应和这些槽关联的键命令。通过cluster addslots命令为节点分配槽。这里利用bash特性批量设置槽(slots),把16384slot平均分配给637963806381三个节点(三主三从),命令如下:

## 分配槽空间
redis-cli -h 127.0.0.1 -p 6379 cluster addslots {0...5461}
redis-cli -h 127.0.0.1 -p 6380 cluster addslots {5462...10922}
redis-cli -h 127.0.0.1 -p 6381 cluster addslots {10923...16383}
## 查看集群状态
127.0.0.1:6379> 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:5
cluster_my_epoch:0
cluster_stats_messages_sent:4874
cluster_stats_messages_received:4726

当前集群状态是OK,集群进入在线状态。所有的槽都已经分配给节点,执行cluster nodes命令可以看到节点和槽的分配关系:

127.0.0.1:6379> cluster nodes
4fa7eac4080f0b667ffeab9b87841da49b84a6e4 127.0.0.1:6384 master - 0 14680762401235 connected
cfb28ef1deee4e0fa78da86abe5d24566744411e 127.0.0.1:6379 myself,master - 0 0 0 connected0-5461
be9485a6a729fc98c5151374bc30277e89a461d8 127.0.0.1:6383 master - 0 14680762396224 connected
40622f9e7adc8ebd77fca0de9edfe691cb8a74fb 127.0.0.1:6382 master - 0 14680762406283 connected
8e41673d59c9568aa9d29fb174ce733345b3e8f1 127.0.0.1:6380 master - 0 14680762376061 connected
5462-10922
40b8d09d44294d2e23c7c768efc8fcd153446746 127.0.0.1:6381 master - 0 14680762386122 connected
10923-16383

主从复制

经过上面的步骤,目前还有三个节点没有使用,作为一个完整的集群,每个负责处理槽的节点应该具有从节点,保证当它出现故障时可以自动进行故障转移。集群模式下,Reids 节点角色分为主节点和从节点。首次启动的节点和被分配槽的节点都是主节点,从节点负责复制主节点槽信息和相关的数据。使用clusterreplicate{nodeId}命令让一个节点成为从节点。其中命令执行必须在对应的从节点上执行,nodeId是要复制主节点的节点ID,命令如下:

## 操作主从复制
127.0.0.1:6382>cluster replicate cfb28ef1deee4e0fa78da86abe5d24566744411e
OK
127.0.0.1:6383>cluster replicate 8e41673d59c9568aa9d29fb174ce733345b3e8f1
OK
127.0.0.1:6384>cluster replicate 40b8d09d44294d2e23c7c768efc8fcd153446746
OK
## 查看集群状态
127.0.0.1:6379> cluster nodes
4fa7eac4080f0b667ffeab9b87841da49b84a6e4 127.0.0.1:6384 slave 40b8d09d44294d2e23c7c768efc8fcd153446746 0 1468076865939 5 connected
cfb28ef1deee4e0fa78da86abe5d24566744411e 127.0.0.1:6379 myself,master - 0 0 0 connected 0-5461
be9485a6a729fc98c5151374bc30277e89a461d8 127.0.0.1:6383 slave 8e41673d59c9568aa9d29fb174ce733345b3e8f1 0 1468076868966 4 connected
40622f9e7adc8ebd77fca0de9edfe691cb8a74fb 127.0.0.1:6382 slave cfb28ef1deee4e0fa78da86abe5d24566744411e 0 1468076869976 3 connected
8e41673d59c9568aa9d29fb174ce733345b3e8f1 127.0.0.1:6380 master - 0 1468076870987 1 connected 5462-10922
40b8d09d44294d2e23c7c768efc8fcd153446746 127.0.0.1:6381 master - 0 1468076867957 2 connected 10923-16383

好了,到这里的话整个集群就搭好了,由6个节点构成,3个主节点负责处理槽和相关数据,3个从节点负责故障转移。手动搭建整个流程还是很繁琐的,也是很容易出错的。不过对于理解集群建立的流程和细节来说还是很有帮助的。

总结

整个搭建过程还是挺麻烦的,Redis 官方也提供了redis-trib.rb工具用于快速搭建集群。这里的话我们就不弄了,用手工搭建出来后,对于理解整个集群还是很有帮助的,好哥哥们不要偷懒哦,动手实践一下基本上就能知道整个过程和一些细节了。后面的话还有一篇关于cluster一些原理性的内容,下篇应该就能弄完了。

本期就到这啦,有不对的地方欢迎好哥哥们评论区留言,另外求关注、求点赞

上一篇: 你竟然还不知道 hash slot

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
搭建一个 Redis Cluster 集群的步骤如下: 1. 下载并安装 Redis:在 Redis 官网下载 Redis 并安装。安装完成后,可以通过 redis-cli 命令来测试 Redis 是否正常工作。 2. 配置 Redis:编辑 redis.conf 文件,设置 Redis 的端口号、密码、数据存储路径等参数。如果需要启用集群功能,需要在配置文件中添加 cluster-enabled yes 和 cluster-config-file 路径等配置信息。 3. 创建 Redis Cluster:使用 create-cluster 脚本创建 Redis Cluster,该脚本可以在 Redis 安装目录的 utils/create-cluster 目录下找到。需要指定 Redis Cluster 的端口号、节点数量等参数。例如,执行以下命令可以创建一个 3 个节点的 Redis Cluster: ``` $ create-cluster start --port 7000 --replicas 0 --num-nodes 3 ``` 4. 添加节点:使用 add-node 脚本向 Redis Cluster 添加新的节点。例如,执行以下命令可以将一个新的节点添加到 Redis Cluster 中: ``` $ redis-cli --cluster add-node 127.0.0.1:7000 127.0.0.1:7001 ``` 5. 删除节点:使用 del-node 脚本从 Redis Cluster 删除节点。例如,执行以下命令可以将一个节点从 Redis Cluster 中删除: ``` $ redis-cli --cluster del-node 127.0.0.1:7000 1234567890abcdef1234567890abcdef12345678 ``` 6. 扩展 Redis Cluster:使用 reshard 脚本可以扩展 Redis Cluster 的节点数量。例如,执行以下命令可以将 Redis Cluster 的节点数量扩展到 6 个: ``` $ redis-cli --cluster reshard 127.0.0.1:7000 ``` 在实际应用中,需要根据具体的业务场景和需求,选择合适的 Redis Cluster 集群方案。同时,在搭建 Redis Cluster 集群时,需要考虑到分布式环境下的各种异常情况,如网络延迟、节点故障等,从而设计出高可用、高性能、高可靠的 Redis Cluster 集群方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值