coldsmog开发笔记
JS 事件笔记
Ckeditor 上传WPS图片失败问题
Springboot
SpringBoot 统一异常处理
Springboot 引入外部jar包
Springboot 打成war包
Springboot 多环境配置
SpringBoot @Scope注解学习
Springboot 快速生成项目API文档
SpringCache 缓存
Spring jetcache 二级缓存
Springboot 按条件装配类
FastJson的JsonPath语法
正则表达式语法
Spring 路径匹配
Feign 基础数据操作
监控Feign调用metrics
Springboot feign的性能优化
Jackson 设置序列化属性
SpringBoot 集成 Spring Data Mongodb 操作 MongoDB
MongoDB 的一些注意事项
MongoDB 指令对比
Jackson 解析XML
Springboot Redis注册
SpringBoot RedisTemplate批量插入
Springboot 指标监控Micrometer
springboot validation 注解校验
springboot 引入配置
Springboot 静态文件处理
Springboot 导出csv文件
Springboot 事件驱动(发布/订阅模式)
Springboot 启动过程和扩展点
Springboot 优化停机上下线
Spring自动装配 - 干饭角度学习
Springboot ShardingJDBC
Springboot的重试
springboot 动态修改端口
Oracle
Oracle 中实现自增ID
Oracle 定时任务
Oracle 解锁临时表
Oracle 检查连接数
Oracle 表空间
Oracle 解释执行SQL
markdown作图(适用typora)
服务器压测
业务对象层和数据层
并发限流处理
中间件
Yarn的使用
Dubbo学习笔记-RPC扩展和本地Mock
Dubbo学习笔记-泛化实现进行mock
Redis缓存穿透,缓存击穿,缓存雪崩
Galera 集群说明
Pip 镜像
pip 使用
MySQL命令行
数据库缓存双写方案
Git相关操作
Redis 操作时间复杂度一览
nacos 杂记
mybatis 散记
shardingjdbc
一次线上事故排查发现的Caffeine缓存死锁问题
设计模式
重新讲讲单例模式和几种实现
更优雅地实现策略模式
Http-headers
Prometheus 杂散笔记
JAVA 散记
CompletableFuture
Gson、FastJson、Jackson、json-lib对比总结
jackson 时间的序列化踩坑
JVM
自定义注解
mysql类型和java类型 转换一览表
枚举维护一个Map<value, Enum>的映射
Java中String +、concat、StringBuilder、StringBuffer 性能对比
TraceId 使用
MySQL 多数据源处理
Mybatis-plus 流式查询
JAVA发送win 桌面通知
idea 启动项目失败非代码问题杂记
Lambda 简述
Arthas 使用笔记
一种链式更新数据的数据模式
Skywalking 新增中间件插件
Redission 使用
数据导出为图片
IDEA 的热重启
Netty 工具类
maven 插件
TCP 抓包
本文档使用 MrDoc 发布
-
+
首页
Redis缓存穿透,缓存击穿,缓存雪崩
# 概念解释 - redis 缓存穿透 key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。 - redis 缓存击穿 key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。 - redis 缓存雪崩 当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。 ## 解决办法 ### 1、 缓存穿透 有很多种方法可以有效地解决缓存穿透问题。 最简单的是将查询为空的也进行缓存,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间要比正常的短。 最常见的则是采用布隆过滤器,通过多个哈希函数,去数据哈希到一个足够大的bitmap中,查询时必须多个哈希函数都返回存在才查询数据库。多个哈希函数是为了避免哈希冲突,但是布隆过滤器只能新增,无法删除,选型时要加以考虑 ### 2、 缓存击穿 **加锁** 当缓存失效的时候,每个请求都落到数据库肯定会造成压力的,这点不论是redis还是mysql都要考虑到。 最简单是对数据访问服务加锁,无论多少并发请求,反正我请求redis时都是串行的。代价是并发性能降低,因为不同的请求参数实际上也被同样限制成串行了。 更优的解决方案地是对同样的请求参数加锁,不同的请求参数锁不互斥,这就涉及到请求参数加锁。由于每个请求默认不共享栈变量,所以同样的字符串作为key时,实际上字符串实例可能不一致,导致加锁没起到作用,故需要使用String::intern将字符串放入常量池,保证同样的字符串只有一份对象实例。代价是如果你的key不是有限的话,常量池会占用过大。 对常量池占用过大的另一种改进方案,是利用本地缓存保证实例唯一。这个代价是sonar会有一个异味,提示缓存函数调用方如果过多,会可能有死锁或者频繁等待的问题,且不易排查。使用者需要自己注意。 **不加锁** 对于只读业务的时间不敏感的数据可以采用主动缓存的方式,对QPS和并发能力都有一个较大的提高。本地缓存拉取数据,请求只从本地缓存。代价是缓存不一致的风险,需视业务而选 ### 3、 缓存雪崩 与缓存击穿的区别在于这里针对很多key缓存,前者则是某一个key。 最简单的方案是给缓存时间延长一个短的随机时间,如果缓存1小时的话,追加一个1分钟的随机时间。 更常见的解决方案是加入线程池或有锁队列保证来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上。
寒烟濡雨
2022年3月9日 11:24
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码