我的编程空间,编程开发者的网络收藏夹
学习永远不晚

缓存穿透问题

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

缓存穿透问题

 一. 缓存穿透 (请求数据缓存大量不命中):

    缓存穿透是指查询一个一定不存在的数据,由于缓存不命中,并且出于容错考虑, 如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

    例如:下图是一个比较典型的cache-storage架构,cache(例如memcache, redis等等) + storage(例如mysql, hbase等等)架构,查一个压根就不存在的值, 如果不做兼容,永远会查询storage。

缓存穿透问题

二. 危害:

     对底层数据源(mysql, hbase, http接口, rpc调用等等)压力过大,有些底层数据源不具备高并发性。下载

     例如mysql一般来说单台能够扛1000-QPS就已经很不错了(别说你的查询都是select * from table where id=xx 以及你的机器多么牛逼,那就有点矫情了)

     例如他人提供的一个抗压性很差的http接口,可能穿透会击溃他的服务。

     缓存穿透问题

三. 如何发现:

   我们可以分别记录cache命中数, storage命中数,以及总调用量,如果发现空命中(cache,storage都没有命中)较多,可能就会在缓存穿透问题。下载

   注意:缓存本身的命中率(例如redis中的info提供了类似数字,只代表缓存本身)不代表storage和业务的命中率。

   

四. 产生原因以及业务是否允许?

    产生原因有很多:可能是代码本身或者数据存在的问题造成的,也很有可能是一些恶意***、爬虫等等(因为http读接口都是开放的)

    业务是否允许:这个要看做的项目或者业务是否允许这种情况发生,比如做一些非实时的推荐系统,假如新用户来了,确实没有他的推荐数据(推荐数据通常是根据历史行为算出),这种业务是会发生穿透现象的,至于业务允不允许要具体问题具体分析了。下载

 

五. 解决方法:

解决思路大致有两个,如下表。下面将分别说明

解决缓存穿透适用场景维护成本
缓存空对象

1. 数据命中不高

2. 数据频繁变化实时性高

1.代码维护简单

2.需要过多的缓存空间

3. 数据不一致

bloomfilter或者压缩filter提前拦截

1. 数据命中不高

2. 数据相对固定实时性低

1.代码维护复杂

2.缓存空间占用少

       1. 缓存空对象下载

         缓存穿透问题

        (1). 定义:如上图所示,当第②步MISS后,仍然将空对象保留到Cache中(可能是保留几分钟或者一段时间,具体问题具体分析),下次新的Request(同一个key)将会从Cache中获取到数据,保护了后端的Storage。

        (2) 适用场景:数据命中不高,数据频繁变化实时性高(一些乱转业务)

        (3) 维护成本:代码比较简单,但是有两个问题:

             第一是空值做了缓存,意味着缓存系统中存了更多的key-value,也就是需要更多空间(有人说空值没多少,但是架不住多啊),解决方法是我们可以设置一个较短的过期时间。

             第二是数据会有一段时间窗口的不一致,假如,Cache设置了5分钟过期,此时Storage确实有了这个数据的值,那此段时间就会出现数据不一致,解决方法是我们可以利用消息或者其他方式,清除掉Cache中的数据。

        (4) 伪代码:

Java代码  下载

  1. package com.carlosfu.service;  

  2.   

  3. import org.apache.commons.lang.StringUtils;  

  4.   

  5. import com.carlosfu.cache.Cache;  

  6. import com.carlosfu.storage.Storage;  

  7.   

  8.   

  9. public class XXXService {  

  10.   

  11.       

  12.     private Cache cache = new Cache();  

  13.   

  14.       

  15.     private Storage storage = new Storage();  

  16.   

  17.       

  18.     public String getNormal(String key) {  

  19.         // 从缓存中获取数据  

  20.         String cacheValue = cache.get(key);  

  21.         // 缓存为空  

  22.         if (StringUtils.isBlank(cacheValue)) {  

  23.             // 从存储中获取  

  24.             String storageValue = storage.get(key);  

  25.             // 如果存储数据不为空,将存储的值设置到缓存  

  26.             if (StringUtils.isNotBlank(storageValue)) {  

  27.                 cache.set(key, storageValue);  

  28.             }  

  29.             return storageValue;  

  30.         } else {  

  31.             // 缓存非空  

  32.             return cacheValue;  

  33.         }  

  34.     }  

  35.   

  36.   

  37.       

  38.     public String getPassThrough(String key) {  

  39.         // 从缓存中获取数据  

  40.         String cacheValue = cache.get(key);  

  41.         // 缓存为空  

  42.         if (StringUtils.isBlank(cacheValue)) {  

  43.             // 从存储中获取  

  44.             String storageValue = storage.get(key);  

  45.             cache.set(key, storageValue);  

  46.             // 如果存储数据为空,需要设置一个过期时间(300秒)  

  47.             if (StringUtils.isBlank(storageValue)) {  

  48.                 cache.expire(key, 60 * 5);  

  49.             }  

  50.             return storageValue;  

  51.         } else {  

  52.             // 缓存非空  

  53.             return cacheValue;  

  54.         }  

  55.     }  

  56.   

  57. }  

 

2. bloomfilter或者压缩filter(bitmap等等)提前拦截下载

缓存穿透问题

        (1). 定义:如上图所示,在访问所有资源(cache, storage)之前,将存在的key用布隆过滤器提前保存起来,做第一层拦截, 例如: 我们的推荐服务有4亿个用户uid, 我们会根据用户的历史行为进行推荐(非实时),所有的用户推荐数据放到hbase中,但是每天有许多新用户来到网站,这些用户在当天的访问就会穿透到hbase。为此我们每天4点对所有uid做一份布隆过滤器。如果布隆过滤器认为uid不存在,那么就不会访问hbase,在一定程度保护了hbase(减少30%左右)。下载

            

        (2) 适用场景:数据命中不高,数据相对固定实时性低(通常是数据集较大)

        (3) 维护成本:代码维护复杂, 缓存空间占用少

              第一是空值做了缓存,意味着缓存系统中存了更多的key-value,也就是需要更多空间(有人说空值没多少,但是架不住多啊),解决方法是我们可以设置一个较短的过期时间。

              第二是数据会有一段时间窗口的不一致,假如,Cache设置了5分钟过期,此时Storage确实有了这个数据的值,那此段时间就会出现数据不一致,解决方法是我们可以利用消息或者其他方式,清除掉Cache中的数据。


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

缓存穿透问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

一篇吃透Redis缓存穿透、雪崩、击穿问题

前言:在学Redis之前我们查询数据的时候都是直接查询数据库的,但是这样会有一个潜在的问题:“如果用户量很大,所有请求都去访问数据库,那么会使数据库压力过大,导致性能下降甚至宕机”。因此,我们需要把经常访问的数据放到
2023-05-22

Redis缓存击穿和穿透问题怎么解决

Redis缓存击穿和穿透是常见的性能问题,可以通过以下方法来解决:缓存击穿:当某个热点数据失效时,大量请求同时访问数据库,导致数据库压力突增。解决方法包括使用互斥锁避免并发请求穿透缓存、设置热点数据永不过期、使用布隆过滤器等方法。缓存穿透:
Redis缓存击穿和穿透问题怎么解决
2024-05-07

Redis缓存穿透、缓存击穿、缓存雪崩

使用redis作为缓存时,存在一些应用问题,包括缓存穿透、缓存击穿、缓存雪崩。 Redis缓存穿透、缓存击穿缓存雪崩redis常被用于作为后台数据库的缓存,缓存一些热点访问数据,根据局部性原理,缓存能够处理大部分请求。当请求数据未命中缓存时,才会引起对数
Redis缓存穿透、缓存击穿、缓存雪崩
2014-07-07

怎么解决Redis缓存雪崩、击穿与穿透问题

这篇文章主要讲解了“怎么解决Redis缓存雪崩、击穿与穿透问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决Redis缓存雪崩、击穿与穿透问题”吧!一、缓存雪崩1. 什么是缓存雪崩?
2022-11-30

缓存穿透、缓存击穿、缓存雪崩、热点数据失效问题的解决方案

在我们的平常项目中多多少少会用到缓存,因为一些数据没必要每次查询都跑到数据库中查询。 1、缓存穿透         请求去查询一条不存在的数据,也就是缓存和数据库都查询不到这条数据,但每次请求都会打到数据库上去。         这种查询不存在数据的现象我们
缓存穿透、缓存击穿、缓存雪崩、热点数据失效问题的解决方案
2021-10-17

怎么在java中解决缓存穿透问题

怎么在java中解决缓存穿透问题?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java有哪些集合类Java中的集合主要分为四类:1、List列表:有序的,可重复的;2、Qu
2023-06-14

redis的缓存雪崩、缓存穿透和缓存击穿

缓存雪崩:比如给缓存中的key设置了统一的过期时间,而在过期时间点,有大量的请求进来,这个时候redis中没有用户请求的资源,所以所有的请求会全部拥到数据库,如果数据库有报警监测的话,可能会报一下警,然后数据库就挂掉了。如果这时候把数据重新起来,redis上还
2017-11-21

redis缓存击穿和缓存穿透的区别

缓存击穿和缓存穿透的区别:缓存击穿:当大量并发请求访问未缓存的 key 时发生,导致数据库压力过大。缓存穿透:当恶意请求或爬虫频繁访问从未被缓存过的 key 时发生,导致不必要的数据库访问。Redis缓存击穿与缓存穿透的区别问题:缓存击穿
redis缓存击穿和缓存穿透的区别
2024-04-19

redis缓存雪崩、缓存击穿和缓存穿透是什么

这篇文章主要介绍了redis缓存雪崩、缓存击穿和缓存穿透是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇redis缓存雪崩、缓存击穿和缓存穿透是什么文章都会有所收获,下面我们一起来看看吧。缓存雪崩首先来看看
2022-11-30

Redis缓存击穿、缓存穿透、缓存雪崩如何解决

本篇内容介绍了“Redis缓存击穿、缓存穿透、缓存雪崩如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Redis缓存使用场景Redis
2023-07-05

redis的缓存击穿和缓存穿透一样吗

否,redis缓存击穿和穿透是不同的概念。击穿是指并发访问未缓存的数据导致直接访问数据库;穿透是指恶意请求访问不存在的数据,导致缓存和数据库都未命中。解决方法分别是使用互斥锁和参数校验。Redis缓存击穿和缓存穿透问题: Redis缓存击
redis的缓存击穿和缓存穿透一样吗
2024-04-20

关于缓存穿透,缓存击穿,缓存雪崩,热点数据失效问题的解决方案(转)

1.我们使用缓存时的业务流程大概为:当我们查询一条数据时,先去查询缓存,如果缓存有就直接返回,如果没有就去查询数据库,然后返回。这种情况下就可能出现下面的一些现象。2.缓存穿透2.1什么是缓存穿透缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的
关于缓存穿透,缓存击穿,缓存雪崩,热点数据失效问题的解决方案(转)
2017-06-16

缓存穿透,缓存击穿,缓存雪崩解决方案分析

阅读本文大概需要 3.7 分钟。一、前言设计一个缓存系统,不得不要考虑的问题就是:缓存穿透、缓存击穿与失效时的雪崩效应。二、缓存穿透缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则
2023-06-05

编程热搜

目录