栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

分布式锁+分布式事务+分布式缓存

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

分布式锁+分布式事务+分布式缓存

1.分布式缓存 1.1高并发下的分布式缓存

我们先从最开始的来说,我们现在一般都是B/S架构,一般都是中间挂一个服务器,后面有一个数据库。如下图:

如果客户端的访问量很大的话,那对于后端的服务来说就有一定压力了,压力主要有两个环节;一个环节是关于服务器,一个环节是我们数据库;当我们的并发量增加时,最先达到瓶颈的是我们数据库,这就会导致客户端的访问速度,访问效率降低,这时该如何解决呢?这个时候我们就需要加缓存层;

我们可以把经常访问的数据 称之为热点数据,存放在缓存中,当我们去数据库拿数据的时候,先去缓存中找一下,找到了直接返回,没找到再去数据库中查找;这时可以阻挡一部分接触数据库的请求
如果热点数据很大,一台redis缓存存放不了,这时我们可以采用多台redis机器,这就牵扯到了redis集群,这就是我们说的分布式缓存;

1.2redis集群模式 1.2.1 主从备份模式

有一台master,它的下面会挂一群slave;
如果客户端去读数据,是找的这些slave;如果客户端去写数据,找的是master,写完之后master会将数据同步给slave

思考一个问题,如果使用了这种集群模式,对于上面说到的问题可以解决吗?搭建这样的集群模式最终所能存储的数据是由单台机器的容量所决定的。
所以搭建这样的集群模式是解决不了海量的热点数据存储的一个问题;所以我们有了下面这种模式的集群;

1.2.2切片模式的集群

我们可以把海量的热点数据进行一个切片,切成一块一块的,每一块存放在一台redis上;

那么我们有什么办法将这些数据均匀的分布在这三台机器上 ?有一个切片规则,可以计算下数据key的hash值; 比如上面的三台机器,我们可以hash(key) % 3 = [0,1,2]它的计算结果在 0,1,2之间,这样就可以把大量的热点数据均匀的存放在三台redis机器上;
但是这样的切片规则是有问题的,什么问题?不利于集群的扩展, 当我们增加一台redis时,这时我们切片规则需要改变并且原本三台上的部分数据需要根据切片规则迁移到新增加的redis机器上

我们来看一下一个优秀的切片规则

1.2.2.1一致性Hash算法

假设我们现在有一个环,这个环叫做Hash环,我们准备三台redis机器,Hash环的作用是决定哪些数据存放在哪个redis机器上。
每一台redis机器都有他的Ip和编号,我们通过给他的IP和编号做Hash运算,计算结果作为在这个环上的位置。

接下来我们对每一条数据也进行这样的计算,每一条数据都会落在这个环上,接下来我们把这些数据在环上沿着顺时针去找,首先找到哪台服务器就放在哪个机器上面

一致性Hash算法的好处是对集群的扩展非常有利,假设我们新增了一台redis4机器,那么只需要将图中redis2和redis4之间线段里的数据(之前存放在redis3)迁移到redis4即可,只需要redis3和redis4发生数据迁移就行,其他的机器不需要动;但这个算法会有一个问题,数据倾斜问题,当redis机器较少或环长度过大时,机器间可能会离的过近,此时我们看下图:

此时可以看出只有少部分数据存放在redis2中,大量数据都存放在redis1中。为了解决这个问题,我们提出了虚拟节点的概念;

1.2.2.2 虚拟节点

我们可以把每一台redis服务虚拟成多个点(redisA1,redisA2。。。),再把虚拟出来的点分布在Hash环上,数据落在虚拟的点但实际落在它对应真实的服务器上,如下图:

1.3缓存击穿,穿透,雪蹦 1.3.1缓存穿透

假设我们现在以id=-1的请求去请求获取数据,这时数据库里没有,缓存里更没有;当有大量不存在的请求过来时,这些请求在缓存中查找不到,便会去数据库中查找,这时就有可能把数据库压垮!!
如何解决呢??
我们可以在缓存与数据库之间搞个过滤器,假设我们每次都是通过ID去查询的,过滤器中保存数据库所有的主键ID;当请求过来之后,首先判断过滤器中是否存在这个ID,不存在的话直接过滤掉请求;
但是上面的方案会存在一个问题,当我们数据库数据越来越大时,过滤器所占用的内存也会随之增大,过滤效率就会降低,客户端请求的链路时间也会越长,客户体验会不好;这时就引出了一个算法-布隆算法

1.3.1.1布隆算法

我们可以使用布隆算法来降低过滤器对内存的占用;布隆算法主要通过错误率来换取空间的占用;
算法的原理
它有一个二进制码数组,假设他的长度是10;此时传入ID=100,它会根据Hash函数得到它在二进制数组中的位置,通过这个hash函数计算的结果集会在二进制数组长度之间。

此时第二位上的1代表id=100的这个数据存在;

那么错误率是怎么出现的呢?
假设id=1000的数据,通过hash函数计算得到位置也是二进制数组的第二位上,此时二进制数组的第二位的1就代表了ID=100和ID=1000这两条数据存在。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/345363.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号