分布式存储面试题
一亿条数据需要缓存,请问如何设计?
#回答
单机单台100%不可能 肯定要分布式存储,用redis如何落地?
哈希取余分区
优点
简单,直接有效,起到负载均衡+分而治之的作用
缺点
扩缩容麻烦,某个机子宕机了,分母就改变了,映射关系就会改变
一致性哈希算法分区
- 为了解决上述问题 映射+数据变动
优点
容错性 假設宕机了,受影响比较小
扩容也还行 直接扩容
缺点
数据倾斜问题
如果节点太少,就会造成数据倾斜
哈希槽分区
解决数据倾斜问题
3主3从redis集群配置
# 启动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
启动成功如下
docker ps
进入redis-node-1并为6台机器构建集群关系
docker exec -it redis-node-1 /bin/bash
#注意,进入docker容器后才能执行一下命令,且注意自己的真实IP地址
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
--cluster-replicas 1 表示为每个master创建一个slave节点
底下输入 yes
以6381作为切入点。查看集群状态
redis-cli -p 6381
cluster nodes
6381 挂载的是 6384 #随机分配的
6382 挂载的是 6385
主从容错切换迁移
docker exec -it redis-node-1 /bin/bash
redis-cli -p 6381
keys * # 空
set k1 v1 # 报错~ 12706高过范围
现象如下~
exit # 退出
redis-cli -p 6381 -c # 进去
flushall
set k1 v1 #成功
现象
查看集群信息
redis -cli --cluster check 192.168.1.150:6381
容错切换—主从恢复
# 6381宕机
docker ps
docker stop redis-node-1 #停了要等一会儿 有心跳机制
docker exec -it redis-node-2 bash
redis-cli -p 6382 -c
cluster nodes
# 发现6384 变成 master 了
get k1 k2 k3 k4 #正常取出
6381回来
docker start redis-node-1
docker ps
6381是slave 6384还是master
# 还是希望6381是master
# 把6384停了再开
主从扩容(重要)
转换四主四从
#再启动两台redis
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
docker ps # 有8个咯
docker exec -it redis-node-7 /bin/bash
#要将6387作为master加入集群
redis-cli --cluster add node 192.168.1.150:6387 192.168.1.150:6381
redis-cli --cluster check 192.168.1.150:6381 #查看集群状态 发现还没分槽位
#重新分槽位
命令:redis-cli --cluster reshard IP地址:端口号
redis-cli --cluster reshard 192.168.1.150:6381
# 输入 4096
# 输入id号
# 输入 all
# 输入 yes
redis-cli --cluster check 192.168.1.150:6381 #查看集群状态 有槽位了
# 三家每家切了点给 6387
# 现象如下
为主节点6387 分配salve 6388
命令:redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
redis-cli --cluster add-node 192.168.111.147:6388 192.168.111.147:6387 --cluster-slave --cluster-master-id e4781f644d4a4e4d4b4d107157b9ba8144631451-------这个是6387的编号,按照自己实际情况
redis-cli --cluster check 192.168.111.147:6382 #再次查看 6381 82 83 84 都可以
主从缩容(重要)
四主四从 恢复成 三主三从
先删6388 再删6387
redis-cli --cluster check 192.168.111.147:6382
# 复制6388机子号
命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID
redis-cli --cluster del-node 192.168.111.147:6388 5d149074b7e57b802287d1797a874ed7a1a284a8
redis-cli --cluster check 192.168.111.147:6382 # 发现6388被删除了,只剩下7台机器了
redis-cli --cluster reshard 192.168.111.147:6381 # 将6387号槽位清空 重新分配
# 输入 4096
# 输入6387的机器id
# 输入done
redis-cli --cluster check 192.168.111.147:6381 #4096个槽位都指给6381,它变成了8192个槽位,相当于全部都给6381了,不然要输入3次,一锅端
#删除6387
命令:redis-cli --cluster del-node ip:端口 6387节点ID
redis-cli --cluster del-node 192.168.111.147:6387 e4781f644d4a4e4d4b4d107157b9ba8144631451
redis-cli --cluster check 192.168.111.147:6381 #再检查一次 恢复三主三从