1.我们使用缓存时的业务流程大概为:

当我们查询一条数据时,先去查询缓存,如果缓存有就直接返回,如果没有就去查询数据库,然后返回。这种情况下就可能出现下面的一些现象。

2.缓存穿透

2.1什么是缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

2.2缓存穿透带来的问题

试想一下,如果有黑客对你的系统进行攻击,拿一个不存在的id去查询数据,会产生大量的请求到你的数据库去查询,可能会导致你的数据库由于压力过大而宕掉。

2.3解决的办法

2.3.1缓存空值

之所以会发生穿透,就是因为缓存中没有储存这些空数据的key。从而导致每次查询都到数据库去了。

那么我们就可以为这些key对应的值设置为null丢到缓存里面去。后面出现查询这个key的请求的时候直接返回null。

这样就不用再到数据库中去走一圈了,但是别忘了设置过期时间。

缓存空对象会有两个问题:

第一,空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间 ( 如果是攻击,问题更严重 ),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。

第二,缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。例如过期时间设置为 5分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致,此时可以利用消息系统或者其他方式清除掉缓存层中的空对象。

2.3.2用布隆过滤器BloomFilter

BloomFilter类似于一个hbase set用来判断某个元素(key)是否存在于某个集合中。

这种方式在大数据场景应用比较多,比如Hbase中使用它去判断数据是否在磁盘上。还有在爬虫场景判断url是否已经被爬取过。

这种方案可以加在第一种方案中,在缓存之前加一层BloomFilter,在查询的时候先去BloomFilter去查询key是否存在,如果不存在就直接返回,存在再去查缓存-------->差数据库。

流程图如下:

2.4如何选择

针对于一些恶意攻击,攻击带来大量key是不存在的,那么我们采用第一种方案就会缓存大量不存在的数据。此时我们采用第一种方案就不合适了,我们完全可以先使用第二种方案过滤掉这些key。

针对这些key异常多,请求多,重复率比较低的数据,我们就没有必要进行缓存,使用第二种方案直接过滤掉。

而对于空数据的key有限的,重复率比较高的,我们则可以采用第一种方式进行缓存。

3.缓存击穿

3.1什么是缓存击穿

缓存击穿是我们使用缓存可能遇到的第二个问题。

在平时高并发的系统中,大量的请求同时查询一个key时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去,这种现象我们称为缓存击穿。

3.2会带来什么问题

会造成某一时刻数据请求量过大,压力剧增。

3.3如何解决

上面现象是多个线程同时去查询数据库的这一条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它。(如果是单机,可以用synchronized或者lock来处理,如果是分布式环境可以用分布式锁就可以了(分布式锁,可以用memcache的add, redis的setnx, zookeeper的添加节点操作))

其他线程走到这一步拿不到锁就等着,等待第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有了缓存,就直接走缓存。

4.缓存雪崩

4.1什么是缓存雪崩

缓存雪崩的情况是指:当某一时刻发生大规模的缓存失效的情况,比如你的缓存服务宕机了,会有大量的请求进来直接打到数据库上面,结果就是数据库挂掉。

4.2解决办法

4.2.1雪崩前:使用集群缓存,保证缓存服务的高可用

这种方案就是在发生雪崩前对缓存集群,实现高可用,如果是使用Redis,可以使用(主从 + 哨兵),Redis Cluster来避免Redis全盘崩溃的情况。

4.2.2雪崩中:ehcache本地缓存 + Hystrix限流 & 降级,避免MySQl被打死

使用ehcache本地缓存的目的也是考虑Redis Cluster完全不可用的时候,ehcache本地缓存还能够支撑一阵。

使用Hystrix进行限流 & 降级,比如一秒来了5000个请求,我们可以设置假设一秒只能有2000个请求可以通过这个组件,那么其他剩余的3000请求就会走限流逻辑。

然后去调用我们自己开发的降级组件(降级),比如设置的一些默认值等等之类的。以此来保护最后的MySQl不会被大量的请求打死。

4.2.3雪崩后:开启Redis持久化,尽快恢复缓存集群。

5.解决热点数据集中失效问题

我们在设置缓存的时候,一般会给缓存设置一个失效的时间,过了这个时间,缓存就失效了。

对于一些热点数据来说,当缓存失效后会存在大量的请求到数据库上来,从而可能导致数据库崩溃的情况。

5.1解决办法

5.1.1设置不同的失效时间

为了避免这些热点数据集体失效,那么我们在设置缓存过期时间的时侯,让他们失效的时间错开。比如我们可以在原有的失效时间基础上增加一个随机值。

5.1.2互斥锁

结合上面的击穿情况,在第一个请求去查询数据库的时候对它加一个互斥锁,其余的查询请求都会被阻塞住,直到锁被释放,从而保护数据库。

但是也是由于它会阻塞其他线程,此时系统的吞吐量会下降。需要结合实际业务去考虑。

关于缓存穿透,缓存击穿,缓存雪崩,热点数据失效问题的解决方案(转)相关推荐

  1. 关于缓存穿透,缓存击穿,缓存雪崩,热点数据失效问题的解决方案

    关于缓存穿透,缓存击穿,缓存雪崩,热点数据失效问题的解决方案 参考文章: (1)关于缓存穿透,缓存击穿,缓存雪崩,热点数据失效问题的解决方案 (2)https://www.cnblogs.com/To ...

  2. Redis 缓存穿透、击穿、雪崩现象及解决方案

    前言 如何有效的理解并且区分 Reids 穿透.击穿和雪崩 缓存穿透 关键词:穿过 Redis 和数据库 当 Redis 和数据库中都没有我们想要的数据时,就需要考虑缓存穿透的问题了.下面这段逻辑大家 ...

  3. Redis应用问题解决(缓存穿透、击穿、雪崩、分布式锁)

    Redis应用问题解决(缓存穿透.击穿.雪崩.分布式锁) 缓存穿透 问题描述 当系统中引入redis缓存后,一个请求进来后,会先从redis缓存中查询,缓存有就直接返回,缓存中没有就去db中查询,db ...

  4. Redis缓存穿透、击穿、雪崩、预热、更新、降级

    Redis是高性能的分布式内存数据库,对于内存数据库经常会出现下面几种情况,也经常会出现在Redis面试题中:缓存穿透.缓存击穿.缓存雪崩.缓存预热.缓存更新.缓存降级.本篇分别介绍这些概念以及对应的 ...

  5. 缓存穿透、击穿、雪崩什么的傻傻分不清楚?看了这篇文后,我明白了

    对于缓存,大家肯定都不陌生,不管是前端还是服务端开发,缓存几乎都是必不可少的优化方式之一.在实际生产环境中,缓存的使用规范也是一直备受重视的,如果使用的不好,很容易就遇到缓存击穿.雪崩等严重异常情景, ...

  6. 缓存穿透、击穿、雪崩

    一.缓存穿透 缓存穿透是指缓存和数据库中均不存在目标数据,而用户不断发起请求,缓存也得不到更新,由此每次请求该数据都会到数据库.高并发量,就会对后端的 DB 系统造成很大压力.如查询 id 为&quo ...

  7. Redis基本数据类型、持久化机制、集群模式、淘汰策略、缓存穿透、击穿、雪崩、常见面试题大集合!

    redis redis reids的常用数据类型 1.String 2.Hash 3.List 5.Sorted Set(ZSet) 6.其他 发布(pub)订阅模式(sub)模式 作用 Redis的 ...

  8. Redis缓存穿透、击穿、雪崩、概念及解决办法

    在生产环境中,会因为很多的原因造成访问请求绕过了缓存,都需要访问数据库持久层,虽然对Redsi缓存服务器不会造成影响,但是数据库的负载就会增大,使缓存的作用降低 一.缓存穿透 1.缓存穿透理解   缓 ...

  9. Redis 缓存穿透、击穿、雪崩 解决方法

    目录 引言 一.缓存穿透 1. 缓存穿透的原理 2. 解决方法 2.1 布隆过滤器 2.2 缓存空对象 二.缓存击穿 1. 缓存击穿原理 2. 解决方法 2.1 设置热点数据永不过期 2.2 加互斥锁 ...

最新文章

  1. 如何编写可测试的golang代码
  2. SilverLight学习笔记--如何解决Button不响应MouseLeftButtonDown与MouseLeftButtonUp事件的问题...
  3. [导入]第 3 章 Enterprise Library 的设计
  4. MaxCompute+ Geabase 大话健康知识图谱取经之路
  5. HTTP协议的头信息详解
  6. [html] 说说js代码写到html里还是单独写到js文件里哪个好?为什么?
  7. 基于socket的C语言编程,C语言实现的Socket编程
  8. JQuery插件,轻量级表单模型验证
  9. 使用虚拟机安装操作系统可能出现的问题
  10. android立方体旋转动画,如何画出一个旋转的立方体
  11. MIPS指令集及汇编
  12. 预言机(Oracle)
  13. 概率论与数理统计 基本概念
  14. 阿里云域名注册与免费证书申请
  15. c#日期转换英文月份
  16. 一个Sqrt函数引发的血案
  17. yarn create @umijs/umi-app或者yarn create umi myapp 报错:文件名、目录名或卷标语法不正确。
  18. 苹果iOS App上架流程,非iOS开发人员上架教程
  19. CTF Crypto/MISC 在线工具网站
  20. 隐藏控制台程序的dos窗口

热门文章

  1. 10个优秀视差滚动插件
  2. 系统日志之logger命令
  3. 目标检测论文阅读:Cascade R-CNN: Delving into High Quality Object Detection(CVPR2018)
  4. 【今日CS 视觉论文速览】Fri, 1 Feb 2019
  5. 文件字节输出流 java
  6. 数据类型的判断 c# 1614092544
  7. 显示行号 visual studio 1006
  8. 存储与硬盘挂载 200305
  9. python项目-每日日考系统-数据结构
  10. -bash: ssh-copy-id: command not found解决方法