环境说明

物理机:ubuntu:20.04
Redis:6.0.7

基本命令

  • cluster info:查看集群信息
  • cluster nodes:查看节点信息
  • cluster meet :将节点加入到工作集群
  • cluster keyslot key:计算key的CRC16算法结果值
  • cluster addslots slot:设置槽位

拓扑图

redis 1500万 数据 redis 10060_数据

搭建说明

如上图所示,本次搭建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

查看服务是否已启动

redis 1500万 数据 redis 10060_redis 1500万 数据_02


注意事项:此时节点是无法写入数据的,因为没有设置哈希槽Slot,数据不知道写入哪个节点,如下图:

redis 1500万 数据 redis 10060_redis_03

第三步 集群meet

集群Master节点都虽然已经启动,但是目前节点之间互相还没有关联,互相都不认识,还没有形成集群。查看集群信息,发现只有自身节点。

redis 1500万 数据 redis 10060_数据_04


连接上其中一台Master服务器,然后通过命令cluster meet <ip> <port>来让节点相互认识,并形成网状结构

# 将192.168.3.12改为你自己的ip地址
cluster meet 192.168.3.12 8000
cluster meet 192.168.3.12 9000

操作如下图:

redis 1500万 数据 redis 10060_Redis_05


重新查看集群信息

redis 1500万 数据 redis 10060_Redis_06

第四步 启动Slave节点

上面我们已经顺利启动了3个Master服务,接着我们依次启动6个从服务器。

启动Slave节点和Master节点步骤一样,启动完成后如下所示:

redis 1500万 数据 redis 10060_数据_07

第五步 主从分配

启动的节点若不做配置,默认都是master,需要 进行主从服务器的指定。

主从分配之前,需要将新启动的Slave节点meet一下,先让节点加入到集群

redis 1500万 数据 redis 10060_redis_08


添加后节点如下:

redis 1500万 数据 redis 10060_数据_09


通过命令cluster replicate <node-id>将Slave节点分配到对应的Master节点下面。(这里只演示7000节点的分配,8000和9000类似)

redis-cli -p 7001 cluster replicate 30a248d524adfb491588d8ae754e65827d455d43
redis-cli -p 7002 cluster replicate 30a248d524adfb491588d8ae754e65827d455d43

redis 1500万 数据 redis 10060_数据_10

第六步 指定槽位

前面已经说过,没有为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

运行脚本,批量设置槽位,设置完成后查看如下图:

redis 1500万 数据 redis 10060_Redis_11

集群测试

指派好槽位后,集群的搭建工作就算完成了。

现在可以正常写入数据了吗?

redis 1500万 数据 redis 10060_redis 1500万 数据_12

答案是否定的,可以看到key通过CRC16算法计算分配在9000节点,如果不通过集群模式连接,无法重定向到9000节点

以集群的模式去连接:redis-cli -c

redis 1500万 数据 redis 10060_Redis_13

通过集群模式连接,会自动重定向到对应节点。可以看到在执行命令时,我们连接的7000的服务器,执行命令之后,自己跳转到9000的服务器。

Redis-cli快速搭建

上面记录的是自己原生搭建Redis Cluster集群的方式,比较繁琐麻烦,Redis提供了一种更简单的方式来快速搭建集群,先使用redis-cli --cluster help命令会显示一些搭建集群的帮助信息。

redis 1500万 数据 redis 10060_redis 1500万 数据_14

快速搭建集群

创建集群命令: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 1500万 数据 redis 10060_Redis_15


可以看到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

添加完主节点后信息如下

redis 1500万 数据 redis 10060_数据_16


添加完所有节点后的信息

redis 1500万 数据 redis 10060_Redis_17

迁移槽位和数据

新扩容的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 1500万 数据 redis 10060_redis 1500万 数据_18

集群缩容

如果集群的性能过剩,也可以选择移除部分节点,Redis同样支持。
缩容步骤如下:

  1. 移除节点前,需要将该节点的槽位和数据重新分配到其他master节点
  2. 槽位和数据迁移后,就可以依次移除从节点和主节点

迁移槽位和数据

我们将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 1500万 数据 redis 10060_Redis_19


移除节点

移除命令:redis-cli --cluster del-node host:port node_id

# 移除 8000节点以及它的两个从节点8001和8002
redis-cli --cluster del-node 192.168.3.12:7000 6e18af30a399e17356ecb35fa6fc6f29a9d326fa

redis 1500万 数据 redis 10060_Redis_20


可以看到,Redis会自动将其SHUTDOWN。