缓存流程

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

程序在处理请求时,会先从缓存中进行查询,如果缓存中没有对应的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. 微软的可疑更新DhMachineSvc.exe

    最近微软大范围的推出了一个只针对中国的更新,包含了DhMachineSvc.exe,也就是所谓的'微软设备健康助手服务'. 这个更新很神秘,首先这个更新只针对中国区,其次这个更新支持WinXP,第三这 ...

  2. 【TensorFlow】理解tf.nn.conv2d方法 ( 附代码详解注释 )

    最近在研究学习TensorFlow,在做识别手写数字的demo时,遇到了tf.nn.conv2d这个方法,查阅了官网的API 发现讲得比较简略,还是没理解.google了一下,参考了网上一些朋友写得博 ...

  3. Vue的filter过滤器

    一和二,请参考https://www.cnblogs.com/zui-ai-java/p/11109213.html 三.index.html <!DOCTYPE html> <ht ...

  4. 【codeforces 789B】Masha and geometric depression

    [题目链接]:http://codeforces.com/contest/789/problem/B [题意] 让你一个一个地写出等比数列的每一项 (注意是一个一个地写出); 有m个数字不能写; 且数 ...

  5. 【t085】Sramoc问题

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] Sramoc(K,M)表示用数字0,1,2,...,K-1组成的自然数中能被M整除的最小数.给定K,M ...

  6. UPC个人训练赛第十五场(AtCoder Grand Contest 031)

    传送门: [1]:AtCoder [2]:UPC比赛场 [3]:UPC补题场 参考资料 [1]:https://www.cnblogs.com/QLU-ACM/p/11191644.html B.Re ...

  7. 2019-9-2-C#命令行解析工具

    title author date CreateTime categories C#命令行解析工具 lindexi 2019-09-02 12:57:37 +0800 2018-2-13 17:23: ...

  8. win10 uwp 发布旁加载自动更新

    在很多企业使用的程序都是不能通过微软商店发布,原因很多,其中我之前的团队开发了很久的应用,结果发现没有用户能从微软应用商店下载所以我对应用商店没有好感.但是作为一个微软粉丝,怎么能不支持 UWP 开发 ...

  9. python调用另一个文件中的代码,pycharm环境下:同文件夹下文件(.py)之间的调用,出现红线问题

    如何调用另一个python文件中的代码无论我们选择用何种语言进行程序设计时,都不可能只有一个文件(除了“hello world”),通常情况下,我们都需要在一个文件中调用另外一个文件的函数呀数据等等, ...

  10. quartz关闭DBUG日志

    引用了Quartz组件后,打印日志时,整天都有相应的调试信息打印出来,严重影响了查找日志效率,谷歌一番后,修改nlog配置文件即可 <?xml version="1.0" e ...