Redis分布式存储&&主从复制

文章介绍了分布式存储的必要性,如单台服务器无法承受大量缓存数据时,采用分布式存储以提高服务稳定性。文中详细对比了哈希取余、一致性Hash算法和哈希槽三种方式的优缺点,特别讨论了数据分布、扩容缩容以及容错性。哈希取余简单但不易于扩展,一致性Hash减少数据迁移但可能产生数据倾斜,哈希槽通过固定槽位实现更灵活的数据迁移。此外,文章还提供了基于Redis的哈希槽实现分布式存储的步骤和示例。
摘要由CSDN通过智能技术生成

分析

为什么要分布式存储

如果有1~2亿条缓存数据需要缓存,这么大的量,单台服务器指定扛不住,必须要进行分布式存储,而为了保证redis的服务不宕机,或者宕机的影响最小化,可以采用主从复制加上redis自带的哨兵模式进行一个事故处理。

分布式存储的方式
1、哈希取余

2亿条记录就是2亿个k,v,单机不行必须要分布式多机,假设有3台机器构成一个集群,用户每次读写操作都是根据公式:
hash(key) % N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。

优点:
简单粗暴,直接有效,只需要预估好数据规划好节点,例如3台、8台、10台,就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。

缺点:
原来规划好的节点,进行扩容或者缩容就比较麻烦了额,不管扩缩,每次数据变动导致节点有变动,映射关系需要重新进行计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化:Hash(key)/3会变成Hash(key) /?。此时地址经过取余运算的结果将发生很大变化,根据公式获取的服务器也会变得不可控。
某个redis机器宕机了,由于台数数量变化,会导致hash取余全部数据重新洗牌。

2、一致性Hash算法

容错性:
假设Node C宕机,可以看到此时对象A、B、D不会受到影响,只有C对象被重定位到Node D。一般的,在一致性Hash算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。简单说,就是C挂了,受到影响的只是B、C之间的数据,并且这些数据会转移到D进行存储。
在这里插入图片描述
扩展性

数据量增加了,需要增加一台节点NodeX,X的位置在A和B之间,那收到影响的也就是A到X之间的数据,重新把A到X的数据录入到X上即可,
不会导致hash取余全部数据重新洗牌。
在这里插入图片描述

缺点:Hash环的数据倾斜问题

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

例如系统中只有两台服务器:
在这里插入图片描述

小总结
为了在节点数目发生改变时尽可能少的迁移数据

将所有的存储节点排列在收尾相接的Hash环上,每个key在计算Hash后会顺时针找到临近的存储节点存放。
而当有节点加入或退出时仅影响该节点在Hash环上顺时针相邻的后续节点。

优点
加入和删除节点只影响哈希环中顺时针方向的相邻的节点,对其他节点无影响。

缺点
数据的分布和节点的位置有关,因为这些节点不是均匀的分布在哈希环上的,所以数据在进行存储时达不到均匀分布的效果。

3、哈希槽

1 为什么出现
在这里插入图片描述
哈希槽实质就是一个数组,数组[0,2^14 -1]形成hash slot空间。

2 能干什么

解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。
在这里插入图片描述
槽解决的是粒度问题,相当于把粒度变大了,这样便于数据移动。

哈希解决的是映射问题,使用key的哈希值来计算所在的槽,便于数据分配。

3 多少个hash槽

一个集群只能有16384个槽,编号0-16383(0-2^14-1)。这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号的槽分配给哪个主节点。集群会记录节点和槽的对应关系。解决了节点和槽的关系后,接下来就需要对key求哈希值,然后对16384取余,余数是几key就落入对应的槽里。slot = CRC16(key) % 16384。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。

技术栈
  • 1、redis,这个不用讲了吧
  • 2、docker,因为docker能快速将需要的环境搭建起来,用实体机差不多的,把中间的命令稍微做更改就行了
  • 3、采用哈希槽的方式进行分布式存储
步骤
前提

需要自己安装docker,让后我的 docker中redis版本是 6.0.8这个版本。只需要执行docker pull redis:6.0.8这个命令就行。

然后启动6个redis实例就行了

docker run -d --name redis-1 --net host --privileged=true -v /data/redis/share/redis-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381

docker run -d --name redis-2 --net host --privileged=true -v /data/redis/share/redis-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382

docker run -d --name redis-3 --net host --privileged=true -v /data/redis/share/redis-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383

docker run -d --name redis-4 --net host --privileged=true -v /data/redis/share/redis-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384

docker run -d --name redis-5 --net host --privileged=true -v /data/redis/share/redis-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385

docker run -d --name redis-6 --net host --privileged=true -v /data/redis/share/redis-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386

命令详解

  • 1、 docker run 创建并运行docker实例
  • 2、-- name redis-4 为每一个实例设置一个名字
  • 3、 --net host 网络模式,代表使用宿主机的ip和端口
  • 4、–privileged=true 使用宿主机的root权限,能写能读
  • 5、-v /data/redis/share/redis-5:/data 容器卷地址 宿主机:实例
  • 6、redis:6.0.8 redis的镜像和版本号
  • 7、–cluster-enabled yes 开启redis集群
  • 8、 --appendonly yes 开启持久化
  • 9、–port 6386 redis端口号

执行完上述命令,可以输入docker ps 命令查看当前运行的实例都有哪些
在这里插入图片描述

随便输入命令docker exec -it redis-1 bash命令进入的其中一台,然后输入redis-cli -p 6381 进入的redis中,发现输入set key value会提示在这里插入图片描述
说没有提供哈希槽,是不能直接使用的。
接下来分配主从机器,将ip换成你们自己的ip

redis-cli --cluster create 172.16.16.144:6381 172.16.16.144:6382 172.16.16.144:6383 172.16.16.144:6384 172.16.16.144:6385 172.16.16.144:6386 --cluster-replicas 1
  • –cluster-replicas 1 表示为每个master创建一个slave节点

在这里插入图片描述
第一个框指出了哈希槽的分配情况,第二个指出了那些是主服务,那些事从服务。最后询问了是否遵循以上设置,输入yes进入下一步。
在这里插入图片描述
出现以上提示代表成功了。

查看集群状态

然后还以 名字为redis-1这台机器作为切入点,命令为docker exec -it redis-1 bash,进入后输入redis-cli -p 6381
在这里插入图片描述
可以看到状态时OK的,并且知道有6个节点。
可以输入 cluster nodes 查看每个节点的状态
在这里插入图片描述
上面可以看出,端口为 6381、6382、6383三台机器为主服务器,其余三台为从服务。可以看看出每个机器分配的哈希槽的范围。

可以通过redis-cli --cluster check 172.16.16.144:6381这么命令查看每个节点存储的信息,现在并没有存入任何信息,可以看到都是0个key,也能看到每一台主服务器都有一台从服务器。

存入数据

如果时通过普通的redis-cli -p直接进入会出现以下情况
在这里插入图片描述
原是key1这个key 哈希计算后的插槽并不在这台机器上
在这里插入图片描述
key2 这个key的哈希在这这台机器上。对于这个情况,需要在连接的时候加上参数 -c就行了,redis就能自动帮把数据路由到位置。

在这里插入图片描述
提示说已经把这个数据移动到开放端口为6382这台机器上了。然后检查集群
在这里插入图片描述
看到有两个key已经放入到了对应的主机上

容错切换
  • redis的策略是如果主服务挂了,从服务器会立马顶上,不过不知道这个和哨兵模式有什么联系,反转能顶。

现在假如6381这台服务器宕机了,就是先停掉了这台服务。然后端口为6382这台服务器重启了
在这里插入图片描述
然后进入端口为6382这台服务器。
输入redis-cli --cluster check 172.16.16.144:6381
在这里插入图片描述
可以看到端口为6386这台机器顶上了之前宕机的这台机器,插槽也继承了宕机的那台。然后重启的端口为6382这台机器,然后6382这台机器还是mast节点。

最后还原三主三从,发现端口为6381这台服务器并没成为主服务器
在这里插入图片描述
也就是具体的主从服务器要具体来看。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值