首页 > 其他分享 >三大缓存问题

三大缓存问题

时间:2023-09-23 13:22:41浏览次数:32  
标签:缓存 过期 数据库 布隆 问题 过滤器 数据 三大

三大缓存问题

缓存穿透

什么是缓存穿透?怎么解决?

缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

解决方案:最简单粗暴的方法如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们就把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

image

当我们去查询一个一定不存在的数据,比如Mybatis在缓存是未命中的情况下需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

这显然是很浪费资源的,我们希望的是,如果这个数据不存在,为什么缓存这一层不直接返回空呢,这时就不必再去查数据库了,但是也有一个问题,缓存不去查数据库怎么知道数据库里面到底有没有这个数据呢?

这时我们就可以使用布隆过滤器来进行判断。什么是布隆过滤器?(当然不是打辅助的那个布隆,只不过也挺像,辅助布隆也是挡子弹的)

(35条消息) 请你谈谈对布隆过滤器的理解?_@Autowire的博客-CSDN博客_说一说你对布隆过滤器的理解

image

使用布隆过滤器,能够告诉你某样东西一定不存在或是某样东西可能存在。

布隆过滤器本质是一个存放二进制位的bit数组,如果我们要添加一个值到布隆过滤器中,我们需要使用N个不同的哈希函数来生成N个哈希值,并对每个生成的哈希值指向的bit位置1,如上图所示,一共添加了三个值abc。

接着我们给一个d,那么这时就可以进行判断,如果说d计算的N个哈希值的位置上都是1,那么就说明d可能存在;这时候又来了个e,计算后我们发现有一个位置上的值是0,这时就可以直接断定e一定不存在。

缓存击穿

image

某个 Key 属于热点数据,访问非常频繁,同一时间很多人都在访问,在这个Key失效的瞬间,大量的请求到来,这时发现缓存中没有数据,就全都直接请求数据库,相当于击穿了缓存屏障,直接攻击整个系统核心。

这种情况下,最好的解决办法就是不让Key那么快过期,如果一个Key处于高频访问,那么可以适当地延长过期时间。

缓存雪崩

image

当你的Redis服务器炸了或是大量的Key在同一时间过期,这时相当于缓存直接GG了,那么如果这时又有很多的请求来访问不同的数据,同一时间内缓存服务器就得向数据库大量发起请求来重新建立缓存,很容易把数据库也搞GG。

解决这种问题最好的办法就是设置高可用,也就是搭建Redis集群,当然也可以采取一些服务熔断降级机制,这些内容我们会在SpringCloud阶段再进行探讨。

缓存穿透:是指客户端查询了根本不存在的数据,使得这个请求直达存储层,导致其负载过大甚至造成宕机。这种情况可能是由于业务层误将缓存和库中的数据删除造成的,当然也不排除有人恶意攻击,专门访问库中不存在的数据导致缓存穿透。 我们可以通过缓存空对象的方式和布隆过滤器两种方式来解决这一问题。

  • 缓存空对象是指当存储层未命中后,仍然将空值存入缓存层 ,当客户端再次访问数据时,缓存层直接返回空值。

  • 还可以将数据存入布隆过滤器,访问缓存之前以过滤器拦截,若请求的数据不存在则直接返回空值。

缓存击穿:当一份访问量非常大的热点数据缓存失效的瞬间,大量的请求直达存储层,导致服务崩溃。 缓存击穿可以通过热点数据不设置过期时间来解决,这样就不会出现上述的问题,这是“物理”上的永不过期。或者为每个数据设置逻辑过期时间,当发现该数据逻辑过期时,使用单独的线程重建缓存。除了永不过期的方式,我们也可以通过加互斥锁的方式来解决缓存击穿,即对数据的访问加互斥锁,当一个线程访问该数据时,其他线程只能等待。这个线程访问过后,缓存中的数据将被重建,届时其他线程就可以直接从缓存中取值。

缓存雪崩:是指当某一时刻缓存层无法继续提供服务,导致所有的请求直达存储层,造成数据库宕机。可能是缓存中有大量数据同时过期,也可能是Redis节点发生故障,导致大量请求无法得到处理。

  • 缓存雪崩的解决方式有三种;

    第一种是在设置过期时间时,附加一个随机数,避免大量的key同时过期。

    第二种是启用降级和熔断措施,即发生雪崩时,若应用访问的不是核心数据,则直接返回预定义信息/空值/错误信息。或者在发生雪崩时,对于访问缓存接口的请求,客户端并不会把请求发给Redis,而是直接返回。

    第三种是构建高可用的Redis服务,也就是采用哨兵或集群模式,部署多个Redis实例,这样即使个别节点宕机,依然可以保持服务的整体可用。

标签:缓存,过期,数据库,布隆,问题,过滤器,数据,三大
From: https://www.cnblogs.com/liuzonglin/p/17724262.html

相关文章

  • Mybatis二级缓存
    Mybatis二级缓存还记得我们在学习Mybatis讲解的缓存机制吗,我们当时介绍了二级缓存,它是Mapper级别的缓存,能够作用与所有会话。但是当时我们提出了一个问题,由于Mybatis的默认二级缓存只能是单机的,如果存在多台服务器访问同一个数据库,实际上二级缓存只会在各自的服务器上生效,但是我......
  • ts和vue3的结合常见的一些问题(持续更新)
    特此注意是vue3,而不是vue2使用typescript的interface关键词定义一个存数据的数据类型interfacePosition{long:number,lnt:number,height:number}constposition=ref<Position>({long:0,lnt:0,height:0})......
  • 保研面试英文问题记录1
    Thedifferencebetweenundergraudateandpostgraduate?Theundergraduateeducationprovidesfoundationalknowledgeandskillsinabroaddiscipline.Thepostgraduateeducationfocusonspecializedexpertiseandreserchcapabilityinaparticularfield.Th......
  • 计算机面试问题记录1
    c++中如何判断一个浮点数是否为0?判断是否在一个误差范围内:cppconstfloateps=1e-6;if(abs(x)<eps){//xisnearlyzero}舍入到整数再判断:cppfloatx=0.00001;if(round(x)==0){//xisnearlyzero}c++如何提高多重循环的效率?一、实例化变量尽量放......
  • ClickHouse数据缓存与性能优化技术实现最佳实践与案例
    前言ClickHouse是一款高性能的列式存储数据库,它的性能在处理海量数据时非常出色。但是,在实际应用中,我们还需要考虑如何进一步优化ClickHouse的性能,特别是在数据缓存方面。本文将深入探讨ClickHouse的数据缓存与性能优化技术实现最佳实践与案例。ClickHouse数据缓存ClickHouse的......
  • chm文件打开不显示内容问题的解决方法
    一、检查文件名和路径是否包含中文或特殊字符1、chm文件是Windows帮助文件格式,其底层是由HTML、CSS、JavaScript等语言构成的。有些特殊字符或中文可能会影响文件的路径或文件名的读取,从而导致文件打开不显示内容。2、解决方法:将文件路径和文件名改为英文或数字命名,同时确保全部使......
  • Android面试必问的6个问题,跟面试官斗智斗勇
    前言在职场中,面试是筛选和评估候选人的重要环节。那么对于各位程序员来讲,在面试的时候,面对HR的“套路”又该如何应对呢?以下是在职场中面试必问的6个问题,以及应对思路。一、请做一下简单的自我介绍面试时,基本上所有求职者听到的第一个问题都是这个,而一般人回答往往也只说姓名、年龄......
  • 'main' attribute cannot be used in a module that contains top-level code 问题解
    核心是@main注解在main.swift文件中,可以重新命名下参考资料https://stackoverflow.com/questions/73431031/swift-cli-app-main-attribute-cannot-be-used-in-a-module-that-contains-top-leve......
  • Docker缓存占有太大的磁盘空间
    Docker在不重建容器的情况下,日志文件默认会一直追加,时间一长会逐渐占满服务器的硬盘的空间,内存消耗也会一直增加。查出占用磁盘较大的文件Docker的日志文件存在/var/lib/docker/containers目录中,通过下面的命令可以将日志文件夹根据升序的方式罗列出来。sudodu-d1-h/var......
  • Arthas问题排除案例
    一、现象(死循环)线上CPU100%(内存无法回收)内存OOM二、原因:(死循环)不断的进行加减操作、不断的死循环打印日志、不断的new对象(内存溢出)不断的大量new对象,但不被回收,也可能不是死循环,但new出的对象无法被回收,导致内存溢出三、解决过程1、启动arthas2、查询cpu占用最高线程thr......