分布式存储与docker部署redis主从集群

一、分布式存储常见算法:

1、哈希取余分区算法:

(1) 概念:hash(key) % N,N是Redis集群的机器台数,用户每次读写操作,根据传入的键名经过哈希运算,来决定数据映射到哪个节点上。

(2) 优点:只要预估好数据规划好节点,就能保证一段时间的数据支撑。使用Hash算法让一部分请求落到同一台服务器上,每台服务器固定这处理一部分请求。

(3) 缺点:需要弹性扩容或者故障停机的情况下,原先取模公式中的N就会发生变化,此时经过取模运算的结果就会发生很大变化,导致根据公式获取的服务器变得不可控。

2、一致性哈希算法:

(1) 概念:

① 一致性Hash算法将整个哈希值空间组成一个虚拟的圆环,整个空间按顺时针方向组织,圆环的正上方的点代表0,0点右侧的第一个点代表1,以此类推,2、3、4.......直到2^32 - 1,0 和 2^32 - 1在零点钟方向重合,这个由 2^32个点组成的圆环称为Hash环。

② 有了哈希环之后,还需要进行节点映射,将集群中各个IP节点映射到环上的某一个位置,具体可以选择服务器的IP或主机名作为关键字进行哈希(假如4个节点NodeA、B、C、D,经过IP地址的哈希函数计算)

③ 当我们需要存储一个key键值对时,首先计算key的hash值 hash(key),并确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其定位到的服务器,并将该键值对存储到该节点上。

假设有ObjectA、B、C、D四个数据对象,经过哈希计算后,根据一致性hash算法,数据A会被定位到NodeA上,B被定位到NodeB上,C被定位到NodeC上,D被定位到NodeD上。

(2) 优点:

① 容错性:

在一致性Hash算法中,如果一台服务器不可用,受影响的数据仅仅是此服务器到其环空间中前一台服务器之间的数据,其他不会受到影响。

假设NodeC宕机,只会影响到Hash定位到NodeB到NodeC之间的数据,并且这些数据会被转移到NodeD进行存储。

② 扩张性:

假如需要扩容增加一台节点NodeX,NodeX的hash(ip)位于NodeB和NodeC之间,那受到影响的就是NodeB 到 NodeX 之间的数据。重新将B到X的数据录入到X节点上即可。

(3) 缺点:

数据倾斜:一致性Hash算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的对象都集中到某一台或某几台服务器)。

3、哈希槽分区:

在数据和节点之间又加入了一层,把这层称之为槽(slot),用于管理数据和节点之间的关系,相当于节点上放的是槽,槽里面放的是数据。

一个集群只能有 16394个槽,编号 0 - 16383(2^14 - 1)。这些槽会分配给集群中所有的主节点,可以指定哪些编号的槽分配给哪个主节点,集群会记录节点和槽的对应关系。

接下来对key求哈希值,然后对16384取余,根据余数决定key落到哪个槽里。

slot = CRC16(key) % 16384

二、redis 集群(三主三从)

1、集群配置:

(1) 新建6个docker容器实例:

在 Docker 容器中运行 Redis 6.0.8 版本,并启用了 Redis 的集群功能,使用主机网络模式并挂载了宿主机目录用于数据持久化

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

(2) 构建主从集群关系:

进入节点一,构建主从关系:

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

● --cluster create:告诉 redis-cli 要创建一个 Redis 集群。

● 192.168.198.130:6381 到 192.168.198.130:6386:这些是 Redis 集群的节点列表。指定了六个节点的地址和端口号,这些节点将一起形成 Redis 集群。

● --cluster-replicas 1:这部分值为1指定了每个主节点都会有一个对应的副本节点。

redis 自动分配的集群信息:

进行主从配置,并为主节点分配哈希槽。

(3) 查看集群状态:

● 使用redis-cli连接到6381节点:redis-cli -p 6381

● 查看集群状态:cluster info

● 查看节点信息:cluster nodes

节点1下挂载的是节点5;

节点2下挂载的是节点6;

节点3下挂载的是节点4。

2、主从容错:

(1) redis 读写出错:

当进入redis单机节点添加数据时,可能会失败,原因是该键计算出的哈希槽值不属于该节点所在的哈希槽范围,redis会提供正确的节点信息。

● 以集群模式运行redis服务器:

redis-cli -p 6381 -c

当添加了不属于该槽位的键值时,redis会重定向至正确的节点去执行。

(2) 查看集群信息:

redis-cli --cluster check 192.168.198.130:6381

(3) 主从容错迁移:

① 节点1宕机,节点5上位:

● 停止节点1运行:docker stop redis-node-1

● 进入节点2查看节点信息:

② 节点1恢复后再次查看节点信息:

docker start redis-node-1

此时节点1已经从原先的主节点变为节点5的从节点。

③ 停止节点5运行,再次查看节点信息:

此时节点1又重新恢复主节点身份。

3、主从扩容缩容:

(1) 主从扩容:

增加一主一从加入集群

① 新建6387、6388两个节点:

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

② 进入节点7,将其作为主节点加入集群:

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

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

通过节点1,将节点7加入redis集群

③ 检查集群情况:

节点7已加入集群(暂时没有槽位)

④ 重新分配槽位:

redis-cli --cluster reshard 192.168.198.130:6381

通过节点1发起重新分配槽位的操作。

⑤ 再次查看节点信息:

节点7是三个槽区间,之前的主节点还是连续的区间(前三个主节点各自匀一些给新节点,不是从0开始重新分配)

⑥ 给节点7分配从节点 (6388):

redis-cli --cluster add-node 192.168.198.130:6388 192.168.198.130:6387 --cluster-slave --cluster-master-id 367f4d705ff85185460cf9c46d602108a37496eb

将6388作为从节点分配给主节点6387,--cluster-master-id 是节点7的ID。

再次查看集群状态:

(2) 主从缩容:

集群缩容,先清除从节点6388,清出来的槽位重新分配,再删除6387,恢复三主三从。

① 从集群中删除节点8:

redis-cli --cluster del-node 192.168.xxx.xxx:6388 6388节点编号

redis-cli --cluster del-node 192.168.198.130:6388 ac30b42b827c049634bfb104508a5d70e4252f00

查看集群状态,此时集群里只剩7个节点:

redis-cli --cluster check 192.168.198.130:6381

② 将6387的槽位清空,重新分配 (本例全部分配给6381):

通过节点1,对整个集群发起重新分配槽位的操作:

redis-cli --cluster reshard 192.168.198.130:6381

查看集群状态:

节点1有8192个槽位 ;节点7还存在,但已经没有槽位。

③ 删除节点7:

redis-cli --cluster del-node 192.168.198.130:6387 367f4d705ff85185460cf9c46d602108a37496eb

查看集群状态,回到三主三从:

  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值