Redis做缓存的一些问题

  2019-1-23 


缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级

Redis做缓存是因为Redis访问快,如果客户端在Redis中找得到目标数据,那就不去mysql找了,分担了mysql压力,实现高并发要求

一般缓存都是用户发起一次请求之后,再将该数据加载到缓存(并为该缓存expire一个有效期)

但是缓存实现高并发会出现一堆问题

缓存过期策略

缓存过期可以采用

主动检查(默认每秒扫描10遍,且使用贪心策略一轮随机检查20个key,超过1/5过期就继续检查,直到轮数上线)

惰性检测(用到再判断是否过期)

从服务器是根据主服务器的指令进行操作,不会自己判断过期

缓存淘汰策略

当redis缓存空间不够用(超maxmemory设置),这时候ram放不下的数据就会放到磁盘,发生RAM和磁盘数据的频繁交换,这样极大影响效率,所以要淘汰 一些即使没有过期的key

以下为淘汰方法:

noeviction:停止写请求

FIFO:最先缓存的最先过期:

LFU:最少频率使用

LRU:最近最少使用

ttl:key的剩余寿命ttl越小越先被淘汰

random:随机淘汰

缓存更新策略

Cache aside:由客户端自己负责写redis缓存还是写mysql数据库(先访问redis,找不到,再去mysql取数据,然后放到缓存中)

Read Through:用户请求的时候,若redis服务器没有缓存,则由redis缓存服务器负责去mysql数据库服务器拿数据来更新缓存

Write Through:和Read Through一样是由redis缓存服务器负责与mysql交道,只不过发生在用户更新数据时候

Write Behind Caching Pattern:Write Through,且redis是异步更新mysql的

第②③④策略下,对于客户端而言,redis和mysql是一个整体,不用管谁是谁,缓存细节被隐藏了

缓存雪崩

【缓存失效】,导致所有本来应该查询redis缓存的请求全部取查后端mysql数据库了,造成mysql数据库压力过大崩盘

造成缓存失效的可能性很多,比较多的一种是原有缓存失效,而新缓存还没有储存到redis缓存中(比如大量缓存同时过期),如果是使用普通的hash定位服务器方法也会造成缓存失效。这样会瞬间给mysql造成巨大压力而崩盘。

解决

①避免缓存大量同时过期解决:比如缓存过期时间随机

在新缓存就位之前,临时储存失效缓存:这样请求来了,新缓存还没到,就先直接返回临时缓存,而不是直接过期丢弃之

③防止过多请求同时访问数据库:加锁队列,但这样就没法高并发了,并没有解决实际问题,所以不会用在高并发环境中

缓存穿透

对于数据库没有的数据,每次用户请求的就要先查redis缓存,返回空,然后去mysql查,又返回空,如果大量这样的请求存在,那就造成了缓存穿透,增加系统负荷

解决:

布隆过滤器:将所有可能的数据存在一个布隆过滤器中(一个很大的bitmap),布隆过滤器可以快速判断出一定不存在的数据,进而直接拦截,不进行在系统中查询

缓存不存在的key:那么第二次相同key来查,redis就返回一个默认值告诉他没有,那也就不会继续访问数据库了

缓存预热

开机的时候,不必等用户第一次访问数据库再将数据加载到缓存,而是预热一部分数据直接加载到缓存

缓存降级

弃车保帅,降级非核心业务缓存,保证核心业务缓存


且听风吟