| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 缓存穿透、缓存击穿、缓存雪崩如何应对 -> 正文阅读 |
|
[大数据]缓存穿透、缓存击穿、缓存雪崩如何应对 |
?参考连接:redis避免缓存穿透为什么缓存空对象而不是null? - 知乎
1. 缓存穿透解决思路:1.1?校验参数我们可以对用户id做检验。 比如你的合法id是15xxxxxx,以15开头的。如果用户传入了16开头的id,比如:16232323,则参数校验失败,直接把相关请求拦截掉。这样可以过滤掉一部分恶意伪造的用户id。 1.2 布隆过滤器如果数据比较少,我们可以把数据库中的数据,全部放到内存的一个map中。 这样能够非常快速的识别,数据在缓存中是否存在。如果存在,则让其访问缓存。如果不存在,则直接拒绝该请求。 但如果数据量太多了,有数千万或者上亿的数据,全都放到内存中,很显然会占用太多的内存空间。 那么,有没有办法减少内存空间呢? 答:这就需要使用 布隆过滤器底层使用bit数组存储数据,该数组中的元素默认值是0。 布隆过滤器最致命的问题是:如果数据库中的数据更新了,需要同步更新布隆过滤器。但它跟数据库是两个数据源,就可能存在数据不一致的情况。 1.3 缓存空值上面使用布隆过滤器,虽说可以过滤掉很多不存在的用户id请求。但它除了增加系统的复杂度之外,会带来两个问题:
所以,通常情况下,我们很少用布隆过滤器解决缓存穿透问题。其实,还有另外一种更简单的方案,即: 当某个用户id在缓存中查不到,在数据库中也查不到时,也需要将该用户id缓存起来,只不过值是空的。这样后面的请求,再拿相同的用户id发起请求时,就能从缓存中获取空数据,直接返回了,而无需再去查一次数据库。 作者:苏三说技术 2. 缓存击穿问题2.1 什么是缓存击穿?有时候,我们在访问热点数据时。比如:我们在某个商城购买某个热门商品。 为了保证访问速度,通常情况下,商城系统会把商品信息放到缓存中。但如果某个时刻,该商品到了过期时间失效了。 此时,如果有大量的用户请求同一个商品,但该商品在缓存中失效了,一下子这些用户请求都直接怼到数据库,可能会造成瞬间数据库压力过大,而直接挂掉。 流程图如下: 那么,如何解决这个问题呢? 2.2 加锁数据库压力过大的根源是,因为同一时刻太多的请求访问了数据库。 如果我们能够限制,同一时刻只有一个请求才能访问某个productId的数据库商品信息,不就能解决问题了? 答:没错,我们可以用 伪代码如下:
在访问数据库时加锁,防止多个相同productId的请求同时访问数据库。 然后,还需要一段代码,把从数据库中查询到的结果,又重新放入缓存中。办法挺多的,在这里我就不展开了。 2.3 自动续期出现缓存击穿问题是由于key过期了导致的。那么,我们换一种思路,在key快要过期之前,就自动给它续期,不就OK了? 答:没错,我们可以用job给指定key自动续期。 比如说,我们有个分类功能,设置的缓存过期时间是30分钟。但有个job每隔20分钟执行一次,自动更新缓存,重新设置过期时间为30分钟。 这样就能保证,分类缓存不会失效。 此外,在很多请求第三方平台接口时,我们往往需要先调用一个获取token的接口,然后用这个token作为参数,请求真正的业务接口。一般获取到的token是有有效期的,比如24小时之后失效。 如果我们每次请求对方的业务接口,都要先调用一次获取token接口,显然比较麻烦,而且性能不太好。 这时候,我们可以把第一次获取到的token缓存起来,请求对方业务接口时从缓存中获取token。 同时,有一个job每隔一段时间,比如每隔12个小时请求一次获取token接口,不停刷新token,重新设置token的过期时间。 2.4 缓存不失效此外,对于很多热门key,其实是可以不用设置过期时间,让其永久有效的。 比如参与秒杀活动的热门商品,由于这类商品id并不多,在缓存中我们可以不设置过期时间。 在秒杀活动开始前,我们先用一个程序提前从数据库中查询出商品的数据,然后同步到缓存中,提前做 等秒杀活动结束一段时间之后,我们再 3. 缓存雪崩问题3.1 什么是缓存雪崩?前面已经聊过缓存击穿问题了。 而缓存雪崩是缓存击穿的升级版,缓存击穿说的是某一个热门key失效了,而缓存雪崩说的是有多个热门key同时失效。看起来,如果发生缓存雪崩,问题更严重。 缓存雪崩目前有两种:
归根结底都是有大量的请求,透过缓存,而直接访问数据库了。 那么,要如何解决这个问题呢? 3.2 过期时间加随机数为了解决缓存雪崩问题,我们首先要尽量避免缓存同时失效的情况发生。 这就要求我们不要设置相同的过期时间。 可以在设置的过期时间基础上,再加个1~60秒的随机数。
这样即使在高并发的情况下,多个请求同时设置过期时间,由于有随机数的存在,也不会出现太多相同的过期key。 3.3 高可用针对缓存服务器down机的情况,在前期做系统设计时,可以做一些高可用架构。 比如:如果使用了redis,可以使用哨兵模式,或者集群模式,避免出现单节点故障导致整个redis服务不可用的情况。 使用哨兵模式之后,当某个master服务下线时,自动将该master下的某个slave服务升级为master服务,替代已下线的master服务继续处理请求。 3.4 服务降级如果做了高可用架构,redis服务还是挂了,该怎么办呢? 这时候,就需要做服务降级了。 我们需要配置一些默认的兜底数据。 程序中有个全局开关,比如有10个请求在最近一分钟内,从redis中获取数据失败,则全局开关打开。后面的新请求,就直接从配置中心中获取默认的数据。 当然,还需要有个job,每隔一定时间去从redis中获取数据,如果在最近一分钟内可以获取到两次数据(这个参数可以自己定),则把全局开关关闭。后面来的请求,又可以正常从redis中获取数据了。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 12:02:43- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |