docker部署redis集群(哈希槽)并实现扩缩容以及相关理论

文章详细介绍了分布式存储的三种常见解决方案,包括哈希取余(适用于小规模场景)、一致性哈希(中等规模)以及哈希槽分区(大规模,如Redis集群)。文中通过实例展示了如何构建和管理Redis集群,包括如何进行主从扩容和缩容,以及处理容错和数据迁移的过程。
摘要由CSDN通过智能技术生成

分布式存储解决方案

哈希取余分区(小厂)

用户的读写操作都通过公式打到不同服务器,取的时候也通过公式,在哪里存就在哪里取。
在这里插入图片描述

  • 优点
    简单有效,只要规划好所使用的redis台数,设定好公式,使用hash算法让部分请求落到一台服务器,起到了负载均衡、分而治之的效果。
  • 缺点
    进行扩容或缩容时麻烦,需要改动公司,且原来存储的信息与新公司可能产生违背(导致所有数据重新排列),某台redis宕机后存入不了数据。

一致性哈希算法分区(中厂)

目的:当服务器个数发生变动时,尽量减少客户端与服务端映射的影响。

步骤

  1. 算法构建一致性哈希环
  2. 服务器IP节点(或主机名)映射
  3. key落到服务器的落键规则
    在这里插入图片描述
    一致性哈希环0 ~ 2^31-1形成闭环,计算key(ip或主机名)的hash值落到环上,然后顺时针寻找第一个服务器所代表的hash值。
  • 优点
    容错性:当某台redis宕机了(如C),那么只会影响key键落在B~C的段落,且会将到C的段落存储到D上,不影响存储。
    扩展性:需要新加一台redis(X)在A与B之间,那么不会导致所有数据重新洗牌,只会将A~X存储到B节点的数据移动至X节点,影响较小。
  • 缺点
    当节点太少容易造成数据倾斜问题(节点在圆环上排列不均)。如下图大量的数据存储在A服务器上。
    在这里插入图片描述

哈希槽分区(大厂)

目的:解决数据倾斜的问题,均匀分配。哈希槽(slot),用于管理数据和节点之间的关系
在这里插入图片描述
redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,也就是映射到某个节点上。

为什么一个集群最多16384(2^14-1 )个槽?
主要是保证心跳方便和数据传输的最大化。
(1)如果65536,发送心跳消息的消息头达到8K,心跳包过于庞大。
(2)redis集群主节点不可能超过1000个。
(3)槽位越小,节点少的情况下,压缩比例高,易传输。

构建redis集群(哈希槽)

注:我这里做的是3主3从集群,如果想做其它比例自行增删实例,redis会自动分配槽位
在这里插入图片描述

1. 新建6个redis容器实例

docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --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:6.0.8 --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:6.0.8 --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:6.0.8 --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:6.0.8 --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:6.0.8 --cluster-enabled yes --appendonly yes --port 6386

在这里插入图片描述
在这里插入图片描述

2. 进入其中一个容器实例为6台机器构建集群关系

docker exec -it redis-node-1 /bin/bash

–cluster-replicas 1 表示为每个master创建一个slave节点

redis-cli --cluster create 192.168.111.147:6381 192.168.111.147:6382 192.168.111.147:6383 192.168.111.147:6384 192.168.111.147:6385 192.168.111.147:6386 --cluster-replicas 1

出现以下画面输入yes
在这里插入图片描述
看到16384个槽全部覆盖则成功,其中含有信息那个槽是master(M),那个是slave(S)
在这里插入图片描述
到这里就完成了。

3. 进入其中一个容器实例,查看集群状态

以6381为例:redis-cli -p 6381

cluster info :查看集群信息
cluster nodes :查看集群节点
在这里插入图片描述
在这里插入图片描述
主从机对应是随机生成的,我这里主从机对应是:6381 => 6385,6382 => 6386,6383 => 6384

数据读写存储

单机连接 redis-cli -p 6381

当我们连接master1(6381),进行数据写入时,如果key的hash值不在分配给master的槽位就会报错,写不进去,由下面第2、3张图可看槽位信息。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

集群连接 redis-cli -p 6381 -c

使用集群进行数据写入时,当key的hash值不在当前master的槽位,则会切换到所在槽位的master实例。如下图。
在这里插入图片描述

查看集群信息

redis-cli --cluster check 192.168.52.129:6381
在这里插入图片描述

容错切换迁移

我们停掉6381主机后,对应的从机6385就变成了主机。当6381再次启动时,6385并不会将主机位置还给6381。

cluster nodes

在这里插入图片描述

主从扩容

1. 新建6387、6388两个节点+新建后启动+查看是否8节点

docker run -d --name redis-node-7 --net host --privileged=true \ 
-v /data/redis/share/redis-node-7:/data redis:6.0.8 \
--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:6.0.8 \
--cluster-enabled yes --appendonly yes --port 6388

2. 进入6387容器实例内部

docker exec -it redis-node-7 /bin/bash

3. 将新增的6387节点(空槽号)作为master节点加入原集群

redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381
6387 就是将要作为master新增节点
6381 就是原来集群节点里面的领路人,相当于6387拜拜6381的码头从而找到组织加入集群

redis-cli --cluster add-node 192.168.52.129:6387 192.168.52.129:6381

在这里插入图片描述

4. 检查集群情况第1次

redis-cli --cluster check 192.168.52.129:6381

可以看到新加入的主节点并没有分配哈希槽
在这里插入图片描述

5. 重新分派槽号

命令:redis-cli --cluster reshard IP地址:端口号

redis-cli --cluster reshard 192.168.52.129:6381

第一步:它会提示你分配多少个槽位:16384/master个数
第二步:提示你分配给谁:新增master节点ID
第三步:是否使用所有节点做位散列槽的源节点:all
第四步:是否“重新洗牌”:yes
在这里插入图片描述

6. 检查集群情况第2次

redis-cli --cluster check 192.168.52.129:6381

发现槽位被均分了,且数据也重新排列好了。
但是是每个master均分了一点儿给新增的master,即新增master的槽位是不连续的
在这里插入图片描述

7. 为主节点6387分配从节点6388

redis-cli --cluster add-node 192.168.52.129:6388 192.168.52.129:6387 \
--cluster-slave --cluster-master-id 731f06d7030997a27ef50e03a84107945cb9b59b-------这个是6387的编号,按照自己实际情况

在这里插入图片描述

8. 检查集群情况第3次

redis-cli --cluster check 192.168.52.129:6381

出现4主4从则成功
在这里插入图片描述

主从缩容

1. 检查集群情况1获得6388的节点ID

redis-cli --cluster check 192.168.52.129:6381

2. 先将要缩容的slave从集群中删除

命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID
 
redis-cli --cluster del-node 192.168.52.129:6388 67b89f272c98c1eed52ae14abe1432ba6c57aa42

再次查看集群状况时就没有从机6388了。
在这里插入图片描述

3. 将缩容的master的槽号清空,重新分配

本例将清出来的槽号都给6382,注意要分配给master,slave不行

redis-cli --cluster reshard 192.168.52.129:6381

第一步:移动多少槽位?:自行输入,这里是4096
第二步:将这些槽位分配给谁?:输入master的id
第三步:移动的这些槽位由谁出?:缩容master的id
第四步:done
第五步:”重新洗牌“:yes

4. 删除缩容的master

此时缩容的master还在,没有槽位,没有slave
在这里插入图片描述

使用命令:redis-cli --cluster del-node ip:端口 6387节点ID
 
redis-cli --cluster del-node 192.168.52.129:6387 731f06d7030997a27ef50e03a84107945cb9b59b

再次查看就没有了master6387了
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值