redis缓存穿透和雪崩,蔚来三面被刷几率大吗
redis缓存穿透和雪崩,蔚来三面被刷几率大吗详细介绍
本文目录一览: redis缓存机制一般会影响软件的哪些功能?
Redis缓存机制主要作用在于提高数据访问速度、减轻数据库压力、提高系统性能。但是,使用Redis缓存机制可能会影响软件的以下功能:
数据一致性:由于Redis缓存中的数据与数据库中的数据可能存在不一致的情况,这会导致用户在查询数据时看到不一致的结果。
数据过期:缓存数据有过期时间,如果缓存数据过期,需要重新从数据库中获取,这可能会影响查询速度。
数据持久化:Redis提供了RDB和AOF两种持久化策略,但在某些情况下,如意外宕机等,可能会导致缓存数据的丢失。
内存限制:Redis是基于内存的存储系统,当缓存数据量过大时,可能会消耗大量内存资源,影响软件其他功能的性能。
缓存穿透、缓存击穿和缓存雪崩:这些现象可能导致缓存系统承受较大压力,进而影响整个软件的性能和稳定性。
分布式环境:在分布式环境下,需要考虑缓存数据的同步和一致性问题,否则可能会导致软件功能异常。
缓存维护:需要定期对缓存进行维护,如清除无用的缓存数据,避免缓存数据过多影响系统性能。
在使用Redis缓存机制时,需要充分考虑这些可能影响软件功能的因素,并采取相应的措施进行优化。
缓存击穿、穿透、雪崩及Redis分布式锁
分布式锁: setnx ,redisson 并发问题
幂等问题: 落表状态,Redis
缓存击穿: 指缓存中无,db中有
原因: 一个key高并发恰好失效导致大量请求到db
方案: 加锁,自旋锁,或一个线程查db,一个线程监控(直接用Redisson分布式锁)
缓存穿透:指缓存和db中均无
原因: 一般是恶意请求
方案: 加布隆过滤,或查db无时,也设置缓存,value为某些特殊表示或"null"
雪崩:指缓存同时大量失效
原因: 大量的key同时失效,db压力加大
方案: 设置失效时间是增加随机数
问题方案文献:
https://www.jianshu.com/p/31ab9b020cd9 (图例分析)
https://blog.csdn.net/fcvtb/article/details/89478554
Redis分布式锁:
事务未执行完锁已到期释放问题:使用Redissoin解决续租问题,内部已解决
分布式锁文献:
https://www.jianshu.com/p/4838f8be00c9
https://blog.csdn.net/qq_30038111/article/details/90696233 (setnx + expire同时操作)
====================================
https://www.runoob.com/redis/keys-scan.html
https://www.jianshu.com/p/611a492d9121 Redis原理与应用
redis使用要注意什么
redis使用要注意的问题主要如下:redis和数据库双写一致性问题(推荐学习:Redis视频教程)分析:一致性问题是分布式常见问题,还可以再分为最终一致性和强一致性。数据库和缓存双写,就必然会存在不一致的问题。答这个问题,先明白一个前提。就是如果对数据有强一致性要求,不能放缓存。我们所做的一切,只能保证最终一致性。另外,我们所做的方案其实从根本上来说,只能说降低不一致发生的概率,无法完全避免。因此,有强一致性要求的数据,不能放缓存。 ----------分析:一致性问题是分布式常见问题,还可以再分为最终一致性和强一致性。数据库和缓存双写,就必然会存在不一致的问题。答这个问题,先明白一个前提。就是如果对数据有强一致性要求,不能放缓存。我们所做的一切,只能保证最终一致性。另外,我们所做的方案其实从根本上来说,只能说降低不一致发生的概率,无法完全避免。因此,有强一致性要求的数据,不能放缓存。首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。如何应对缓存穿透和缓存雪崩问题分析:这两个问题,说句实在话,一般中小型传统软件企业,很难碰到这个问题。如果有大并发的项目,流量有几百万左右。这两个问题一定要深刻考虑。回答:如下所示缓存穿透,即黑客故意去请求缓存中不存在的数据,导致所有的请求都怼到数据库上,从而数据库连接异常。解决方案:(一)利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试(二)采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。(三)提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。缓存雪崩,即缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常。解决方案:(一)给缓存的失效时间,加上一个随机值,避免集体失效。(二)使用互斥锁,但是该方案吞吐量明显下降了。(三)双缓存。我们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。自己做缓存预热操作。然后细分以下几个小点I 从缓存A读数据库,有则直接返回II A没有数据,直接从B读数据,直接返回,并且异步启动一个更新线程。III 更新线程同时更新缓存A和缓存B。如何解决redis的并发竞争key问题分析:这个问题大致就是,同时有多个子系统去set一个key。这个时候要注意什么呢?大家思考过么。需要说明一下,博主提前百度了一下,发现答案基本都是推荐用redis事务机制。博主不推荐使用redis的事务机制。因为我们的生产环境,基本都是redis集群环境,做了数据分片操作。你一个事务中有涉及到多个key操作的时候,这多个key不一定都存储在同一个redis-server上。因此,redis的事务机制,十分鸡肋。回答:如下所示(1)如果对这个key操作,不要求顺序这种情况下,准备一个分布式锁,大家去抢锁,抢到锁就做set操作即可,比较简单。(2)如果对这个key操作,要求顺序假设有一个key1,系统A需要将key1设置为valueA,系统B需要将key1设置为valueB,系统C需要将key1设置为valueC.期望按照key1的value值按照 valueA_>valueB_>valueC的顺序变化。这种时候我们在数据写入数据库的时候,需要保存一个时间戳。假设时间戳如下系统A key 1 {valueA 3:00}系统B key 1 {valueB 3:05}系统C key 1 {valueC 3:10}那么,假设这会系统B先抢到锁,将key1设置为{valueB 3:05}。接下来系统A抢到锁,发现自己的valueA的时间戳早于缓存中的时间戳,那就不做set操作了。以此类推。更多Redis相关技术文章,请访问Redis数据库使用入门教程栏目进行学习!
redis常见问题
1. 缓存击穿
缓存击穿是指一个请求要访问的数据,缓存中没有,但数据库中有的情况。这种情况一般都是缓存过期了。
但是这时由于并发访问这个缓存的用户特别多,这是一个热点 key,这么多用户的请求同时过来,在缓存里面没有取到数据,所以又同时去访问数据库取数据,引起数据库流量激增,压力瞬间增大,直接崩溃给你看。
所以一个数据有缓存,每次请求都从缓存中快速的返回了数据,但是某个时间点缓存失效了,某个请求在缓存中没有请求到数据,这时候我们就说这个请求就"击穿"了缓存。
针对这个场景,对应的解决方案一般来说有三种。
借助Redis setNX命令设置一个标志位就行。设置成功的放行,设置失败的就轮询等待。就是在更新缓存时加把锁
后台开一个定时任务,专门主动更新过期数据
比如程序中设置 why 这个热点 key 的时候,同时设置了过期时间为 10 分钟,那后台程序在第 8 分钟的时候,会去数据库查询数据并重新放到缓存中,同时再次设置缓存为 10 分钟。
其实上面的后台续命思想的最终体现是也是永不过期。
只是后台续命的思想,会主动更新缓存,适用于缓存会变的场景。会出现缓存不一致的情况,取决于你的业务场景能接受多长时间的缓存不一致。
2. 缓存穿透
缓存穿透是指一个请求要访问的数据,缓存和数据库中都没有,而用户短时间、高密度的发起这样的请求,每次都打到数据库服务上,给数据库造成了压力。一般来说这样的请求属于恶意请求。
解决方案有两种:
就是在数据库即使没有查询到数据,我们也把这次请求当做 key 缓存起来,value 可以是 NULL。下次同样请求就会命中这个 NULL,缓存层就处理了这个请求,不会对数据库产生压力。这样实现起来简单,开发成本很低。
3. 缓存雪崩
缓存雪崩是指缓存中大多数的数据在同一时间到达过期时间,而查询数据量巨大,这时候,又是缓存中没有,数据库中有的情况了。
防止雪崩的方案简单来说就是错峰过期。
在设置 key 过期时间的时候,在加上一个短的随机过期时间,这样就能避免大量缓存在同一时间过期,引起的缓存雪崩。
如果发了雪崩,我们可以有服务降级、熔断、限流手段来拒绝一些请求,保证服务的正常。但是,这些对用户体验是有一定影响的。
4. Redis 高可用架构
Redis 高可用架构,大家基本上都能想到主从、哨兵、集群这三种模式。
哨兵模式:
它主要执行三种类型的任务:
哨兵其实也是一个分布式系统,我们可以运行多个哨兵。
然后这些哨兵之间需要相互通气,交流信息,通过投票来决定是否执行自动故障迁移,以及选择哪个从服务器作为新的主服务器。
哨兵之间采用的协议是 gossip,是一种去中心化的协议,达成的是最终一致性。
选举规则:
该怎么解决 Redis 缓存穿透和缓存雪崩问题?
缓存雪崩: 由于缓存层承载着大量请求,有效地 保护了存储层,但是如果缓存层由于某些原因不能提供服务,比如 Redis 节点挂掉了,热点 key 全部失效了,在这些情况下,所有的请求都会直接请求到数据库,可能会造成数据库宕机的情况。
预防和解决缓存雪崩问题,可以从以下三个方面进行着手:
1、使用 Redis 高可用架构:使用 Redis 集群来保证 Redis 服务不会挂掉
2、缓存时间不一致: 给缓存的失效时间,加上一个随机值,避免集体失效
3、限流降级策略:有一定的备案,比如个性推荐服务不可用了,换成热点数据推荐服务
缓存穿透: 缓存穿透是指查询一个根本不存在的数据,这样的数据肯定不在缓存中,这会导致请求全部落到数据库上,有可能出现数据库宕机的情况。
预防和解决缓存穿透问题,可以考虑以下两种方法:
1、缓存空对象: 将空值缓存起来,但是这样就有一个问题,大量无效的空值将占用空间,非常浪费。
2、布隆过滤器拦截: 将所有可能的查询key 先映射到布隆过滤器中,查询时先判断key是否存在布隆过滤器中,存在才继续向下执行,如果不存在,则直接返回。布隆过滤器有一定的误判,所以需要你的业务允许一定的容错性。
你们都是怎么确保系统不被突然的访问流量压垮的?
确保系统的高可用,要做的事情非常多,比如使用Redis缓存数据库的数据,降低数据库的压力,同时也要注意缓存穿透、雪崩、击穿等问题;但要是说到“不要被突增的访问量击垮”,通常就会到我们常说的分布式架构三板斧:限流、熔断、降级。
01.限流
限流理解起来很简单,比如故宫每天只卖八万张票,超过八万的游客,无法买票进入,因为如果超过八万人,景点的工作人员可能就忙不过来,过于拥挤的景点也会影响游客的体验和心情,并且还会有安全隐患;只卖N张票,这就是一种限流的手段。
软件架构中的限流也一样,就是流量徒增的时候,只允许一部分流量进来,而多余的那部分,就拒绝掉。
通常我们可以通过限流算法达到这样的效果,比如计数器法、滑动窗口法、漏桶算法、令牌桶算法,每个算法的详解之前的文章有介绍过,这里就不在占用篇幅了。上面的例子中,故宫每天只卖八万张票,有点儿类似于令牌桶算法,票就相当于令牌,只有拿到令牌的请求,才能访问到服务。
另外限流可以针对不同的系统或业务流程限流,比如核心系统A要做限流,B系统调用A系统很重要,C系统调用A系统相对来说不是那么重要,所以当A系统有些扛不住的时候,可以限制C系统的调用次数,保证B系统的稳定运行。
02.熔断
现实生活中,保险丝的作用就是熔断,可以在发生短路的时候自动跳闸,保护家电。
在我们大部分应用场景中,A系统调B系统接口,B系统再调C系统接口这样的场景非常多,这就是调用链路:A->B->C->D;每个系统的承载上限肯定是不一样的,比如流量徒增,D系统达到承载上限了,D系统的接口响应非常慢,这样可能会导致A/B/C调用它时出现超时等待的情况;如果进一步恶化,会导致链路雪崩,从一个服务的故障,变成了多个系统的故障。
这时候熔断就排上用场了,如果短时间内有大量的请求超时,那么就意味着这个系统出现了故障,那么就没有必要再去访问这个服务了,这时候就要使用熔断,断开这条链路。
熔断器还可以自动诊断下游服务的状态,如果服务恢复的话,那么再慢慢释放请求,直到故障发生前的状态。
03.降级
服务降级既可以通过代码自动判断,比如上文的服务限流中说到,当流量徒增,可以限制不重要的系统或服务的访问量,这里的谁重要谁不重要,就算是服务级别的区分,当访问量徒增,哪些系统是可以自动降级的。
服务降级也可以人工根据突发情况切换;比如在某些服务节点的时候(例如双11,618),为了保证购物和支付的正常运行,会禁用一些不重要的服务;甚至在购物和支付两者之间,购物更重要,所以可以提前预付或者延迟支付。
总之,限流、熔点和降级都是在流量徒增、过大时,保证系统稳定的手段。
我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。
12 个问题搞懂 Redis
都说学习需要带着问题,带着思考进行学习,下面就以问题的形式来学习下 Redis 。
1、什么是 Redis ?
2、都说 Redis 是单线程模型,到底是什么意思?
3、为什么在数据读写处理上不使用多线程?
4、为什么使用单线程,速度却很快?
5、单线程处理的瓶颈是什么?
6、Redis 6.0 调整为多线程的原因?
7、在 Redis 中怎样做持久化?
8、常说的缓存雪崩、击穿、穿透是什么?
9、怎样解决雪崩、击穿、穿透带来的问题?
10、怎样设计缓存的淘汰机制?
11、怎样保证缓存和数据库的数据一致?
12、Redis 有什么使用规范?
Redis 的知识远不止如此,本文总结了一些我认为比较重要的一些点,希望对您有所帮助!
五分钟系列之Redis大规模数据存储简述
互联网场景下面临的主要技术问题之一是高并发大数据量。为了提高性能保护数据库通常会在数据库之上加一层缓存。目前常用的缓存是Redis,那么Redis如何存储大规模数据?如何将数据库的数据同步到Redis?Redis缓存设计要注意哪些问题?
Redis大规模数据存储通过集群实现。目前常见的集群方式有三种方案。
第一种使用Redis自带的集群技术Redis cluster。
第二种是使用代理方式,在客户端与Redis节点之间加一层代理服务目前开源的实现有codis和twemproxy。
第三种是定制客户端实现,在客户端实现节点的寻址功能。
数据库数据同步到缓存目前常见的方式有四种方式。
方式一在业务应用服务中实现。在修改数据库的同时更新缓存。
方式二通过消息队列异步更新。在业务中更新数据后发送消息,消息消费者订阅消息对缓存进行更新。
方式三通过定时任务更新。通过定时任务监控数据变更,同步更新数据到缓存。
方式三通过数据库Binlog更新。通过一些开源中间间如canal订阅数据库日志更新,解析日志然后对解析后的日志执行缓存更新操作。
缓存设计需要注意下面四个问题。
数据一致性问题。
数据库和缓存数据保持一致。目前常见的四种缓存更新模式。cache aside、read through 、write through、write behind caching。
缓存穿透问题。
目前解决缓存击穿的思路主要是过滤无效请求。如通过键的规则校验过滤恶意请求,布隆过滤器过滤无效请求。其次是缓存空结果。
缓存击穿问题。
目前解决缓存击穿的思路是对请求加全局锁,还有就是对即将过期的数据进行主动刷新。
缓存雪崩问题。
缓存雪崩目前常见的思路是设置缓存过期时间时随机设置失效时间避免缓存同时失效。还有缓存存储时划分更小的缓存区间按区间设置缓存失效时间。
缓存的使用是一个整体方案分层分布式设计。上述只是整体性描述,实际过程中的细节很多也很复杂。
蔚来三面被刷几率大吗
蔚来三面被刷几率大。一面:问了一些基础的八股文,比如springcloud的生态用到了有哪些,注册中心调用的原理、限流器的原理。平时有没有用到AQS相关,底层怎么去实现的。redis缓存穿透、击穿、雪崩。mysql事物相关问题。
redis分布式怎么做
一 为什么使用 Redis在项目中使用 Redis,主要考虑两个角度:性能和并发。如果只是为了分布式锁这些其他功能,还有其他中间件 Zookpeer 等代替,并非一定要使用 Redis。性能:如下图所示,我们在碰到需要执行耗时特别久,且结果不频繁变动的 SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。特别是在秒杀系统,在同一时间,几乎所有人都在点,都在下单。。执行的是同一操作———向数据库查数据。根据交互效果的不同,响应时间没有固定标准。在理想状态下,我们的页面跳转需要在瞬间解决,对于页内操作则需要在刹那间解决。 并发:如下图所示,在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用 Redis 做一个缓冲操作,让请求先访问到 Redis,而不是直接访问数据库。使用 Redis 的常见问题缓存和数据库双写一致性问题缓存雪崩问题缓存击穿问题缓存的并发竞争问题二 单线程的 Redis 为什么这么快这个问题是对 Redis 内部机制的一个考察。很多人都不知道 Redis 是单线程工作模型。原因主要是以下三点:纯内存操作单线程操作,避免了频繁的上下文切换采用了非阻塞 I/O 多路复用机制仔细说一说 I/O 多路复用机制,打一个比方:小名在 A 城开了一家快餐店店,负责同城快餐服务。小明因为资金限制,雇佣了一批配送员,然后小曲发现资金不够了,只够买一辆车送快递。经营方式一客户每下一份订单,小明就让一个配送员盯着,然后让人开车去送。慢慢的小曲就发现了这种经营方式存在下述问题:时间都花在了抢车上了,大部分配送员都处在闲置状态,抢到车才能去送。随着下单的增多,配送员也越来越多,小明发现快递店里越来越挤,没办法雇佣新的配送员了。配送员之间的协调很花时间。综合上述缺点,小明痛定思痛,提出了经营方式二。经营方式二小明只雇佣一个配送员。当客户下单,小明按送达地点标注好,依次放在一个地方。最后,让配送员依次开着车去送,送好了就回来拿下一个。上述两种经营方式对比,很明显第二种效率更高。在上述比喻中:每个配送员→每个线程每个订单→每个 Socket(I/O 流)订单的送达地点→Socket 的不同状态客户送餐请求→来自客户端的请求明曲的经营方式→服务端运行的代码一辆车→CPU 的核数于是有了如下结论:经营方式一就是传统的并发模型,每个 I/O 流(订单)都有一个新的线程(配送员)管理。经营方式二就是 I/O 多路复用。只有单个线程(一个配送员),通过跟踪每个 I/O 流的状态(每个配送员的送达地点),来管理多个 I/O 流。下面类比到真实的 Redis 线程模型,如图所示:Redis-client 在操作的时候,会产生具有不同事件类型的 Socket。在服务端,有一段 I/O 多路复用程序,将其置入队列之中。然后,文件事件分派器,依次去队列中取,转发到不同的事件处理器中。三 Redis 的数据类型及使用场景一个合格的程序员,这五种类型都会用到。String最常规的 set/get 操作,Value 可以是 String 也可以是数字。一般做一些复杂的计数功能的缓存。Hash这里 Value 存放的是结构化的对象,比较方便的就是操作其中的某个字段。我在做单点登录的时候,就是用这种数据结构存储用户信息,以 CookieId 作为 Key,设置 30 分钟为缓存过期时间,能很好的模拟出类似 Session 的效果。List使用 List 的数据结构,可以做简单的消息队列的功能。另外,可以利用 lrange 命令,做基于 Redis 的分页功能,性能极佳,用户体验好。Set因为 Set 堆放的是一堆不重复值的集合。所以可以做全局去重的功能。我们的系统一般都是集群部署,使用 JVM 自带的 Set 比较麻烦。另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。Sorted SetSorted Set 多了一个权重参数 Score,集合中的元素能够按 Score 进行排列。可以做排行榜应用,取 TOP N 操作。Sorted Set 可以用来做延时任务。四 Redis 的过期策略和内存淘汰机制Redis 是否用到家,从这就能看出来。比如你 Redis 只能存 5G 数据,可是你写了 10G,那会删 5G 的数据。怎么删的,这个问题思考过么?正解:Redis 采用的是定期删除+惰性删除策略。为什么不用定时删除策略定时删除,用一个定时器来负责监视 Key,过期则自动删除。虽然内存及时释放,但是十分消耗 CPU 资源。在大并发请求下,CPU 要将时间应用在处理请求,而不是删除 Key,因此没有采用这一策略。定期删除+惰性删除如何工作定期删除,Redis 默认每个 100ms 检查,有过期 Key 则删除。需要说明的是,Redis 不是每个 100ms 将所有的 Key 检查一次,而是随机抽取进行检查。如果只采用定期删除策略,会导致很多 Key 到时间没有删除。于是,惰性删除派上用场。采用定期删除+惰性删除就没其他问题了么不是的,如果定期删除没删除掉 Key。并且你也没及时去请求 Key,也就是说惰性删除也没生效。这样,Redis 的内存会越来越高。那么就应该采用内存淘汰机制。在 redis.conf 中有一行配置:# maxmemory-policy volatile-lru该配置就是配内存淘汰策略的:noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 Key。(推荐使用,目前项目在用这种)(最近最久使用算法)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 Key。(应该也没人用吧,你不删最少使用 Key,去随机删)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 Key。这种情况一般是把 Redis 既当缓存,又做持久化存储的时候才用。(不推荐)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 Key。(依然不推荐)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 Key 优先移除。(不推荐)五 Redis 和数据库双写一致性问题一致性问题还可以再分为最终一致性和强一致性。数据库和缓存双写,就必然会存在不一致的问题。前提是如果对数据有强一致性要求,不能放缓存。我们所做的一切,只能保证最终一致性。另外,我们所做的方案从根本上来说,只能降低不一致发生的概率。因此,有强一致性要求的数据,不能放缓存。首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。六 如何应对缓存穿透和缓存雪崩问题这两个问题,一般中小型传统软件企业很难碰到。如果有大并发的项目,流量有几百万左右,这两个问题一定要深刻考虑。缓存穿透,即黑客故意去请求缓存中不存在的数据,导致所有的请求都怼到数据库上,从而数据库连接异常。缓存穿透解决方案:利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试。采用异步更新策略,无论 Key 是否取到值,都直接返回。Value 值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的 Key。迅速判断出,请求所携带的 Key 是否合法有效。如果不合法,则直接返回。缓存雪崩,即缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常。缓存雪崩解决方案:给缓存的失效时间,加上一个随机值,避免集体失效。使用互斥锁,但是该方案吞吐量明显下降了。双缓存。我们有两个缓存,缓存 A 和缓存 B。缓存 A 的失效时间为 20 分钟,缓存 B 不设失效时间。自己做缓存预热操作。然后细分以下几个小点:从缓存 A 读数据库,有则直接返回;A 没有数据,直接从 B 读数据,直接返回,并且异步启动一个更新线程,更新线程同时更新缓存 A 和缓存 B。八 如何解决 Redis 的并发竞争 Key 问题这个问题大致就是,同时有多个子系统去 Set 一个 Key。这个时候要注意什么呢?大家基本都是推荐用 Redis 事务机制。但是并不推荐使用 Redis 的事务机制。因为我们的生产环境,基本都是 Redis 集群环境,做了数据分片操作。你一个事务中有涉及到多个 Key 操作的时候,这多个 Key 不一定都存储在同一个 redis-server 上。因此,Redis 的事务机制,十分鸡肋。如果对这个 Key 操作,不要求顺序这种情况下,准备一个分布式锁,大家去抢锁,抢到锁就做 set 操作即可,比较简单。如果对这个 Key 操作,要求顺序假设有一个 key1,系统 A 需要将 key1 设置为 valueA,系统 B 需要将 key1 设置为 valueB,系统 C 需要将 key1 设置为 valueC。期望按照 key1 的 value 值按照 valueA > valueB > valueC 的顺序变化。这种时候我们在数据写入数据库的时候,需要保存一个时间戳。假设时间戳如下:系统 A key 1 {valueA 3:00}系统 B key 1 {valueB 3:05}系统 C key 1 {valueC 3:10}那么,假设系统 B 先抢到锁,将 key1 设置为{valueB 3:05}。接下来系统 A 抢到锁,发现自己的 valueA 的时间戳早于缓存中的时间戳,那就不做 set 操作了,以此类推。其他方法,比如利用队列,将 set 方法变成串行访问也可以。更多Redis相关技术文章,请访问Redis教程栏目进行学习!