作用:加速读写,降低数据库的访问负载
存在的问题:数据不一致,缓存层和数据层有段时间不一致问题,与更新策略有关
缓存更新策略
1.LRU/LFU/FIFO算法剔除
- maxmemory-policy: 最大内存剔除策略 过期键执行LRU
2.超时剔除
- expire:设置过期时间(问题是没过期时数据变化,数据不一致)
3.主动更新
- 开发控制生命周期,删除缓存重新获取数据
推荐使用更新策略:
1.低一致性:最大内存
2.高一致性:超时与主动更新结合,最大内存防备(避免内存超过最大内存出现问题)
缓存粒度控制
在MySQL中获取数据如:select * from user where id={id}
设置用户信息缓存如:set user:{id} "用户数据"
-
缓存的粒度:
全部属性字段
部分重要字段
比较:
- 通用性:全量属性更好
- 占用空间:部分属性更好
- 代码维护:表面上全量属性更好
综合具体数据使用不同的粒度,对用户数据容易扩展使用全量,对于开发的一些功能可能后期不会有很大变化使用部分属性
缓存雪崩
缓存层服务异常,大量请求直接达到存储层,造成故障,
1.保证缓存的高可用
- 如:redis cluster, redis sentinel
2.使用隔离组件限流
- 如:Hystrix
3.提前演练
- 如:压力测试
优化io的方法:
1.命令本身优化 如:慢查询key hgetall
2.减少网络通信的次数
3.降低接入成本 如:长连接连接池
批量优化方法:
1.串行mget
2.串行io
- pipeline流水线
3.并行io
- 使用并行特性
缓存穿透
访问的数据缓存中没有,继续请求存储层,如果存储层也没有数据,大量请求会到存储层加大存储层的负载
发现缓存穿透:
1.业务的请求时间
2.业务出现问题
3.监测指标:缓存命中数,存储层命中数,采集每分钟的变化
解决方法:
1.缓存空对象(确定数据不存在 ,设置过期时间10min根据具体业务定 ,减少storage的负载)
-
存在的问题:
1.需要更多的键(设置过期时间,避免导致后面的数据问题)
2.缓存层与存储层短期不一致(使用订阅消息,有数据刷新缓存)
2.布隆过滤器拦截
所有的key放到布隆过滤器中,不存在的key进行拦截 ,需要实时更新布隆过滤器中的key
热点key重建
热点key访问量大,重建的时间长,导致很多线程重建,加大了存储层负载
解决方法:
1.互斥锁 mutex lock
- 缺点:会有大量线程阻塞
2.永不过期
没有设置过期时间,为每个value设置逻辑过期时间,超过逻辑过期时间使用单独的线程去重建缓存
- 缺点:过期到缓存重建的时间间隙数据不一致