环境说明
物理机:ubuntu:20.04
Redis:6.0.7
基本命令
- cluster info:查看集群信息
- cluster nodes:查看节点信息
- cluster meet :将节点加入到工作集群
- cluster keyslot key:计算key的CRC16算法结果值
- cluster addslots slot:设置槽位
拓扑图
搭建说明
如上图所示,本次搭建3台Master,6台Slave
实际应用中Redis节点是需要部署到不同物理机,笔者作为演示,这块使用单机的不同端口跑多个Redis节点服务
测试环境:7000、8000、9000为主服务器(master)
7001、7002 slaveof 7000
8001、8002 slaveof 8000
9001、9002 slaveof 9000
Cluster集群原生搭建
第一步 准备工作
我们先创建/usr/local/redis-cluster
目录,接着在该目录下分别创建7000、8000、9000三个目录
# 分别用于存放三个集群
mkdir /usr/local/redis-cluster/7000
mkdir /usr/local/redis-cluster/8000
mkdir /usr/local/redis-cluster/9000
第一步 修改配置文件
# 指定服务启动监听的端口
port 7000
# 保存pid的文件
pidfile /var/run/redis_6379.pid
# 启用Cluster集群
cluster-enabled yes
# 保存集群信息的文件,每台节点都会同步集群信息并保存到各自的文件中
cluster-config-file nodes-7000.conf
第二步 启动所有Master节点
redis-server 7000/redis.conf
redis-server 8000/redis.conf
redis-server 9000/redis.conf
查看服务是否已启动
注意事项:此时节点是无法写入数据的,因为没有设置哈希槽Slot,数据不知道写入哪个节点,如下图:
第三步 集群meet
集群Master节点都虽然已经启动,但是目前节点之间互相还没有关联,互相都不认识,还没有形成集群。查看集群信息,发现只有自身节点。
连接上其中一台Master服务器,然后通过命令cluster meet <ip> <port>
来让节点相互认识,并形成网状结构
# 将192.168.3.12改为你自己的ip地址
cluster meet 192.168.3.12 8000
cluster meet 192.168.3.12 9000
操作如下图:
重新查看集群信息
第四步 启动Slave节点
上面我们已经顺利启动了3个Master服务,接着我们依次启动6个从服务器。
启动Slave节点和Master节点步骤一样,启动完成后如下所示:
第五步 主从分配
启动的节点若不做配置,默认都是master,需要 进行主从服务器的指定。
主从分配之前,需要将新启动的Slave节点meet一下,先让节点加入到集群
添加后节点如下:
通过命令cluster replicate <node-id>
将Slave节点分配到对应的Master节点下面。(这里只演示7000节点的分配,8000和9000类似)
redis-cli -p 7001 cluster replicate 30a248d524adfb491588d8ae754e65827d455d43
redis-cli -p 7002 cluster replicate 30a248d524adfb491588d8ae754e65827d455d43
第六步 指定槽位
前面已经说过,没有为Master指定Slot槽位,是无法写入数据的。cluster keyslot key
该命令可以查看指定key的CRC16计算的值。
Redis集群默认有16384个槽位,现有3台Master节点,平均进行分配。
- Master-7000:0~5461
- Master-8000:5462~10922
- Master-9000:10923~16383
cluster addslot slot [槽位下标]
该命令用来设置节点的槽位。
为了快速分配,写了个shell脚本,如下:
#!/bin/sh
# 读取端口
echo -n 'port:'
read port
#槽位起始下标
echo -n 'start:'
read s
#槽位结束下标
echo -n 'end:'
read e
#循环设置槽位
for i in $(seq $s $e)
do
redis-cli -h 192.168.3.12 -p $port cluster addslots $i
echo redis-cli -h 192.168.3.12 -p $port cluster addslots $i;
done
运行脚本,批量设置槽位,设置完成后查看如下图:
集群测试
指派好槽位后,集群的搭建工作就算完成了。
现在可以正常写入数据了吗?
答案是否定的,可以看到key通过CRC16算法计算分配在9000节点,如果不通过集群模式连接,无法重定向到9000节点
以集群的模式去连接:redis-cli -c
通过集群模式连接,会自动重定向到对应节点。可以看到在执行命令时,我们连接的7000的服务器,执行命令之后,自己跳转到9000的服务器。
Redis-cli快速搭建
上面记录的是自己原生搭建Redis Cluster集群的方式,比较繁琐麻烦,Redis提供了一种更简单的方式来快速搭建集群,先使用redis-cli --cluster help
命令会显示一些搭建集群的帮助信息。
快速搭建集群
创建集群命令:redis-cli --cluster create host1:port1 ... hostN:portN --cluster-replicas [主从节点的比例]
redis-cli --cluster create 192.168.3.12:7000 192.168.3.12:7001 192.168.3.12:7002 192.168.3.12:8000 192.168.3.12:8001 192.168.3.12:8002 192.168.3.12:9000 192.168.3.12:9001 192.168.3.12:9002 --cluster-replicas 2
查看节点信息
可以看到redis-cli工具一条命令即可快速搭建集群,自动分配主从节点,分配槽位。
集群扩容
假设此时的性能没有达到预期,需要进行扩容。
Redis支持线性扩容,官方宣称可以支持扩容到1000个节点。
扩容命令: redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-slave --cluster-master-id <arg>
- - -cluster-slave:指明以从节点的方式添加到集群中,不填默认以主节点方式添加
- - -cluster-master-id :以从节点方式添加需要指定主服务器,其中
arg
参数就是主服务器的node-id
例如我们将10000、10001、10002添加到集群。
#将10000节点以主节点的方式添加到集群
redis-cli --cluster add-node 192.168.3.12:10000 192.168.3.12:7000
#将10001节点作为10000的从节点添加到集群
redis-cli --cluster add-node 192.168.3.12:10001 192.168.3.12:7000 --cluster-slave --cluster-master-id 370c56d43ac0a4cf9f220eeff4945db0db0ab46e
#将10002节点作为10000的从节点添加到集群
redis-cli --cluster add-node 192.168.3.12:10002 192.168.3.12:7000 --cluster-slave --cluster-master-id 370c56d43ac0a4cf9f220eeff4945db0db0ab46e
添加完主节点后信息如下
添加完所有节点后的信息
迁移槽位和数据
新扩容的Master节点(10000节点)没有默认槽位,是不会被写入数据的,需要进行槽位的分配和数据的迁移。槽位和key是绑定的,槽位重新分配意味着数据需要重新迁移。
迁移命令:redis-cli --cluster reshard ip:port
redis-cli --cluster reshard 192.168.3.12:10000 # 输入分配的槽位数量
How many slots do you want to move (from 1 to 16384)? 1000
What is the receiving node ID? # 输入要分配给哪个节点的node-id
Source node #1: #要从哪个节点取出槽位分配给新节点 1.指定节点node-id:从该主节点取 2.all:表示从所有节点中平均取
分配的槽位如下,我是从8000节点分出来1000个槽位给了10000这个主节点。
集群缩容
如果集群的性能过剩,也可以选择移除部分节点,Redis同样支持。
缩容步骤如下:
- 移除节点前,需要将该节点的槽位和数据重新分配到其他master节点
- 槽位和数据迁移后,就可以依次移除从节点和主节点
迁移槽位和数据
我们将8000节点上剩下的槽位分配到10000节点上
迁移命令:redis-cli --cluster reshard ip:port --cluster-from <node-id> --cluster-to <node-id> --cluster-slots <slot-number>
- - -cluster-from:来自那台节点
- - -cluster-to:分配到哪台节点去
- - -cluster-slots:迁移的槽位数量
# 将8000节点上剩下的槽位全部迁移到10000节点上
redis-cli --cluster reshard 192.168.3.12:7000 --cluster-from 6e18af30a399e17356ecb35fa6fc6f29a9d326fa --cluster-to 370c56d43ac0a4cf9f220eeff4945db0db0ab46e --cluster-slots 4461
可以看到8000这个节点后面已经没有槽位了。
移除节点
移除命令:redis-cli --cluster del-node host:port node_id
# 移除 8000节点以及它的两个从节点8001和8002
redis-cli --cluster del-node 192.168.3.12:7000 6e18af30a399e17356ecb35fa6fc6f29a9d326fa
可以看到,Redis会自动将其SHUTDOWN。