缓存尽可能设置过期时间
如果不设置过期时间,缓存的内存就会越占越多,最后内存用完了,就没法缓存了。
注意缓存雪崩
缓存雪崩 (Cache Avalanche) :是指在某一时刻发生大量的缓存失效,导致瞬间大量的请求直接打到了数据库,可能会导致数据库瞬间压力过大甚至宕机。
为避免缓存雪崩,可以:
-
设置不同的过期时间:可以给过期时间设置为不同的过期时间,防止同一时间全部过期。
-
使用熔断:使用熔断机制,当数据库请求到达一定的阈值时,直接拒绝部分请求,以保护数据库不被过度访问。
详情见: https://www.cnblogs.com/lianshuiwuyi/p/17771618.html
注意缓存击穿
缓存击穿(Hotspot Invalid),是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到数据库。
为避免缓存击穿,可以:
-
设置热点数据不过期。避免在数据过期后对数据库造成压力。
-
提前做好缓存预热。在高峰期开始之前,将热点数据预先加载到缓存中并设置其永不过期,以避免在高峰期对数据库造成过大压力。
注意缓存穿透
缓存穿透(Cache penetration) 是指请求一个不存在的数据,导致每次请求发现缓存中没有,都直接查询数据库,而数据库中也没有这个数据。
为避免缓存穿透,可以:
- 缓存空对象:当数据库中查不到数据时,缓存一个空对象,并给这个空对象的缓存设置一个过期时间。减小数据库压力。
- 布隆过滤器(Boom Filter): 在查询数据时,先判断该数据是否存在于布隆过滤器中,如果存在则直接返回结果,否则再从数据库中查询数据。布隆过滤器可能会存在误报(即误认为key存在而实际不存在)。
缓存的实体类需要实现序列化
实现 implements Serializable 接口。
public class MyDto implements Serializable {private static final long serialVersionUID = 7659376799579550945L;}
如果使用 @Cacheable 缓存 要避免在同一个类内调用
@Cacheable 是基于 AOP 动态代理的。如果在同一个类里面,调用 @Cacheable 注解的方法,缓存是不会生效的。
可以用 @Resource 在类里面注入同样的类,再用注入的类调用方法,就会走 Aop 代理。
或者是 将 @Cacheable 注解的方法 移到另一个类中。
如果使用 @Cacheable 缓存 ,需要要在启动类上加上 @EnableCaching注解
需要要在启动类上加上 @EnableCaching注解, 否则 @Cacheable 注解不会生效。
要注意缓存和数据库的一致性
如果更新数据库的数据之后,没有处理缓存,那么在查询时,查到的还是缓存中的旧数据,这就会导致缓存和数据库的不一致。
在数据更新之后,可以删除掉缓存。这样数据库和缓存能保持一致。
缓存大key时,要注意
什么才叫大 key?一般认为:
- 缓存的value > 10kb,即认定为大 key.
- 像list,set,hash 等容器类型的 redis key,元素数量 > 5000,即认定为大 key
缓存大key如何解决?
(1) 数据分拆:将原本存储在单个大key下的数据分拆成多个较小的key-value对。例如,可以使用Redis的哈希结构(hash)来存储原本属于大key的多个字段,每个字段作为哈希结构的一个域(field),从而分散存储数据。
(2) 数据压缩:适用于字符串类型的 redis key。采用压缩算法进行压缩,减小value。
参考资料:
https://blog.csdn.net/wdj_yyds/article/details/132189196
www.cnblogs.com/lianshuiwuyi/p/17771618.html