缓存的作用在于提高程序的响应速度,一般用于程序存储运算所需数据或程序运算后的结果,以便再次访问或运算相同的程序(数据同样相同)时,能够得到快速的响应(适用于读多写少的场景)。在现代计算机体系结构中,根据多级存储体系的思想,为解决cpu运算速度与主存读取数据之间的速度不匹配问题,在cpu与主存之间便添加了多级缓存,用于存储部分经常使用到的数据,以此来提高响应速度。对于大容量存储设备—硬盘(磁盘)而言,主存同样可以看成是该设备的缓存。

在一个大型分布式系统中,为减轻数据库的压力,一般而言都会有一个专门的内存空间用于当做数据库部分热点数据的缓存。对于增加了缓存的程序,获取数据的流程一般而言按这样的逻辑进行的:

  1. 访问缓存,当缓存中存在所需数据时,直接返回数据,流程结束。否则进行步骤2

  2. 访问数据库,获取相应的数据进行运算并返回,同时将数据(数据库中拿出的数据或者运算后的结果)存入缓存中,流程结束

这两个步骤在不考虑高并发和缓存失效(数据过期/删除了缓存数据)的情况,是没有多大问题的。但是当考虑进这两个情况,缓存中没有相应数据时,便会出现缓存击穿和缓存穿透以及缓存雪崩的问题,下面便就这几个问题分别进行讨论,同时给出解决方法。

缓存穿透:

缓存穿透是指缓存和数据库中都没有相应的数据,而大量用户对不存在的数据进行请求访问,而导致所有请求都访问了数据库,让缓存“形若于无”的情况。

该问题会出现在用户删除了数据库中的相关数据后,删除缓存的场景中。也会出现在用户对系统的恶意请求中。

解决办法:

  1. 请求校验;在请求访问数据库之前,先校验请求参数的合法性。避免了非法参数访问数据库的情况(因为非法参数,如id=-1在数据库中是不存在的,为此每次请求都会导致访问数据库)

  2. 缓存空值;当访问了数据库中不存在的数据时,可以在缓存中设置对应数据为空值,这样后续访问该数据的请求就会被缓存所拦截而直接返回空值,从而减少对数据库的访问量。但需要注意的是,缓存时间应该设置得短一些,避免新增了数据之后,依然查询不到值的情况

缓存击穿:

缓存击穿是指缓存中没有相应的数据,数据库却中存在相应的数据。大量用户对该数据的请求直接访问了数据库造成的一种现象。

该问题会出现于更新了数据库中的数据之后去删除缓存的数据的场景中。也会出现于首次使用缓存,缓存中没有相关数据的场景中。同时也会出现在某个数据在缓存中失效过期的情况中。

解决方法:

  1. 缓存预热;在缓存启动时,可以对热点数据进行预加载处理。

  2. 加锁,重试;其中一个线程获取锁去访问数据库并将数据放置于缓存行中,另一些线程等待一段时间之后再重试获取缓存中的数据,当不存在时,再度竞争锁。

  3. 热点数据永不过时;不对热点数据设置过期时间,等到更新数据的时候,且下一次查询的时候,再更新数据。

缓存雪崩:

缓存雪崩是指缓存中的大量数据在短时间内失效,导致大量请求直接访问了数据库而导致的一种现象。其可以看成缓存击穿的一种泛化情况,缓存击穿是并发请求同一条失效数据,而缓存雪崩则是不同数据的数据均失效,应用大量请求数据库导致的。

解决方法:

  1. 随机延长数据的缓存时长;对缓存中被访问到的数据随机延长一定的失效时间,这样可以避免数据集中的在短时间内失效。

  2. 缓存进行分布式部署;对缓存做高可用的分布式部署,避免缓存出现单点故障问题导致缓存不可用而应用大量请求数据库。

  3. 限流、降级;当缓存雪崩发生时,为避免大量的请求访问数据库导致系统的不可用,可以采用限流和降级系统的方式,确保系统的可用。

总结:

缓存穿透和缓存击穿这个两个名词有点相近,乍一看不容易辨别,也容易搞混淆,但细细一想其实还是很容易分辨的。缓存穿透和缓存击穿的共同点是缓存中没有相应的数据,而不同点在于缓存穿透在数据库中是没有相应的数据。而对于缓存雪崩,其实际上就是缓存击穿的一种泛化,缓存击穿是针对某一个缓存项失效而言的,而缓存雪崩是针对大量缓存项的。

ps:这篇文章最主要的目的是对上一篇文章中关于缓存使用可能会出现的相关问题的总结。通篇是理论有关的内容,在此仅做个记录。


这个是本人的公众号,致力于写出绝大部分人都能读懂的技术文章。欢迎相互交流,我们博采众长,共同进步。

K:缓存相关问题的更多相关文章

  1. 《前端之路》之 Cookie && localStorage && Session Storage 缓存相关

    08: Cookie && localStorage && Session Storage 缓存相关 客户端.前端 存储 一. 起 因 首先解释下为什么想来写这个关于前 ...

  2. 浏览器缓存相关http头

    近期看雅虎黄金34条,学习下优化站点性能的方法. 当中有一条:"为文件头指定Expires或Cache-Control",详细来说指对于静态内容:设置文件头过期时间Expires的 ...

  3. SPSS-Friedman 秩和检验-非参数检验-K个相关样本检验 案例解析

    三人行,必有我师,是不是真有我师?三种不同类型的营销手段,最终的营销效果是否一样,随即区组秩和检验带你进入分析世界 今天跟大家讨论和分享一下:spss-Friedman 秩和检验-非参数检验-K个(多 ...

  4. Java缓存相关memcached、redis、guava、Spring Cache的使用

    随笔分类 - Java缓存相关 主要记录memcached.redis.guava.Spring Cache的使用 第十二章 redis-cluster搭建(redis-3.2.5) 摘要: redi ...

  5. Django的contenttypes应用、缓存相关

    一.django的contenttypes contenttypes 是Django内置的一个应用 , 可以追踪项目中所有app 和 model 的对应关系, 并记录djang_content_typ ...

  6. http中有关缓存相关的几个字段

    转载自:http://blog.csdn.net/lifeibo/article/details/5979572 Expires.Cache-Control.Last-Modified. ETag是R ...

  7. MySQL的Innodb缓存相关优化

    MySQL的Innodb缓存相关优化 INNODB 状态的部分解释 通过 命令 SHOW STATUS LIKE  'Innodb_buffer_pool_%' 查看  Innodb缓存使用率  (I ...

  8. contenttype应用 , 缓存相关

    一. Django的contenttypes contenttypes 是Django内置的一个应用,可以追踪项目中所有 app和model 的对应关系,并记录在 django_content_typ ...

  9. 网页缓存相关的HTTP头部信息详解

    前言 之前看完了李智慧老师著的<大型网站技术架构-核心原理与案例分析>这本书,书中多次提起浏览器缓存的话题,恰是这几天生产又遇到了一个与缓存的问题,发现自己书是没少看,正经走心的内容却不多 ...

随机推荐

  1. ES6学习笔记(三):教你用js面向对象思维来实现 tab栏增删改查功能

    前两篇文章主要介绍了类和对象.类的继承,如果想了解更多理论请查阅<ES6学习笔记(一):轻松搞懂面向对象编程.类和对象>.<ES6学习笔记(二):教你玩转类的继承和类的对象>, ...

  2. C++扬帆远航——9(小学生算数程序)

    /* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:studentjishu.cpp * 作者:常轩 * 微信公众号 ...

  3. 达拉草201771010105《面向对象程序设计(java)》第二周学习总结

    达拉草201771010105<面向对象程序设计(java)>第二周学习总结 一.理论知识学习部分          这一周我们学习的是书上第三章java的基本程序设计结构的内容,在这一章 ...

  4. 47-Python进阶小结

    目录 Python进阶小结 一.异常TODO 二.深浅拷贝 2.1拷贝 2.2 浅拷贝 2.3 深拷贝 三.数据类型内置方法 3.1 数字类型内置方法 3.1.1 整型 3.1.2 浮点型 3.2 字 ...

  5. 天坑,CSS之定位Position(六分之五)

    Position定位 个人觉得position这个属性真的算是CSS的见面杀了.尤其是absolute,当年可是被虐的不轻.当然了,现在爱上了这个属性,谁用谁知道. position属性 positi ...

  6. uWSGI, send_file and Python 3.5

    当你的Flask项目通过Nginx+uWSGI成功部署的时候,当你很高兴你Flask里面的接口成功跑通的时候,你会发现真高兴!好牛逼! 然后当你写了其他几个接口的时候,在启动uWSGI服务的时候,死活 ...

  7. 【django】 接收所有文件,前端展示文件(包括视频,文件,图片)ajax请求

    如果是后台上传文件: setting配置: STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ...

  8. python正则表达式之re模块使用

    python第一个正则表达式 https://www.imooc.com/learn/550 r'imooc'  Pattern Match result In [2]: import re In [ ...

  9. 数据挖掘入门系列教程(二)之分类问题OneR算法

    数据挖掘入门系列教程(二)之分类问题OneR算法 数据挖掘入门系列博客:https://www.cnblogs.com/xiaohuiduan/category/1661541.html 项目地址:G ...

  10. etcdctl的使用

    etcdctl是一个提供简洁命令的etcd客户端,使用etcdctl可以直接和etcd服务打交道,对etcd中的键值对进行增删改查. 安装etcdctl 下载etcdctl工具 下载地址:etcdct ...