赞
踩
描述: 在某些特定环境下,无论是先更新Redis
还是更新数据库,两者的数据都有可能不一致。
解决方案1 双写模式
解决方案2 失效模式
最终解决方案
无论是双写模式还是失效模式,都会导致缓存的不一致问题。即多个实例同时更新会出事,怎么办?
canal
订阅binlog
的方式总结:
Canal - Binlog的增量订阅和消费组件(了解)
描述: 指查询一个一定不存在的数据,由于缓存是不命中,将去查询数据库,但是数据库也无此记录,我们没有将这次查询的null
写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。
风险:利用不存在的数据进行攻击,数据库瞬时压力增大,最终导致崩溃。
解决方案:
id
做基础校验,id<=0
的直接拦截;value
存为null
,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用),这样可以防止攻击用户反复用同一个id
暴力攻击。描述:
key
,如果这些key
可能会在某些时间点被超高并发地访问,是一种非常热点的数据key
在大量请求同时进来前正好失效,那么所有对这个key
的数据查询都落到db
,我们称为缓存击穿。解决方案:
https://hucheng.blog.csdn.net/article/details/106020884
描述:
缓存雪崩是指在我们设置缓存时key
采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB
,DB
瞬时压力过重雪崩。
解决方案:
造成异常的原因: SpringBoot 2.0
以后默认使用lettuce
作为操作redis
的客户端,它使用netty
进行网络通信;lettuce
的bug
导致netty
堆外内存溢出,netty
如果没有指定堆外内存,默认使用-Xmx
参数指定的内存;可以通过-Dio.netty.maxDirectMemory
进行设置。
解决方案:不能只使用-Dio.netty.maxDirectMemory
去调大堆外内存,这样只会延缓异常出现的时间。
升级 lettuce 客户端,或使用 jedis 客户端。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。