缓存常见问题及解决方案
【大咖・来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》
使用缓存可以缓解大流量压力,显著提高程序的性能。我们在使用缓存系统时,尤其是大并发情况下,经常会遇到一些“疑难杂症”。本文总结了一些使用缓存时常见的问题及解决方案,以后在遇到这类问题时可以作为参考,在设计缓存系统的时候也应该考虑这些常见的情况。
为了表述方便,本文以数据库查询缓存为例,使用缓存可以减小对数据库的压力。
缓存穿透
我们在使用缓存时,往往先尝试去缓存中取值,如果没有,再去数据库取值,如果数据库也没有值,则根据业务需求,返回空或者抛异常。
如果用户一直访问一个数据库不存在的数据,比如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的数据建立一个队列。对这条数据的写操作,删除缓存后,放进一个队列;然后另一个线程过来了,发现没有缓存,则把这个读操作也放进这个队列里面。
不过这样会增加程序的复杂性,串行化也会降低程序的吞吐量,可能得不偿失。一般主流的解决方案还是先删除缓存,再更新数据库。可以满足绝大部分需求。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
中国自研数据库打破西方垄断
【大咖・来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》 中国基础技术,再破外国垄断。 而且新近提交成绩,大幅刷新之前纪录,斩获全球第一。 荣誉属于阿里巴巴,属于蚂蚁金服。 十一期间,权威机构国际事务处理性能委员会(TPC)官网披露,阿里巴巴自主研发的金融级分布式关系数据库OceanBase,在TPC-C基准测试中登上榜首。 这一成绩还打破了由美国公司甲骨文(Oracle)保持了9年之久的世界记录,成为首个登顶该榜单的中国数据库产品。 中国工程院院士、计算机专家李国杰盛赞说:“这是中国基础软件取得的重大突破。” TPC-C基准测试,被誉为“数据库领域世界杯”,是全球公认的数据库性能评价金指标,美国公司Oracle(甲骨文)已经垄断了9年冠军。 而此次登顶的OceanBase,完全由阿里巴巴和蚂蚁金服自主研发,是全球首个应用于金融核心业务的分布式关系数据库。其创造的新的联机交易处理系统(OLTP)世界纪录,是Oracle最好成绩的两倍多。 此前,国内的数据库市场,长期由Oracle、IBM等国外科技公司占据主导地位,不仅导致软件服务费用高昂,而且在许多关键领域还存在信息安全...
- 下一篇
10月数据库排行:Microsoft SQL Server 分数增加最多
【大咖・来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》 DB-Engines 数据库流行度排行榜 10月更新已发布,排名前二十如下: 这期的数据比较有意思,上个月才说完Microsoft SQL Server 分数出现罕见的下滑,并且是下滑最多的一个。到了这个月,Microsoft SQL Server 马上扭转局势,成了分数增长最多的一个,与上个月相比其增加了 9.66 分,比第一名Oracle 增加9.22 分稍胜一筹。当然,整体来看排名和上个月的保持一致。 可以看到,排名前 5 的数据库的分数较上个月都有了一定的增长,尤其是和去年同时期相比,增长更为明显。 有关其他方面的变动,以及完整排名请查看https://db-engines.com/en/ranking。 接下来看一下前十名的趋势变化图: 最后看看每种数据库的排名情况。 关系数据库前 10 名如下: Key-Value 数据库前 10 名如下: 文档数据库前 10 名如下: 图数据库前 10 名如下: 时序数据库前 10 名如下: DB-Engines 根据受欢迎程度对数据库管理系统进行排名,排名每月更新一...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器