目录
架构方案
优化方案
冷热分离
缓存数据带有超时时间
查询后给缓存续期
缓存击穿
缓存中大数据量同时失效
解决:缓存过期时间+随机数
缓存穿透
流量因为某些原因,不仅仅打到缓存,并且打到DB,DB中也没有
常见是数据清理,但是前端仍可访问的高频数据
解决:
- 存放空缓存,超时时间设置较短且一般是一个固定的字符串,续期
- 布隆过滤器
冷数据突然变热,缓存重建
大量请求直接到DB
解决:重建缓存逻辑加锁(分布式锁),锁中先重新检查,再重建
缓存、数据库不一致
查询数据库塞入缓存
如果有其他线程插入执行就会有不一致问题
解决:
- 并发小的就直接加超时时间
- 加分布式锁,锁住:查询和更新操作,可以使用读写锁
锁的优化
读写锁
如果操作之间没有并发关系那么就应该加读锁
如:数据库读,Redis写
如果操作之间存在并发关系那么就应该加写锁
如:1个线程数据库写,缓存写
1个线程数据库读,缓存写
数据库写就应该加写锁
Redis雪崩
Redis都承受不住的时候就需要考虑再加一层缓存,EhCache等。
注意本地缓存的同步处理
- 缓存层高可用
- 限流、熔断、降级
Redis连接池参数
- maxTotal
应用数据 * maxTotal 不能大于Redis配置的maxclients
估算一个连接的QPS,然后总QPS/单个连接QPS - maxIdle
资源池中空闲情况下保留的连接数 - minIdle
基本没有什么用,有些配置要用
连接池预热
把连接池中的连接提前执行命令
可以基于minIdle去初始化
并且不需要执行连接的 close()
这里的close()只是归还连接的意思
如果初始化的时候归还则重新获取有可能获取到原来的连接
所以需要初始化之后统一的在执行一次close()
可以把初始化的连接维护在另外一个list中
Redis过期key的清除策略
- 被动删除:
惰性删除,
下次拿key的时候判断是否过期,
过期则清理后返回为空 - 主动删除
定期清除已过期的key清除 - 主动清理策略
内存已经超过maxmemory则执行主动清理策略
清楚策略
-
volatile-ttl : 越早过期越先删除
-
volatile-random : 从设置过期时间的key中随机选
-
volatile-lru : LRU算法删除配置了过期时间的key
-
volatile-lfu : LFU算法删除配置了过期时间的key
-
allkeys-random
-
allkeys-lru
-
allkeys-lfu
-
noeviction : 不删除原有数据,拒绝新的写入操作并返回错误信息,只响应读操作
LRU
Least Recently Used 最近最少使用 : 基于最近一次访问时间
LFU
Least Frequently Used 最不经常使用: 基于 次数
布隆过滤器
如果 布隆过滤器 查询不存在 则key一定不存在,如果过滤器说存在则可能存在
组成
一个大型位数组
多个不同的无偏Hash函数
过程:存key 的时候先进行几次hash运算,算出hash值%位数,把对应的位数设置为1
查数据的时候先惊醒几次hash运算,然后hash值%位数,去位数组中查询,如果有一个返回为0则说明 key 再redis中不存在