著者以前のブログは、ビルドサービスと「センチネルモード」へのRedis「マスター・スレーブレプリケーション」を導入しますが、いくつかの問題があり、両方のサービスが未解決のままで、例えば:
- シングルマスタ書き込み性能のボトルネック
- データストレージは、限られたスタンドアロンのメモリに分散することができません
これらの問題を解決するために、Redisのは、よりスケーラブルな、クラスタークラスタープログラムの優れた可用性を提供します。
何RedisのクラスタAクラスタですか?
Redisのクラスタ分散サーバクラスタは、特性データの複製を有するマスター組成物からクラスタ内の複数のノードのクラスタであり、データ片の可用性が格納されます。
Redisのクラスタクラスタセンチネルセンチネルは、関数ノードおよびフェイルオーバーを完了するために、削除する必要はありません。
各ノードは、クラスタモードに設定する必要があり、このモードでは、クラスタノードの中心ではなく、水平にスケーラブルな、公式文書が直線千のノードに拡張することができると述べました。
Redisのクラスタクラスタのパフォーマンスと可用性は、より良い「マスター・スレーブレプリケーション」と「見張りモード」の設定よりも、また、エンタープライズサービスに適して非常に簡単です。
クラスタクラスタのネイティブ構造
図アーキテクチャは
、上記の3つのマスター、6組のスレーブを構築し、この環境を示します。
Redisのデフォルト16,384スロットがある、これらのスロットを書き込むことができませんそれ以外の場合は、いくつかのデータにつながる、すべてのマスターに割り当てる必要があります。
データが書き込まれると、RedisのCRC16アルゴリズムは番号キーを計算するために使用される、ハッシュコードは、スロットモジュロ16384で決定された値と同様であり、マスタスロットにノードが存在するデータを書き込みます。
書き込みデータにマスターした後、データ、すなわちマスタコピーから、対応するスレーブノードに同期します。
単一のマスターダウンした後、自動的にRedisのを失敗し、マスターにスレーブを新しいマスターの下で推進しました。
实际应用中Redis节点需要部署到不同的物理机,笔者没有那么多的物理机,遂用单机的不同端口跑多个Redis节点服务。
测试环境:8001、8004、8007为Master。
8002、8003 slaveof 8001
8005、8006 slaveof 8004
8008、8009 slaveof 8007
几个基本命令
- cluster info:查看集群信息
- cluster nodes:查看节点信息
- cluster meet ip port:将节点加入到工作集群
- cluster keyslot key:计算Key的CRC16算法结果值
- cluster addslots slot (槽下标):设置槽位
- cluster replicate (master node-id):将节点设为指定Master的Slave
1、创建配置文件
拷贝Redis提供的默认配置文件,做一些常规修改(不赘述),搭建集群主要修改如下:
# 启用Cluster集群
cluster-enabled yes
# 保存集群信息的文件,每台节点都会同步集群信息并保存到各自的文件中
cluster-config-file nodes-8001.conf
2、依次启动Master节点
redis-server 8001/redis.conf
redis-server 8004/redis.conf
redis-server 8007/redis.conf
查看服务是否启动成功:
注意:这时候节点是无法写入数据的,因为没有设置哈希槽Slot,数据不知道该写入哪个节点,如下图:
3、集群meet
集群Master节点都虽然已经启动,但是目前节点之间互相还没有关联,互相都不认识,还没有形成集群。
查看集群信息,发现只有自身节点。
cluster meet ip port
通过该命令来让节点互相认识,并形成网状结构。
cluster meet 192.168.1.120 8004
cluster meet 192.168.1.120 8007
重新查看集群信息
4、启动Slave节点
除了Master,还得有Slave节点,否则无法实现高可用和数据备份。
启动Slave节点和Master步骤一样,这里不再赘述,启动完成后如下图所示:
5、主从分配
启动的节点若不做配置,默认都是Master,需要进行主从分配。
主从分配之前,需要将新启动的Slave节点meet一下,先让节点加入到集群。
cluster replicate node-id
通过该命令来分配主从。
登录到Slave节点执行该命令,node-id为Master节点的id。
查看节点的node-id
将Slave节点分配到Master节点下。(演示8002、8003,其他不赘述)
redis-cli -p 8002 cluster replicate 22bbad3e9cd6065861f13b95cef5d437483c6360
OK
redis-cli -p 8003 cluster replicate 22bbad3e9cd6065861f13b95cef5d437483c6360
OK
全部分配完成后,如下图所示:
6、指派槽位
前面已经说过,没有为Master指定Slot槽位,是无法写入数据的。
cluster keyslot key
该命令可以查看指定Key的CRC16计算的值。
Redis集群默认有16384个槽位,现有3台Master节点,平均进行分配。
- Master-8001:0~5461
- Master-8004:5462~10922
- Master-8007:10923~16383
cluster addslots 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.1.120 -p $port cluster addslots $i
echo redis-cli -h 192.168.1.120 -p $port cluster addslots $i;
done
运行脚本,批量设置槽位,设置完成后查看如下图:
7、集群测试
指派好槽位后,集群的搭建工作就算完成了。
现在可以正常写入数据了:
以集群的模式去连接:redis-cli -c
Jedis集群写入数据
Set<HostAndPort> hostAndPorts = new HashSet<>(3);
hostAndPorts.add(new HostAndPort("192.168.1.120", 8001));
hostAndPorts.add(new HostAndPort("192.168.1.120", 8004));
hostAndPorts.add(new HostAndPort("192.168.1.120", 8007));
JedisCluster jedisCluster = new JedisCluster(hostAndPorts);
for (int i = 0; i < 100; i++) {
jedisCluster.set(String.valueOf(i), String.valueOf(i));
}
jedisCluster.close();
100个数据会被分散到3台Master里分片存储。
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.1.120:8001 192.168.1.120:8002 192.168.1.120:8003 192.168.1.120:8004 192.168.1.120:8005 192.168.1.120:8006 192.168.1.120:8007 192.168.1.120:8008 192.168.1.120:8009 --cluster-replicas 2
查看节点信息
redis-cli工具一条命令即可快速搭建集群,自动分配主从节点,分配槽位。
集群扩容
如果集群的性能达不到预期,可以进行扩容。
Redis Cluster支持线性扩容,官方宣称可以扩容至1000个节点。
扩容命令:redis-cli --cluster add-node new_host:new_port 存在的IP:存在的端口
。
节点默认作为Master被添加,如果需要指明为Slave,加参数:--cluster-slave --cluster-master-id Master的node-id
。
例えば、7001,7002,7003は、クラスタに追加しました。
# 7001Master
redis-cli --cluster add-node 192.168.1.120:7001 192.168.1.120:8001
# 7002作为7001的Slave
redis-cli --cluster add-node 192.168.1.120:7002 192.168.1.120:7001 --cluster-slave --cluster-master-id f8bbd9f97db60f4b00a80a2bdcf555e95559582a
# 7003作为7001的Slave
redis-cli --cluster add-node 192.168.1.120:7003 192.168.1.120:7001 --cluster-slave --cluster-master-id f8bbd9f97db60f4b00a80a2bdcf555e95559582a
ノードを追加したら、できるcluster nodes
コマンドノード情報を参照してください。
スロットとデータ移行
マスタノードの拡張スロットにはデータが、スロット割り当て及び移行データの必要性が書き込まれていないことを、デフォルトではありません。
槽位和Key是绑定的,槽位重新分配意味着数据需要重新迁移。
コマンド:redis-cli --cluster reshard ip port
。
例えば:7001に新規参入者に割り当てられたスロット4096。
redis-cli --cluster reshard 192.168.1.120:8001
How many slots do you want to move (from 1 to 16384)? 4096 #输入分配的槽位数量
What is the receiving node ID? #输入要分配给哪台节点的node-id
Source node #1: all #要从哪些节点取出槽位分配给新节点?all表示从所有节点中平均取
割り当て後のスロット割当情報の表示を終了:
クラスタボリュームの減少
クラスタ過剰のパフォーマンスは、また、いくつかのノードを削除するように選択することができた場合は、Redisのもサポートされています。
スロットおよび移行データの
注意:移除节点前,需要将该节点的槽位和数据重新分配到其他Master节点!
データが失われる可能性がありそうしないと、だけでなく、いくつかのデータが書き込まれると失敗します。
8001から7001と割り当てられたデータスロット:
-cluster-から局ノードそこから
、-clusterに分配局ノードへれる
スロットの数-clusterスロットマイグレーション
# 移除7001的槽位和数据
redis-cli --cluster reshard 192.168.1.120:8001 --cluster-from f8bbd9f97db60f4b00a80a2bdcf555e95559582a --cluster-to 201ce4d928c795384bbfde39215065d2eb41592e --cluster-slots 4096
スロットとデータの移行が完了したら、ノードを削除することができます。
コマンド:redis-cli --cluster del-node host:port node_id
例:追加したばかり7001個のノードを削除します。
# 集群移除节点
redis-cli --cluster del-node 192.168.1.120:8001 f8bbd9f97db60f4b00a80a2bdcf555e95559582a
ノードが除去された後、Redisのは自動的になりますSHUTDOWN
。