缓存流程

在讲这五个问题之前,首先我们回顾下正常的缓存的使用流程

程序在处理请求时,会先从缓存中进行查询,如果缓存中没有对应的key,则会从数据库中查询,如果查询到结果,并将查询结果添加到缓存中去,反之不缓存。流程就不多解释了,基于这个我们展开下面的问题。


缓存穿透

产生原因

当查询一个一定不存在的key时,由于不能命中缓存,所以要查询数据库,但是这个key又不存在,所以查询不到结果,不会缓存。于是就有了利用这种一定不存在的key作为查询条件,对系统进行攻击,增加数据库压力,这种现象称为缓存穿透

解决方法

  1. 布隆过滤
    首先要规范key的命名,对不规范的key直接过滤掉,并对所有可能的key以hash形式存储到一个足够大的bitmap中,不存在的数据会被此bitmap拦截,以避免查询数据库。
  2. 缓存空对象
    意思很简单,就是对返回数据为空的情况也进行缓存,并设置一个很短的过期时间,这样也能起缓解作用。但是这也会产生下面两个问题:

    • 缓存空对象意味着需要更多的存储空间,可再缩短缓存时间,过期自动剔除
    • 导致缓存与数据库不一致,比如某个key:a查询时还没有数据,这时会缓存空值,但是其他某个流程已走完,数据已添加到了数据库中,这时访问依旧会返回空值,因为缓存还没过期,所以解决方法就是增删改时也进行缓存的刷新

缓存雪崩

产生原因

当大批量缓存集中在同一时间内失效(或者redis宕机),产生大量缓存穿透,此时又有请求并发袭来,查询压力瞬间都落在了数据库上,此时就产生了缓存雪崩

解决方法

  1. 失效时间加随机值
    给缓存失效时间加一个随机值,避免集体失效
  2. 实现redis高可用
    通过对redis实现集群搭建来避免部分机器宕机导致redis不可用的情况
  3. 分布式锁或分布式队列
    保证缓存单线程写,并在没有获取锁的线程中一直轮询缓存,直到超时

缓存击穿

产生原因

缓存击穿是指缓存中没有但是数据库中有的数据(通常是缓存到期),由于并发,未能从缓存读到数据,从而引起数据库鸭梨瞬间增大

解决方法

  1. 设置热门缓存数据永不过期
    这里永不过期有两层意思:

    • 不设置过期时间或超长缓存时间即物理上不过期
    • 在缓存对象上添加一个标识过期时间的属性,在获取数据后校验过期时间,如果已过期则异步去更新改缓存
      这种方式可能会出现数据脏读(在缓存更新期间取到旧数据)的情况,视业务而定使用与否
  2. 分布式锁或分布式队列
    保证缓存单线程写,并在没有获取锁的线程中一直轮询缓存,直到超时

缓存一致性

如果对数据有强一致性要求的,那就不要使用缓存了


缓存并发竞争

产生原因

多个子系统set同一个key,导致产生并发竞争

解决方法

  1. 对key没有顺序要求
    使用分布式锁实现
  2. 对key有顺序要求
    将key对应的值带上时间戳
  3. 异步队列
    放入队列中,串行set就行

Redis-缓存穿透、缓存雪崩、缓存击穿、缓存一致性、并发竞争的更多相关文章

  1. Redis缓存穿透和雪崩

    缓存穿透 用户想要查询一个数据 在redis缓存数据库中没有获取到 就会向后端的数据库中查询. 当用户很多 都去访问后端数据库的话,这就会给数据库带来很大的压力. 常见场景:秒杀活动 等 解决方法: ...

  2. 缓存穿透、雪崩、热点与Redis

    (拼多多问:Redis雪崩解决办法) 导读:互联网系统中不可避免要大量用到缓存,在缓存的使用过程中,架构师需要注意哪些问题?本文以 Redis 为例,详细探讨了最关键的 3 个问题. 一.缓存穿透预防 ...

  3. Redis系列(八)--缓存穿透、雪崩、更新策略

    1.缓存更新策略 1.LRU/LFU/FIFO算法剔除:例如maxmemory-policy 2.超时剔除,过期时间expire,对于一些用户可以容忍延时更新的数据,例如文章简介内容改了几个字 3.主 ...

  4. redis的穿透和雪崩

    穿透: 从缓存中查询一个数据,查到为空,需要每次都去数据库中查询.而从数据库中查询出来也为空,也就不写入缓存.导致一个不存在的数每次都去数据库中查询,造成db系统很大压力 造成缓存穿透 解决:如果从数 ...

  5. 深入了解Redis(7)-缓存穿透,雪崩,击穿

    redis作为一个内存数据库,在生产环境中使用会遇到许多问题,特别是像电商系统用来存储热点数据,容易出现缓存穿透,雪崩,击穿等问题.所以实际运用中需要做好前期处理工作. 一.缓存雪崩 1.概念 缓存雪 ...

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

    Redis缓存能够有效地加速应用的读写速度,就DB来说,Redis成绩已经很惊人了,且不说memcachedb和Tokyo Cabinet之流,就说原版的memcached,速度似乎也只能达到这个级别 ...

  7. Redis高级应用解析:缓存穿透、击穿、雪崩

    1 背景 像我们去面试一些大公司的时候,就会遇到一些关于缓存的问题.可能很多同学都是接触过,多多少少了解一些,但是如果没有好好记录这些内容,不熟练精通的话,在真正面试的时候,就很难答出来了. 在我们的 ...

  8. SpringBoot微服务电商项目开发实战 --- Redis缓存雪崩、缓存穿透、缓存击穿防范

    最近已经推出了好几篇SpringBoot+Dubbo+Redis+Kafka实现电商的文章,今天再次回到分布式微服务项目中来,在开始写今天的系列五文章之前,我先回顾下前面的内容. 系列(一):主要说了 ...

  9. Redis中几个简单的概念:缓存穿透/击穿/雪崩,别再被吓唬了

    Redis中几个“看似”高大上的概念,经常有人提到,某些好事者喜欢死扣概念,实战没多少,嘴巴里冒出来的全是高大上的名词,个人一向鄙视概念党,呵呵! 其实这几个概念:缓存穿透/缓存击穿/缓存雪崩,有一个 ...

  10. Redis缓存穿透,缓存击穿,缓存雪崩,热点Key

    导读 使用Redis难免会遇到Redis缓存穿透,缓存击穿,缓存雪崩,热点Key的问题.有些同学可能只是会用Redis来存取,基本都是用项目里封装的工具类来操作.但是作为开发,我们使用Redis时可能 ...

随机推荐

  1. DIRECTORY_SEPARATOR 与 getcwd

    DIRECTORY_SEPARATOR:目录分隔符,linux上就是’/’    windows上是’\’ ,php的内置常量是一个显示系统分隔符的命令,php的内部常量,不需要任何定义与包含即可直接 ...

  2. Vue打包文件放在服务器,浏览器存在缓存问题的解决

    在入口文件index.html添加 <meta http-equiv="pragram" content="no-cache"> <meta ...

  3. linux readv 和 writev

    Unix 系统已经长时间支持名为 readv 和 writev 的 2 个系统调用. 这些 read 和 write 的"矢量"版本使用一个结构数组, 每个包含一个缓存的指针和一个 ...

  4. H3C DHCP中继配置示例

  5. HDU 6662 Acesrc and Travel (换根dp)

    Problem Description Acesrc is a famous tourist at Nanjing University second to none. During this sum ...

  6. LeetCode3_无重复字符的最长子串(数组&字符串问题)

    题目: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "ab ...

  7. Struts2 基于XML校验(易百教程)

    以下是的各类字段级和非字段级验证在Struts2列表: date validator: <field name="birthday"> <field-valida ...

  8. [译文] 为什么你在 C# 里总是应该使用 "var" 关键字

    [译文] Why You Should Always Use the 'var' Keyword in C# (为什么你总是应该在 C# 里使用 "var" 关键字) Using ...

  9. 解析GMT+N时区,返回日期类型

    涉及到正则表达式,时区转换. /** * * 按格式 yyyy-MM-dd HH:mm:ss 以指定GMT时区进行解析,返回对应的当前系统时区当地时间. * @param dateString  格式 ...

  10. fastdfs基本安装流程和集成springboot总结

    FastDFS介绍 1.简介 FastDFS 是一个开源的高性能分布式文件系统(DFS). 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡.主要解决了海量数据存储问题,特别适合以 ...