缓存流程

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

程序在处理请求时,会先从缓存中进行查询,如果缓存中没有对应的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. H3C 配置CHAP验证

  2. 洛谷P1809 过河问题 经典贪心问题

    作者:zifeiy 标签:贪心 题目链接:https://www.luogu.org/problem/P1809 我们假设第 \(i\) 个人过河的耗时是 \(t[i]\) ,并且 \(t[i]\) ...

  3. JavaScript:4个常见的内存泄露

    什么是内存泄漏 内存泄漏基本上就是不再被应用需要的内存,由于某种原因,没有被归还给操作系统或者进入可用内存池. 编程语言喜欢不同的管理内存方式.然而,一段确定的内存是否被使用是一个不可判断的问题.换句 ...

  4. 整理了一下angularJs的webpack模板

    github地址:https://github.com/qianxiaoning/demo-angularJs1.7.5 欢迎大家star或者fork呀~ 目录结构 src/ components/ ...

  5. [Atom 编辑器 ] Packages

    Atom包      https://atom.io/packages 常用包整理: atom-chinese-menu   中文插件 atom-ternjs   对 es5,es6的语法支持 ato ...

  6. linux 在启动时获得专用的缓冲

    如果你真的需要一个大的物理上连续的缓冲, 最好的方法是在启动时请求内存来分配它. 在启动时分配是获得连续内存页而避开 get_free_pages 施加的对缓冲大小限制的唯一 方法, 不但最大允许大小 ...

  7. 消息驱动Bean

    消息驱动bean是专门用来处理基于消息请求的组件.MDB负责处理消息,而EJB容器则负责处理服务(事务,安全,并发,消息确认等),使Bean的开发者集中精力在处理消息的业务逻辑上. 消息驱动Bean. ...

  8. [Linux] 利用tcpdump和strace进行debug

    比如说要查看所有的sql查询语句,数据库的端口是3306 tcpdump -i any port 3306 -l -s 0 -w -|strings|grep -A 5 select 要查看所有的调用 ...

  9. 前端工具--利用Adblock Plus阻止js执行

    今天遇到个问题:需要阻止页面某个js的运行 效果达到

  10. win10 配置g++环境

    一.配置g++编译器的环境 1.将g++编译器的位置添加到环境变量path中,安装了C++ IDE的可以在IDE的安装目录下寻找 例如:C:\MySoftware\dev\Dev-Cpp\MinGW6 ...