概述
使用哈希槽分区,6台机器,1主1从。
一、节点搭建
使用docker创建6个redis容器,如果有6台主机也是一样的。
现在我们又6台机器分别是:
主机名 | IP | 端口 |
---|---|---|
redis-node-1 | 192.168.78.100 | 6381 |
redis-node-2 | 192.168.78.100 | 6382 |
redis-node-3 | 192.168.78.100 | 6383 |
redis-node-4 | 192.168.78.100 | 6384 |
redis-node-5 | 192.168.78.100 | 6385 |
redis-node-6 | 192.168.78.100 | 6386 |
下面是创建脚本:
docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis --cluster-enabled yes --appendonly yes --port 6386
如果是多台机器的,只需要在不同的机器上执行一次创建就可以了,这需要创建6个节点就行。
二、构建哈希槽分区
然后在任意一个节点执行以下脚本,构建哈希槽分区。
# 进入容器
docker exec -it redis-node-1 /bin/bash
# 构建哈希槽分区
redis-cli --cluster create 192.168.78.100:6381 192.168.78.100:6382 192.168.78.100:6383 192.168.78.100:6384 192.168.78.100:6385 192.168.78.100:6386 --cluster-replicas 1
cluster-replicas 1
表示为每个master节点创建1个从节点。
根据构建输出的日志,我们可得出:
主节点 | 从节点 | 哈希槽 |
---|---|---|
192.168.78.100:6381 | 192.168.78.100:6385 | 0 – 5460 |
192.168.78.100:6382 | 192.168.78.100:6386 | 5461 – 10922 |
192.168.78.100:6383 | 192.168.78.100:6384 | 10923 – 16383 |
在存储数据时,根据key计算出存储在对应的哈希槽,然后存储到对应的主节点,从节点再从主节点同步数据。
我们可以进入redis客户端,执行以下命令查询槽点和节点的信息:
# 打开客户端
redis-cli -p 6381
# 查看槽分区信息
cluster info
# 查看节点信息
cluster nodes
三、数据存储
在存储数据时,需要使用 -c
表示集群模式,否则根据key计算槽点,发现不属于该节点上的槽点时会出错。
下面k1计算出的槽点就不在6381这个节点上,所以就发生了错误。
root@localhost:/data# redis-cli -p 6381
127.0.0.1:6381> set k1 v1
(error) MOVED 12706 192.168.78.100:6383
127.0.0.1:6381> set k2 v2
OK
127.0.0.1:6381> set k3 v3
OK
127.0.0.1:6381>
如果我们在启动客户端指定集群模式,保存k1
时,redis就会自动给我们把数据保存到6383
这个节点上去。
root@localhost:/data# redis-cli -p 6381 -c
127.0.0.1:6381> set k1 v1
-> Redirected to slot [12706] located at 192.168.78.100:6383
OK
192.168.78.100:6383> set k2 v2
-> Redirected to slot [449] located at 192.168.78.100:6381
OK
192.168.78.100:6381> set k3 v3
OK
192.168.78.100:6381> set k4 v4
-> Redirected to slot [8455] located at 192.168.78.100:6382
OK
192.168.78.100:6382>
使用以下命令,可查看集群存储key的分布情况:
redis-cli --cluster check 192.168.78.100:6381
从上图看看出,6381节点存储了2个key,6382和6383分别存储了一个key。
四、主从切换
假设6381
这个节点宕机了,6381
对应的从节点6385
节点就会升级为主节点。
# 停止6381节点
docker stop redis-node-1
此时,进入redis-node-2 6382
节点,查看节点的情况
# 进入容器
docker exec -it redis-node-2 /bin/bash
# 打开redis客户端
redis-cli -p 6382 -c
# 查看节点状态
cluster nodes
此时可以看出,6381处于fail状态,6385
变成了master,然后获取之前存储的数据,数据正常取出。
在6381
恢复后,会变为从节点,如果需要恢复为主节点,可以把6385
停掉一下,让6381
变成主节点,再启动6385
节点,这样就恢复原状了。
五、集群的扩容
现在添加2台机器,组成一主一从,添加到之前的集群中。
在docker中创建2个容器:
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis --cluster-enabled yes --appendonly yes --port 6388
进入6387
这台机器,使用redis-cli把节点添加到集群中:
# 进入容器
docker exec -it redis-node-7 /bin/bash
# 添加节点到集群,需要指定集群中的任意一个主节点,用于获取集群信息,此处指定6381节点
redis-cli --cluster add-node 192.168.78.100:6387 192.168.78.100:6381
此时节点就添加成功,此时检查6387
节点信息,可看到节点已存在,只是没有key和槽点。
redis-cli --cluster check 192.168.78.100:6387
在添加节点后需要进行重新分配槽点,不然6387
没有槽点,没法正常存储数据。
进入任意一台主节点,此处为6381
这个主节点,然后执行重新分配槽点:
# 进入容器
docker exec -it redis-node-1 /bin/bash
# 重新分配槽点
redis-cli --cluster reshard 192.168.78.100:6381
再输入对应的参数后,redis就会从其他节点上匀未使用的槽点过来,然后再次检查一下节点信息:
redis-cli --cluster check 192.168.78.100:6387
此时,6387
节点也有了槽点。
最后再把6388
节点分配为6387
的从节点,就完成集群的扩容了。
redis-cli --cluster add-node 192.168.78.100:6388 192.168.78.100:6387 --cluster-slave --cluster-master-id 156f002af4e395f547f0262c5db2b54e634a1fda
cluster-master-id 就是6387节点的ID。
此时查看集群情况:
cluster nodes
此时集群节点情况如下:
主节点 | 从节点 | 哈希槽 |
---|---|---|
192.168.78.100:6381 | 192.168.78.100:6385 | 1365-5460 |
192.168.78.100:6382 | 192.168.78.100:6386 | 6827-10922 |
192.168.78.100:6383 | 192.168.78.100:6384 | 12288-16383 |
192.168.78.100:6387 | 192.168.78.100:6388 | 0-1364 5461-6826 10923-12287 |
在扩容后的集群环境下,再次查看之前存储的数据,数据还能正常读取,数据也可以存储到6387
节点。
六、集群的缩容
在流量降下来后,需要把之前扩容的机器下线,避免资源的浪费。
此时只需要把从机6388
从集群中删除,然后把6387
的槽点清空,重新分配槽点,再把6387
节点也删除,最后把6387
和6388
节点停机,这样就完成缩容了。
# 进入6381节点,删除6387节点
docker exec -it redis-node-1 /bin/bash
redis-cli --cluster del-node 192.168.78.100:6388 c99eb43d05cb017ad717104051cb4e2341ead739
c99eb43d05cb017ad717104051cb4e2341ead739是6388节点的ID。
此时可看到6387
节点的从节点已经不在了。
# 重新分配槽位
redis-cli --cluster reshard 192.168.78.100:6381
再次检查集群情况,槽位已经被迁移到6381节点了:
redis-cli --cluster check 192.168.78.100:6381
然后在把6387
节点删除,再次检查集群情况,6387
节点已经不在了:
redis-cli --cluster del-node 192.168.78.100:6387 156f002af4e395f547f0262c5db2b54e634a1fda
最后再把6387和6388两台机器关掉:
docker stop redis-node-7
docker stop redis-node-8
完成redis集群的缩容。
原创文章,作者:wdmbts,如若转载,请注明出处:https://blog.ytso.com/tech/database/275100.html