跳至主要內容

缓存击穿和缓存穿透如何解决

Echo Hou...大约 3 分钟Redis面试高频缓存

缓存击穿和缓存穿透如何解决

当数据量达到一定数量级后,对于用户经常访问的数据(热点数据)或者构建比较复杂的数据,只用MySQL进行查询是比较耗时的,所以我们用Redis进行缓存,因为是基于内存的数据库,所以查询很快。

但是使用缓存又会产生一些问题,比如缓存雪崩、缓存击穿、缓存穿透。

今天来重点讲一下缓存击穿和缓存穿透(滴滴面试题)。

缓存击穿

当Web应用触发请求,到Redis读取数据,而此时热点数据缓存过期,缓存无法命中,就去数据库中请求数据,这一瞬间大量请求就会打到数据库,数据库压力过大,可能会有宕机的风险。

如何解决

缓存击穿的原因就是热点数据缓存过期,那么其中一个解决方案就是:不给热点数据设置过期时间,由后台异步更新缓存,或者当热点数据快要过期的时候,提前通知后台线程更新缓存以及重新设置更新时间。

还有一个点就是缓存无法命中的场景,可以设置互斥锁,保证同一时间只有一个用户线程更新缓存,未能获取互斥锁的请求,要么返回空值或者默认值,要么等待锁释放后重新读取缓存。

缓存穿透

当Web应用触发请求,到Redis读取数据,而此时缓存中没有数据,缓存无法命中,就去数据库中请求数据,而数据库中也没有数据,就无法构建缓存。这时候大量请求又请求数据库,而数据库没有对应的资源,数据库承受巨大压力,有宕机的风险。

如何解决

这种现象的原因就是:数据库中没有Web应用要请求的数据。

一、可能是恶意请求,数据压根就不存在。我们可以在接口层面,对于一些非法的请求进行拦截判断,也就不会到达数据库了。

二、缓存空值或默认值。当线上发现发生缓存穿透的问题,我们可以针对请求,在Redis里缓存一个空值或者默认值,会直接返回给前端,而不会请求数据库。

三、布隆过滤器。在向数据库写入数据的时候,在布隆过滤器上做个标记,在Web应用请求查询的时候,先查布隆,如果不存在就直接返回,如果存在再向缓存中查询数据。但是可能有精度问题,因为布隆过滤器底层是由位图数组和哈希算法实现的,可能会存在哈希碰撞的问题,如果布隆判断不存在,就一定不存在,但是如果判断存在,实际上可能不存在。

上次编辑于:
贡献者: houbingzhi123
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8