K:缓存相关问题
缓存的作用在于提高程序的响应速度,一般用于程序存储运算所需数据或程序运算后的结果,以便再次访问或运算相同的程序(数据同样相同)时,能够得到快速的响应(适用于读多写少的场景)。在现代计算机体系结构中,根据多级存储体系的思想,为解决cpu运算速度与主存读取数据之间的速度不匹配问题,在cpu与主存之间便添加了多级缓存,用于存储部分经常使用到的数据,以此来提高响应速度。对于大容量存储设备—硬盘(磁盘)而言,主存同样可以看成是该设备的缓存。
在一个大型分布式系统中,为减轻数据库的压力,一般而言都会有一个专门的内存空间用于当做数据库部分热点数据的缓存。对于增加了缓存的程序,获取数据的流程一般而言按这样的逻辑进行的:
访问缓存,当缓存中存在所需数据时,直接返回数据,流程结束。否则进行步骤2
访问数据库,获取相应的数据进行运算并返回,同时将数据(数据库中拿出的数据或者运算后的结果)存入缓存中,流程结束
这两个步骤在不考虑高并发和缓存失效(数据过期/删除了缓存数据)的情况,是没有多大问题的。但是当考虑进这两个情况,缓存中没有相应数据时,便会出现缓存击穿和缓存穿透以及缓存雪崩的问题,下面便就这几个问题分别进行讨论,同时给出解决方法。
缓存穿透:
缓存穿透是指缓存和数据库中都没有相应的数据,而大量用户对不存在的数据进行请求访问,而导致所有请求都访问了数据库,让缓存“形若于无”的情况。
该问题会出现在用户删除了数据库中的相关数据后,删除缓存的场景中。也会出现在用户对系统的恶意请求中。
解决办法:
请求校验;在请求访问数据库之前,先校验请求参数的合法性。避免了非法参数访问数据库的情况(因为非法参数,如id=-1在数据库中是不存在的,为此每次请求都会导致访问数据库)
缓存空值;当访问了数据库中不存在的数据时,可以在缓存中设置对应数据为空值,这样后续访问该数据的请求就会被缓存所拦截而直接返回空值,从而减少对数据库的访问量。但需要注意的是,缓存时间应该设置得短一些,避免新增了数据之后,依然查询不到值的情况
缓存击穿:
缓存击穿是指缓存中没有相应的数据,数据库却中存在相应的数据。大量用户对该数据的请求直接访问了数据库造成的一种现象。
该问题会出现于更新了数据库中的数据之后去删除缓存的数据的场景中。也会出现于首次使用缓存,缓存中没有相关数据的场景中。同时也会出现在某个数据在缓存中失效过期的情况中。
解决方法:
缓存预热;在缓存启动时,可以对热点数据进行预加载处理。
加锁,重试;其中一个线程获取锁去访问数据库并将数据放置于缓存行中,另一些线程等待一段时间之后再重试获取缓存中的数据,当不存在时,再度竞争锁。
热点数据永不过时;不对热点数据设置过期时间,等到更新数据的时候,且下一次查询的时候,再更新数据。
缓存雪崩:
缓存雪崩是指缓存中的大量数据在短时间内失效,导致大量请求直接访问了数据库而导致的一种现象。其可以看成缓存击穿的一种泛化情况,缓存击穿是并发请求同一条失效数据,而缓存雪崩则是不同数据的数据均失效,应用大量请求数据库导致的。
解决方法:
随机延长数据的缓存时长;对缓存中被访问到的数据随机延长一定的失效时间,这样可以避免数据集中的在短时间内失效。
缓存进行分布式部署;对缓存做高可用的分布式部署,避免缓存出现单点故障问题导致缓存不可用而应用大量请求数据库。
限流、降级;当缓存雪崩发生时,为避免大量的请求访问数据库导致系统的不可用,可以采用限流和降级系统的方式,确保系统的可用。
总结:
缓存穿透和缓存击穿这个两个名词有点相近,乍一看不容易辨别,也容易搞混淆,但细细一想其实还是很容易分辨的。缓存穿透和缓存击穿的共同点是缓存中没有相应的数据,而不同点在于缓存穿透在数据库中是没有相应的数据。而对于缓存雪崩,其实际上就是缓存击穿的一种泛化,缓存击穿是针对某一个缓存项失效而言的,而缓存雪崩是针对大量缓存项的。
ps:这篇文章最主要的目的是对上一篇文章中关于缓存使用可能会出现的相关问题的总结。通篇是理论有关的内容,在此仅做个记录。
这个是本人的公众号,致力于写出绝大部分人都能读懂的技术文章。欢迎相互交流,我们博采众长,共同进步。

K:缓存相关问题的更多相关文章
- 《前端之路》之 Cookie && localStorage && Session Storage 缓存相关
08: Cookie && localStorage && Session Storage 缓存相关 客户端.前端 存储 一. 起 因 首先解释下为什么想来写这个关于前 ...
- 浏览器缓存相关http头
近期看雅虎黄金34条,学习下优化站点性能的方法. 当中有一条:"为文件头指定Expires或Cache-Control",详细来说指对于静态内容:设置文件头过期时间Expires的 ...
- SPSS-Friedman 秩和检验-非参数检验-K个相关样本检验 案例解析
三人行,必有我师,是不是真有我师?三种不同类型的营销手段,最终的营销效果是否一样,随即区组秩和检验带你进入分析世界 今天跟大家讨论和分享一下:spss-Friedman 秩和检验-非参数检验-K个(多 ...
- Java缓存相关memcached、redis、guava、Spring Cache的使用
随笔分类 - Java缓存相关 主要记录memcached.redis.guava.Spring Cache的使用 第十二章 redis-cluster搭建(redis-3.2.5) 摘要: redi ...
- Django的contenttypes应用、缓存相关
一.django的contenttypes contenttypes 是Django内置的一个应用 , 可以追踪项目中所有app 和 model 的对应关系, 并记录djang_content_typ ...
- http中有关缓存相关的几个字段
转载自:http://blog.csdn.net/lifeibo/article/details/5979572 Expires.Cache-Control.Last-Modified. ETag是R ...
- MySQL的Innodb缓存相关优化
MySQL的Innodb缓存相关优化 INNODB 状态的部分解释 通过 命令 SHOW STATUS LIKE 'Innodb_buffer_pool_%' 查看 Innodb缓存使用率 (I ...
- contenttype应用 , 缓存相关
一. Django的contenttypes contenttypes 是Django内置的一个应用,可以追踪项目中所有 app和model 的对应关系,并记录在 django_content_typ ...
- 网页缓存相关的HTTP头部信息详解
前言 之前看完了李智慧老师著的<大型网站技术架构-核心原理与案例分析>这本书,书中多次提起浏览器缓存的话题,恰是这几天生产又遇到了一个与缓存的问题,发现自己书是没少看,正经走心的内容却不多 ...
随机推荐
- Android中的路径记录
Android中的路径记录 | RobinBlog 导航 导航 博客 分类 标签 友链 关于 搜索 Environment.getDataDirectory().getPath()=/dataEnvi ...
- 【原创】从零开始搭建Electron+Vue+Webpack项目框架(六)Electron打包,同时构建客户端和web端
导航: (一)Electron跑起来(二)从零搭建Vue全家桶+webpack项目框架(三)Electron+Vue+Webpack,联合调试整个项目(四)Electron配置润色(五)预加载及自动更 ...
- C# InputStream获取后乱码处理
Post推送过来的数据流获取后部分中文出现乱码,晚上找了好多办法,不如朋友鼎力相助,哈哈哈~不说废话了上代码把 旧代码基本是网上普遍写法,字段不长用起来不会有乱码情况,但是传送字段一旦过长,超过byt ...
- 国产数据库适配publiccms开源项目
金仓数据库适配 操作说明: 一.在程序的所有实体层添加schema=”public”(这里的public是根据数据库定义的模式) 二.切换数据库,修改配置文件cms.properties里面的cms. ...
- C/C++ 手动开O2
手动O2比赛不能用,平时玩玩就好 #pragma GCC optimize (2) #pragma G++ optimize (2)
- ES6的编程风格
1,建议使用let替代var 2,全局常量使用const,多使用const有利于提高程序的运行效率. const有两个好处:一是阅读代码的人立刻会意识到不应该修改这个值,二是防止无意间修改变量值导致错 ...
- 对javaweb项目中web.xml重用配置的理解(个人学习小结)
<!-- 所有的总结描述性与语言都在注释中 --><?xml version="1.0" encoding="UTF-8"?> < ...
- 「从零单排HBase 06」你必须知道的HBase最佳实践
前面,我们已经打下了很多关于HBase的理论基础,今天,我们主要聊聊在实际开发使用HBase中,需要关注的一些最佳实践经验. 1.Schema设计七大原则 1)每个region的大小应该控制在10G到 ...
- mybatis进阶案例之多表查询
mybatis进阶案例之多表查询 一.mybatis中表之间的关系 在数据库中,实体型之间的关系主要有如下几种: 1.一对一 如果对于实体集A中的每一个实体,实体集B中至多有一个(也可以没有)实体与之 ...
- Linux系统是什么?亲身自学经历分享
我是数字媒体专业学生,第一次接触LINUX的时候,是大一C语言课程里看到的,书上讲了C语言的发展历史.说到C语言的起源,就离不开UNIX系统.在20世纪60年代,贝尔实验室的研究员Ken Thomps ...