一、问题引入?
Q: 1~2亿条数据需要缓存,请问如何设计这个存储案例,并保证能动态扩缩容 ?
A: 分布式存储,使用redis集群,使用容器化技术....
二、数据的三种分区简介
2.1 哈希取余分区
2.1.1 概念
2亿条记录就是2亿个k,v,我们单机不行必须要分布式多机,假设有3台机器构成一个集群,
用户每次读写操作都是根据公式:hash(key) % N个机器台数,计算出哈希值,用来决定数据映
射到哪一个节点上。
2.1.2 优点
简单粗暴,直接有效,只需要预估好数据规划好节点,例如3台、8台、10台,就能保证一段时间的数据支
撑。使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请
求的信息),起到负载均衡+分而治之的作用。
2.1.3 缺点
原来规划好的节点,进行扩容或者缩容就比较麻烦了额,不管扩缩,每次数据变动导致节点有变动,映射关系
需要重新进行计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式
就会发生变化:Hash(key)/3会变成Hash(key) /?。此时地址经过取余运算的结果将发生很大变化,根据公式获
取的服务器也会变得不可控。某个redis机器宕机了,由于台数数量变化,会导致hash取余全部数据重新洗牌。
2.2 一致性哈希算法分区
2.2.1 概念
一致性Hash算法背景
一致性哈希算法在1997年由麻省理工学院中提出的,设计目标是为了解决
分布式缓存数据变动和映射问题,某个机器宕机了,分母数量改变了,自然取余数不OK了。
2.2.2 作用
提出一致性Hash解决方案。目的是当服务器个数发生变动时,尽量减少影响客户端到服务器的映射关系
2.2.3 核心三步骤
(1)算法构建一致性哈希环
(2) 服务器IP节点映射
(3)key落到服务器的落键规则
2.2.4 优点
(1)一致性哈希算法的容错性
(2)一致性哈希算法的扩展性
2.2.5 缺点
(1)一致性哈希算法的数据倾斜问题
2.2.6 总结
为了在节点数目发生改变时尽可能少的迁移数据将所有的存储节点排列在首尾相接的Hash环上,每个key在计
算Hash后会顺时针找到临近的存储节点存放。而当有节点加入或退出时仅影响该节点在Hash环上顺时针相邻的后
续节点。
优点
加入和删除节点只影响哈希环中顺时针方向的相邻的节点,对其他节点无影响。
缺点
数据的分布和节点的位置有关,因为这些节点不是均匀的分布在哈希环上的,所以数据在进行存储时达不到均匀分
布的效果。
2.3 哈希槽分区【重点】
2.3.1 概念
2.3.2 哈希槽计算
三、3主3从redis集群配置
3.1关闭防火墙+启动docker后台服务
关闭防火墙: systemctl stop firewalld.service
永久关闭防火墙: systemctl disable firewalld.service
启动docker: systemctl start docker
3.2 新建6个docker容器redis实例
实例分别为:redis-node-1/2/3/4/5/6 端口号 6381/6382/6383/6384/6385/6386
docker run -d --name redis-node-1 --net host --privileged=true -v /home/dongzhigang/redis/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 /home/dongzhigang/redis/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 /home/dongzhigang/redis/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 /home/dongzhigang/redis/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 /home/dongzhigang/redis/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 /home/dongzhigang/redis/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
【关键参数解释】
--net host 使用宿主机的IP和端口,默认
--privileged=true 获取宿主机root用户权限
--cluster-enabled yes 开启redis集群
--appendonly yes 开启持久化
3.3 构建集群关系
1、进入 redis-node-1
docker exec -it redis-node-1 /bin/bash
2、为6台机器构建集群关系(192.168.215.141)
redis-cli --cluster create 192.168.215.141:6381 192.168.215.141:6382 192.168.215.141:6383 192.168.215.141:6384 192.168.215.141:6385 192.168.215.141:6386 --cluster-replicas 1
【注意】
--cluster-replicas 1 表示为每个master创建一个slave节点
图片中的信息如下:可以发现
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.215.141:6385 to 192.168.215.141:6381
Adding replica 192.168.215.141:6386 to 192.168.215.141:6382
Adding replica 192.168.215.141:6384 to 192.168.215.141:6383
Master(1,2,3) Slave (4,5,6)
1-5 2-6 3-4
3.4 查看集群状态
1、进入 redis-node-1
docker exec -it redis-node-1 /bin/bash
2、连接redis节点
redis-cli -p 6381
3、查看集群状态
cluster info / cluster nodes
四、主从容错切换
4.1数据读写存储
1、启动redis集群,并通过任意节点exec进入
docker exec -it redis-node-1 /bin/bash
2、防止路由失效加参数-c并新增两个key
redis-cli -p 6381 -c
3、查看集群信息
redis-cli --cluster check 192.168.215.141:6381
4.2 容错切换迁移
1、先停止6382
docker stop redis-node-2
2、在node1上面查看集群状态
cluster info / cluster nodes
3、再启动6382
docker start redis-node-2
4、在node1上面查看集群状态
cluster info / cluster nodes
五、主从扩容案例
5.1 新增2个节点
docker run -d --name redis-node-7 --net host --privileged=true -v /home/dongzhigang/redis/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 /home/dongzhigang/redis/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
docker ps
5.2 把新节点加入集群
1、进入6387容器实例内部(不需要连接redis)
docker exec -it redis-node-7 /bin/bash
2、将新增的6387节点(空槽号)作为master节点加入原集群【重要】
redis-cli --cluster add-node 192.168.215.141:6387 192.168.215.141:6381
【注】6381相当于6387的领路人,带头大哥
5.3 检查集群并重新分配槽号
5.3.1 检查集群情况第1次
redis-cli --cluster check 192.168.215.141:6381
5.3.2 重新分派槽号【重点】
redis-cli --cluster reshard 192.168.215.141:6381
5.3.3 检查集群情况第2次
redis-cli --cluster reshard 192.168.215.141:6381
【注意】
重新分配成本太高,所以前3家各自匀出来一部分,从6381/6382/6383三个旧节点大约分配1365个坑位给新节点
所以6387的槽数由三个段构成 [0-1364],[5461-6826],[10923-12287] 共计1365+1366+1365=4096个
5.4 为主节点6387分配从节点6388
命令:给集群加入新节点6388,并且成为6387的slave
redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
redis-cli --cluster add-node 192.168.215.141:6388 192.168.215.141:6387 --cluster-slave --cluster-master-id 08bba8913167ff4145c3c732ad759a68b46a7937
5.5 检查集群
redis-cli --cluster check 192.168.215.141:6381
六、主从缩容案例
6.1 从集群中移除6388节点
【过程】2、3不能颠倒
1、先删除salve
2、再重新分配哈希槽(把要删除的master节点上面的槽数分配给其他节点)
3、再删除master
1、查询 6388节点的id
redis-cli --cluster check 192.168.215.141:6381
14a72c34ff382c8e1b18f0f041dceb1956b677cb
2、将6388节点删除
命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID
redis-cli --cluster del-node 192.168.215.141:6388 14a72c34ff382c8e1b18f0f041dceb1956b677cb
6.2 重新分配哈希槽
redis-cli --cluster reshard 192.168.215.141:6381
6.3 查看集群,并删除6387节点
1、查看集群
redis-cli --cluster check 192.168.215.141:6381
2、删除6387节点
命令:redis-cli --cluster del-node ip:端口 6387节点ID
redis-cli --cluster del-node 192.168.215.141:6387 08bba8913167ff4145c3c732ad759a68b46a7937
3、再次查看集群
redis-cli --cluster check 192.168.215.141:6381
版权声明:本文为m0_62676056原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。