缓存使用过程中,我们经常遇到的问题有一下四个:
- 缓存穿透
- 缓存雪崩
- 缓存预热
- 缓存降级
1、缓存穿透
一般访问缓存的流程,如果缓存中存在查询的商品数据,那么直接返回,如果缓存中不存在,则访问数据库
image.png由于不恰当的业务功能实现,或者外部恶意攻击不断地请求某些不存在的数据内存,由于缓存中没有保存该数据,导致所有的请求都会落到数据库上,对数据库可能带来一定的压力,甚至奔溃。
解决方案:
针对缓存穿透的情况,简单是对策就是将不存在的数据访问结果,也存储到缓存中,可以有效的避免缓存穿透的风险。但是这样的话,可能会浪费大量的内存,那么可以使用布隆过滤器来节省内存空间,redis本身也是支持这种方式,布隆过滤器的介绍见海量数据下的去重和查重(二):布隆过滤器
同时,为了避免无效key过多,key要有规则,如果不满足key生成规则,则直接返回。
2、缓存雪崩
当缓存重启或者大量的缓存在某一时间段失效,这样就导致大批流量直接访问数据库,对DB造成压力,从而引起DB故障,系统奔溃。
举例来说,我们在准备一项抢购的促销运营活动,活动期间将带来大量的商品信息,库存等相关信息的查询,为了避免商品数据库的压力,将商品数据放入缓存中存储,不巧的是,抢购活动期间,大量的热门商品缓存同时失效过期了,导致很大的查询流量落到了数据库之上,对于数据库造成了很大的压力。
解决方案
- 将商品根据品类热度分类,购买比价多的类目缓存周期长一些,购买相对冷门的类目商品,缓存周期短一些;
- 在设置商品具体的缓存生效时间的时候,加上一个随机的区间因子,比如说5—10分钟之间来随意选择失效时间;
- 提前预估DB能力,如果缓存挂掉,数据库仍可以在一定程度上抗住流量的压力
这三个策略能够有效的避免短时间被,大批量的缓存失效的问题。
3、缓存预热
缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统,这样就避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题,用户直接查询事先被预热的缓存数据。
image.png如果不进行预热,那么redis初始状态数据为空,系统上线初期,对于高并发的流量,都会访问到数据库中,对数据库造成流量的压力。
解决方案
- 1、数据量不大的时候,工程启动的时候进行加载缓存动作
- 2、数据量大的时候,设置一个定时任务脚本,进行缓存的刷新
- 3、数据量太大的时候,优先保证热点数据进行提前加载到缓存
4、缓存降级
降级的情况,就是缓存失效或者缓存服务挂掉的情况下,我们也不去访问数据库,我们直接访问内存部分数据缓存,或者直接返回默认数据。
举例来说:
对于应用的首页,一般是访问量非常大的地方,首页里面往往包含了部分推荐商品的展示信息,这些推荐商品都会放到缓存中进行存储,同时我们为了避免缓存的异常情况,对热点数据也存储到了内存中,同时内存中还保留了一些默认的商品信息,
降级一般是有损的操作,所以尽量减少降级对于业务的影响程度。
网友评论