接口查询性能优化-缓存
查询性能优化
-
缓存种类
-
mybatis一级缓存
-
mybatis二级缓存
-
本地缓存
-
各个节点的数据不同步
-
分布式缓存
-
redis
-
前端h5的缓存
-
本地缓存
-
session缓存
-
mybatis一级缓存
-
一个方法中对同一个sql,查询了多次
-
当在这个方法上加@transactional
-
后续的查询就是走一级缓存,不会查数据库。
-
关闭一级缓存
-
mybatis.configuration.local-cache-scope=statement
-
mybatis二级缓存
-
默认是没有开启的
-
在多次接口调用时的缓存,后几次请求就走缓存
-
缓存的类要序列化
-
加cache标签就行了
-
有增删改的时候缓存会刷新
-
缺点:刷新快的场景不适合用,分布式场景:执行增删改的时候,没有被执行的机器,还会读之前的数据。
-
springboot内置的缓存
- redis
-
缓存击穿
-
热点key失效,都打到数据库了
-
60s失效
-
定时任务刷新缓存60s
-
如果缓存坏了
-
分布式锁,
-
只有一个线程能查询数据库。
-
没有锁的就快速失败。
-
有上千个获取锁的请求
缓存穿透
-
if(有数据){ 返回}else{ 查询数据库,写入缓存}
-
这样就有上千个请求打到数据库
-
-
这样就有上千个请求打到数据库
-
解决办法
-
else里加分布式锁,其他快速失败
-
空列表也方缓存,null;null则去数据库查,空列表则直接返回,不查数据库。
-
-
雪崩
-
多个key同时失效
-
热点key大量失效
-
如果设置成不过期
-
则需要设置缓存过期策略
-
最好的办法是把所有的key打散
-
定时任务主动查询进行打散
-
查询时也要针对事务加锁。
-
加锁的外面也要加个限流
数据库缓存一致性
类型 |
具体方法 | 优劣 |
强一致性 原子性 |
||
redis的decr | 简单场景可以,使用方便 | |
lua脚本 | 需要会lua语言,lua脚本过大性能低 | |
分布式锁 | 适合复杂场景 | |
最终一致性 | ||
消息,重试直到成功 | 不能立刻一致 | |
延时双删 | 不好,延时时间不可把握,且也是依赖消息异步删除,还有缓存穿透的风险 | |
监听binlog,异步更新 | 有短暂延迟,和消息类似。还要引入canal中间件,增加系统复杂程度。 |
~