精华内容
下载资源
问答
  • 常见的缓存问题

    2020-10-12 22:56:45
    一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(DB等)。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力。 也就是说,对不...

    数据读

    1.缓存穿透

    一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(DB等)。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力。
    也就是说,对不存在的key进行高并发访问,导致数据库压力瞬间增大,这就叫缓存穿透。
    解决方案:
    对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

    2.缓存雪崩

    当服缓存服务器重启或者大量缓存集中在某一个时间段失效,这样失效的时候,会给后端系统带来很大压力。
    突然间大量的key失效了或缓存服务重启,大量访问数据库。
    解决方案:
    1.key的失效期分散开,不同的key设置不同的有效期
    2.设置二级缓存
    3.高可用

    3.缓存击穿

    对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。
    缓存在某个时间点过期的时候,恰好在这个时间点对这个key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
    解决方案:
    使用分布式锁控制访问的线程
    使用redis的setnx互斥锁先进行判断,这样其它线程就处于等待状态,保证不会有大并发请求去操作数据库。

    数据写

    数据不一致的根源:数据源不一样
    如何解决:
    强一致性很难,追求最终一致性
    互联网业务数据处理特点:
    高吞吐量
    低延迟
    数据敏感性低于金融业
    时序控制是否可行?
    先更新数据库再更新缓存或者先更新缓存再更新数据库
    本质上不是一个原子操作,所以时序控制不可行

    保证数据的最终一致性(延时双删)

    1.先更新数据库同时删除缓存key,等读的时候再填充缓存
    2.2秒后再删除一次缓存key
    3.设置缓存过期时间Expired Time 10秒或者1小时
    4.将缓存删除失败记录到日志中,利用脚本提取失败记录再次删除
    升级方案:
    通过数据库的binlog来异步淘汰key,利用工具(canal)将binlog日志采集发送到MQ中,然后通过ACK机制确认处理删除缓存。

    展开全文
  • 缓存预热这个应该是一个比较常见的概念,相信很多小伙伴都应该可以很容易的理解,缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的...

    缓存预热

    缓存预热这个应该是一个比较常见的概念,相信很多小伙伴都应该可以很容易的理解,缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

    现象:

         项目刚上线,服务器迅速宕机。

    问题排查:

    1、请求数量较高
    2、主从之间数据吞吐量较大,数据同步操作频度较高

    3、redis中没有缓存数据,全部请求数据库。

    解决思路:

    前置准备工作:
    1. 日常例行统计数据访问记录,统计访问频度较高的热点数据
    2. 利用LRU数据删除策略,构建数据留存队列
    例如:storm与kafka配合
    准备工作:
    1. 将统计结果中的数据分类,根据级别,redis优先加载级别较高的热点数据
    2. 利用分布式多服务器同时进行数据读取,提速数据加载过程
    3. 热点数据主从同时预热
    实施:
    1. 使用脚本程序固定触发数据预热过程
    2. 如果条件允许,使用了CDN(内容分发网络),效果会更好

    总结:

    缓存预热就是系统启动前,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

    缓存雪崩

    缓存雪崩可能是因为数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。

    现象:

    1. 系统平稳运行过程中,忽然数据库连接量激增
    2. 应用服务器无法及时处理请求
    3. 大量408,500错误页面出现
    4. 客户反复刷新页面获取数据
    5. 数据库崩溃
    6. 应用服务器崩溃
    7. 重启应用服务器无效
    8. Redis服务器崩溃
    9. Redis集群崩溃
    10. 重启数据库后再次被瞬间流量放倒

    问题排查:

    1. 在一个较短的时间内,缓存中较多的key集中过期
    2. 此周期内请求访问过期的数据,redis未命中,redis向数据库获取数据
    3. 数据库同时接收到大量的请求无法及时处理
    4. Redis大量请求被积压,开始出现超时现象
    5. 数据库流量激增,数据库崩溃
    6. 重启后仍然面对缓存中无数据可用
    7. Redis服务器资源被严重占用,Redis服务器崩溃
    8. Redis集群呈现崩塌,集群瓦解
    9. 应用服务器无法及时得到数据响应请求,来自客户端的请求数量越来越多,应用服务器崩溃
    10. 应用服务器,redis,数据库全部重启,效果不理想

    解决思路:

    1. 更多的页面静态化处理
    2. 构建多级缓存架构

    • Nginx缓存+redis缓存+ehcache缓存

    3. 检测Mysql严重耗时业务进行优化

    • 对数据库的瓶颈排查:例如超时查询、耗时较高事务等

    4. 灾难预警机制

    • 监控redis服务器性能指标(Grafana+Prometheus系统监控之Redis)
    1. CPU占用、CPU使用率
    2.  内存容量
    3.  查询平均响应时间
    4.  线程数

    5. 限流、降级
    短时间范围内牺牲一些客户体验,限制一部分请求访问,降低应用服务器压力,待业务低速运转后再逐步放开访问(比如令牌桶或者sentinel限流)

     解决方案:

    1. LRU与LFU切换
    2. 数据有效期策略调整

    •  根据业务数据有效期进行分类错峰,A类90分钟,B类80分钟,C类70分钟
    • 过期时间使用固定时间+随机值的形式,稀释集中到期的key的数量

    3. 超热数据使用永久key
    4. 定期维护(自动+人工)
    对即将过期数据做访问量分析,确认是否延时,配合访问量统计,做热点数据的延时
    5. 加锁,慎用!不推荐在高并发的场景下使用

    缓存击穿

    我们在项目中使用缓存通常都是先检查缓存中是否存在,如果存在直接返回缓存内容,如果不存在就直接查询数据库然后再缓存查询结果返回。这个时候如果我们查询的某一个数据在缓存中一直不存在,就会造成每一次请求都查询DB,这样缓存就失去了意义,在流量大时,可能DB就挂掉了。

    现象:

    1. 系统平稳运行过程中
    2. 数据库连接量瞬间激增
    3. Redis服务器无大量key过期
    4. Redis内存平稳,无波动
    5. Redis服务器CPU正常
    6. 数据库崩溃

    问题排查:
    1. Redis中某个key过期,该key访问量巨大
    2. 多个数据请求从服务器直接压到Redis后,均未命中
    3. Redis在短时间内发起了大量对数据库中同一数据的访问

    问题分析:

    • 单个key高热数据
    •  key过期

    解决方案:

    1. 预先设定

    • 以电商为例,每个商家根据店铺等级,指定若干款主打商品,在购物节期间,加大此类信息key的过期时长

              注意:购物节不仅仅指当天,以及后续若干天,访问峰值呈现逐渐降低的趋势
    2. 现场调整

    • 监控访问量,对自然流量激增的数据延长过期时间或设置为永久性key

    3. 后台刷新数据

    • 启动定时任务,高峰期来临之前,刷新数据有效期,确保不丢失

    4. 二级缓存

    • 设置不同的失效时间,保障不会被同时淘汰就行

    5. 加锁

    • 分布式锁,防止被击穿,但是要注意也是性能瓶颈,慎重!

    总结
    缓存击穿就是单个高热数据过期的瞬间,数据访问量较大,未命中redis后,发起了大量对同一数据的数据库访问,导致对数据库服务器造成压力。应对策略应该在业务数据分析与预防方面进行,配合运行监控测试与即时调整策略,毕竟单个key的过期监控难度较高,配合雪崩处理策略即可。

    缓存穿透

    缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。

    现象:

    1. 系统平稳运行过程中
    2. 应用服务器流量随时间增量较大
    3. Redis服务器命中率随时间逐步降低
    4. Redis内存平稳,内存无压力
    5. Redis服务器CPU占用激增
    6. 数据库服务器压力激增
    7. 数据库崩溃

    问题排查:
    1. Redis中大面积出现未命中
    2. 出现非正常URL访问

    问题分析
    1.获取的数据在数据库中也不存在,数据库查询未得到对应数据
    2.Redis获取到null数据未进行持久化,直接返回
    3. 下次此类数据到达重复上述过程
    4. 出现黑客攻击服务器

    解决方案
    1. 缓存null

    • 对查询结果为null的数据进行缓存(长期使用,定期清理),设定短时限,例如30-60秒,最高5分钟

    2. 白名单策略

    •  提前预热各种分类数据id对应的bitmaps,id作为bitmaps的offset,相当于设置了数据白名单。当加载正常数据时,放行,加载异常数据时直接拦截(效率偏低)
    •  使用布隆过滤器(有关布隆过滤器的命中问题对当前状况可以忽略)

    3. 实施监控

    • 实时监控redis命中率(业务正常范围时,通常会有一个波动值)与null数据的占比
    1. 非活动时段波动:通常检测3-5倍,超过5倍纳入重点排查对象
    2. 活动时段波动:通常检测10-50倍,超过50倍纳入重点排查对象
    3. 根据倍数不同,启动不同的排查流程。然后使用黑名单进行防控(运营)

    4. key加密

    • 问题出现后,临时启动防灾业务key,对key进行业务层传输加密服务,设定校验程序,过来的key校验
    • 例如每天随机分配60个加密串,挑选2到3个,混淆到页面数据id中,发现访问key不满足规则,驳回数据访问。

    总结
    缓存击穿访问了不存在的数据,跳过了合法数据的redis数据缓存阶段,每次访问数据库,导致对数据库服务器造成压力。通常此类数据的出现量是一个较低的值,当出现此类情况以毒攻毒,并及时报警。应对策略应该在临时预案防范方面多做文章。

    展开全文
  • 缓存可以有效提高查询速度,但是由于缓存的时限以及非法操作,导致缓存系统会出现三个问题 1、缓存穿透 2、缓存雪崩 3、缓存击穿 4、缓存预热 2、实际开发使用 大部分互联网应用当中,缓存的使用方式如下所示: ...

    一、使用redis作为缓存

    1、概述

    缓存可以有效提高查询速度,但是由于缓存的时限以及非法的操作,导致缓存系统会出现三个问题
    1、缓存穿透
    2、缓存雪崩
    3、缓存击穿
    4、缓存预热
    

    2、实际开发使用

    大部分互联网应用当中,缓存的使用方式如下所示:

    img

    3、调用流程

    1. 当业务系统发起某一个查询请求时,首先判断缓存中是否有该数据;
    2. 如果缓存当中存在,则直接返回数据;
    3. 如果缓存当中不存在,则查询数据库,将返回的结果保存到缓存当中,同时返回给业务系统

    二、四大问题解析

    一、缓存击穿

    1、概念
    我们一般都会给缓存数据设定一个失效时间,过了失效时间后,该数据会被缓存删除,从而在一定程度上保证了数据的实时性。
    但是,对于一些请求量极高的热点数据而言,一旦过了有效时间,此刻会有大量请求落在了数据库上,从而可能会导致数据库崩溃。其过程如下图所示
    
    img
    如果某一个热点数据失效,那么当再次有该数据的查询请求[req-1]时就会前往数据库查询。但是,从请求发往数据库,到该数据更新到缓存中的这段时间中,由于缓存中仍然没有该数据,因此这段时间内到达的查询请求都会落到数据库上,这将会对数据库造成巨大的压力。此外,当这些请求查询完成后,都会重复更新缓存。
    
    
    2、解决方法
    1、互斥锁
    此方法只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。
    当第一个数据库查询请求发起后,就将缓存中该数据上锁;此时到达缓存的其他查询请求将无法查询该字段,从而被阻塞等待;当第一个请求完成数据库查询,并将数据更新值缓存后,释放锁;此时其他被阻塞的查询请求将可以直接从缓存中查到该数据。
    
    当某一个热点数据失效后,只有第一个数据库查询请求发往数据库,其余所有的查询请求均被阻塞,从而保护了数据库。但是,由于采用了互斥锁,其他请求将会阻塞等待,此时系统的吞吐量将会下降。这需要结合实际的业务考虑是否允许这么做。
    

    img互斥锁可以避免某一个热点数据失效导致数据库崩溃的问题,而在实际业务中,往往会存在一批热点数据同时失效的场景。那么,对于这种场景该如何防止数据库过载呢?

    设置不同的失效时间
    当我们向缓存中存储这些数据的时候,可以将他们的缓存失效时间错开。这样能够避免同时失效。如:在一个基础时间上加/减一个随机数,从而将这些缓存的失效时间错开
    
    2、永远不过期
    永远不过期”包含两层意思: 
    从缓存层面来看,确实没有设置过期时间,所以不会出现热点 key 过期后产生的问题,也就是“物理”不过期。 
    从功能层面来看,为每个 value 设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去构建缓存
    

    img

    从实战看,此方法有效杜绝了热点 key 产生的问题,但唯一不足的就是重构缓存期间,会出现数据不一致的情况,这取决于应用方是否容忍这种不一致。
    
    3、方案对比
    1. 互斥锁 (mutex key):这种方案思路比较简单,但是存在一定的隐患,如果构建缓存过程出现问题或者时间较长,可能会存在死锁和线程池阻塞的风险,但是这种方法能够较好的降低后端存储负载并在一致性上做的比较好。
    2. ” 永远不过期 “:这种方案由于没有设置真正的过期时间,实际上已经不存在热点 key 产生的一系列危害,但是会存在数据不一致的情况,同时代码复杂度会增大。

    二、缓存雪崩

    1、概念
    通过上文流程,我们可以知道,缓存其实扮演了一个保护数据库的角色,它帮助数据库抵挡了大量的查询操作,从而避免数据库的IO使用率提高到不可控程度,导致宕机。
    如果缓存因某种原因发生了宕机,那么原本被缓存抵挡的海量查询请求就会全部落在了数据库当中。这时候,如果数据库无法支撑这么大的查询请求压力,则有可能会导致数据宕机。
    这就是缓存雪崩
    

    img

    2、解决方法
    1、使用缓存集群,保证缓存高可用
    如果缓存设计成高可用的,即使个别节点、个别机器、甚至时机房宕掉,也还是可以提供服务。只要集群当中还有集群在充当缓存的角色,那么系统还是可以正常运行。
    
    2、使用Hystrix
    Hystrix是一款开源的“防雪崩工具”,它通过 熔断、降级、限流三个手段来降低雪崩发生后的损失。
    	Hystrix就是一个Java类库,它采用命令模式,每一项服务处理请求都有各自的处理器。所有的请求都要经过各
    自的处理器。
    	处理器会记录当前服务的请求失败率。一旦发现当前服务的请求失败率达到预设的值,Hystrix将会拒绝随后该
    服务的所有请求,直接返回一个预设的结果。这就是所谓的“熔断”。
    	当经过一段时间后,Hystrix会放行该服务的一部分请求,再次统计它的请求失败率。如果此时请求失败率符合
    预设值,则完全打开限流开关;如果请求失败率仍然很高,那么继续拒绝该服务的所有请求。这就是所谓的“限流”。
    	而Hystrix向那些被拒绝的请求直接返回一个预设结果,被称为“降级”。
    

    三、缓存穿透

    1、概念
    业务系统要查询的数据根本不存在!当业务系统发起查询时,按照上输流程,首先会前往缓存中查询,由于缓存中不存在,然后再前往数据库钟查村。由于该数据根本上就不存在,因为数据库也返回空,这就是缓存穿透。
    综上所述:业务系统访问呀本就不存在的数据,或者由于恶意伪造访问请求导致的业务系统异常请求,就成为缓存穿透
    
    2、危害
    如果存在海量请求查询压根就不存在的数据,那么就写海量请求都会落到数据库钟,导致数据库压力剧增,可能会导致系统崩溃。
    
    3、为什么会发生缓存穿透
    发生缓存穿透的原因有很多,一般为如下两种:
    
    1. 恶意攻击,故意营造大量不存在的数据请求我们的服务,由于缓存中并不存在这些数据,因为海量请求均落在数据库中,从而可能会导致数据库崩溃。
    2. 代码逻辑错误。这个是业务编码的问题。
    4、缓存穿透的解决方案

    下面来介绍几种防止缓存击出的手段

    1、缓存空数据
    之所以发生缓存穿透,是因为缓存当中没有存储这些控数据的key,导致这些请求全部落在了数据库上。
    那么我们可以对缓存的业务代码进行改动,将数据库查询结果为空的key也存储在缓存当中。当后续又出现该key的查询请求时,缓存直接返回努力了,从而无需查询数据库
    

    img

    缓存空对象会有两个问题: 
    第一,空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间 ( 如果是攻击,问题更严重 ),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。 
    第二,缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。例如过期时间设置为 5 分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致,此时可以利用消息系统或者其他方式清除掉缓存层中的空对象。
    
    2、布隆过滤器

    第二种避免缓存穿透的方式即使用BloomFilter

    它需要在缓存之前再加一道判断逻辑,即将数据库当中存储的所有的key都存到BloomFilter当中。

    当业务系统有查询请求的时候,首先去BloomFilter中查询该key是否存在。若不存在,则说明数据库中也不存在该数据,因此缓存都不要查了,直接返回null。若存在,则继续执行后续的流程,先前往缓存中查询,缓存中没有的话再前往数据库中的查询。
    这种方法适用于数据命中不高,数据相对固定实时性低(通常是数据集较大)的应用场景,代码维护较为复杂,但是缓存空间占用少。 
    
    3、暴力解决方法
    正常逻辑上,我们都是根据ID来作为key去数据库当中获取数据。而key的值范围一般都不会是负数。在业务代码当中事先判断id值的合法性。若是负数,则进行不进行后续操作即可。
    
    5、前两种方法比对

    这两种方案都能解决缓存穿透的问题,但使用场景却各不相同。

    对于一些恶意攻击,查询的key往往各不相同,而且数据贼多。此时,第一种方案就显得提襟见肘了。因为它需要存储所有空数据的key,而这些恶意攻击的key往往各不相同,而且同一个key往往只请求一次。因此即使缓存了这些空数据的key,由于不再使用第二次,因此也起不了保护数据库的作用。
    因此,对于空数据的key各不相同、key重复请求概率低的场景而言,应该选择第二种方案。而对于空数据的key数量有限、key重复请求概率较高的场景而言,应该选择第一种方案。
    
    

    四、缓存预热

    1、概念
    缓存预热这个应该是一个比较常见的概念,相信很多小伙伴都应该可以很容易的理解,缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
    
    2、方案借鉴
    1. 直接写个缓存刷新页面,上线时手工操作下;
    2. 数据量不大,可以在项目启动的时候自动进行加载;
    3. 定时刷新缓存;

    PS:图片直接从网络上摘取,如有侵权,请及时联系我。

    展开全文
  • 本文总结了一些使用缓存常见的问题及解决方案,以后在遇到这类问题时可以作为参考,在设计缓存系统的时候也应该考虑这些常见的情况。 为了表述方便,本文以数据库查询缓存为例,使用缓存可以减小对数据库的压力。...

    前言

    使用缓存可以缓解大流量压力,显著提高程序的性能。我们在使用缓存系统时,尤其是大并发情况下,经常会遇到一些“疑难杂症”。本文总结了一些使用缓存时常见的问题及解决方案,以后在遇到这类问题时可以作为参考,在设计缓存系统的时候也应该考虑这些常见的情况。

    为了表述方便,本文以数据库查询缓存为例,使用缓存可以减小对数据库的压力。

     

    缓存穿透

    我们在使用缓存时,往往先尝试去缓存中取值,如果没有,再去数据库取值,如果数据库也没有值,则根据业务需求,返回空或者抛异常。

    如果用户一直访问一个数据库不存在的数据,比如id为-1的数据,就会导致每次请求都会先去缓存查一次,然后再去数据库查一次,造成严重的性能问题。这种情况就叫缓存穿透。

    解决方案

    以下几种解决方案:

    • 对请求参数做校验,比如用户鉴权校验,id做基础校验,id <= 0的直接拦截。

    • 如果查询到数据库没有值,也将对应的key存进缓存中,value为null。这样下次查询就直接从缓存返回了。但这里的key的缓存时间应该比较短,比如30s。防止后面在数据库插入了这条数据,而用户获取不到。

    • 使用布隆过滤器,判断一个key是否已经查过了,如果已经查过了,就不去数据库查询。

     

    缓存击穿

    缓存击穿指的是,一个key的访问量非常大,比如某秒杀活动,有1w/s的并发量。这个key在某一时刻过期,那这些大量的请求就会一瞬间到数据库,数据库可能会直接崩溃。

    解决方案

    缓存击穿的解决方案也有几种,可以配合使用:

    • 对于热点数据,慎重考虑过期时间,确保热点期间key不会过期,甚至有些可以设置永不过期。

    • 使用互斥锁(比如Java的多线程锁机制),第一个线程访问key的时候就锁住,等查询数据库返回后,把值插入到缓存后再释放锁,这样后面的请求就可以直接取缓存里面的数据了。

     

    缓存雪崩

    缓存雪崩指的是,在某一时刻,多个key失效。这样就会有大量的请求从缓存中获取不到值,全部到数据库。还有另一种情况,就是缓存服务器宕机,也算做缓存雪崩。

    解决方案

    针对上述两种情况,缓存雪崩有两种解决方案:

    • 对每个key的过期时间设置一个随机值,而不是所有key都相同。

    • 使用高可用的分布式缓存集群,确保缓存的高可用性,比如redis-cluster。

     

    双写不一致

    在使用数据库缓存的时候,读和写的流程往往是这样的:

    • 读取的时候,先读取缓存,如果缓存中没有,就直接从数据库中读取,然后取出数据后放入缓存

    • 更新的时候,先删除缓存,再更新数据库

    所谓双写不一致,就是在发生写操作(更新)的时候或写操作之后,可能会存在数据库里面的值和缓存中的值不同的情况。

    为什么更新的时候要先删除缓存,再更新数据库?因为如果先更新数据库,然后在删除缓存的时候失败了,就会造成缓存里面的值和数据库的值不一致。

    然而这样并不能完全避免双写不一致问题。假设在大并发情景下,一个线程先删除缓存,然后取更新数据库,这个时候另一个线程去取缓存,发现没有值,于是去读数据库,然后把数据库旧的值设置进缓存。等第一个线程更新完数据库后,数据库里面就是新的值,而缓存里面是旧的值,所以就存在了数据不一致的问题。

    一个比较简单的解决办法是把过期时间设置得比较低,这样就只有在缓存没过期之前存在数据不一致问题,在一些业务场景下也还能接受。

    另一种解决方案是使用队列辅助。先更新数据库,再删除缓存。如果删除失败,就放进队列。然后另一个任务从队列中取出消息,不断去重试删除相应的key。

    还有一种解决方案是使用对一个数据使用一个队列,使读写操作串行化。比如对id为n的数据建立一个队列。对这条数据的写操作,删除缓存后,放进一个队列;然后另一个线程过来了,发现没有缓存,则把这个读操作也放进这个队列里面。

    欢迎大家关注我的公种浩【程序员追风】,文章都会在里面更新,整理的资料也会放在里面。

    不过这样会增加程序的复杂性,串行化也会降低程序的吞吐量,可能得不偿失。一般主流的解决方案还是先删除缓存,再更新数据库。可以满足绝大部分需求。

     

    最后

    欢迎大家一起交流,喜欢文章记得点个赞哟,感谢支持!

    展开全文
  • 1.redis线程模型是什么?为什么单线程redis比多线程memcached效率要高得多(为什么redis是单线程但是还可以支撑高并发)? [redis线程模型] redisserver端会有server socket来接收客户端请求,当准备...
  • 上述方案也存在风险。如果淘汰缓存成功,写数据库失败,会导致后来请求会直接查询数据库。  也可以引入MQ来处理一致性 转载于:https://www.cnblogs.com/albert1024/p/9242656.html...
  • 方法一:key值不存在也保存在缓存中,设置短过期时间,缓解db压力。 方法二:布隆过滤器,即对一定不存在key进行过滤。把所有可能key值放到bitmap中,查询时根据bitmap过滤。 redis缓存雪崩 简介...
  • 缓存常见问题

    千次阅读 2018-11-04 20:34:08
    接下来直接讲常见的缓存问题。 缓存击穿 概念:对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据 原因:缓存在某个时间点过期的时候,恰好在这个时间点对这...
  • 缓存常见的分类有:前端缓存、网络传输缓存、服务端缓存和数据库缓存等。...不合理的缓存失效策略 缓存失效策略如果设置不合理,比如设置了大量缓存在同一时间点失效,那么将导致大量缓存数据在同一时刻发生...
  • 常见分布式缓存问题

    2018-03-19 10:16:00
    缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,084
精华内容 1,633
关键字:

常见的缓存问题