目录
互联网公司多级缓存架构:
Nginx(负载均衡设备)缓存:例如存放热点数据(容量最小)
web缓存(JVM级别):Ehcache 、Map等(容量稍大)
Redis缓存:容量最大
缓存访问顺序:
Nginx缓存,有则返回 -> 本地内存(JVM)缓存,有则返回 -> Redis缓存,有则返回 -> 应用服务,访问数据库
缓存存在的问题:
1. Redis缓存穿透,缓存击穿,缓存雪崩
2. 热点缓存key重建问题
3. 缓存与数据库双写不一致问题
缓存穿透
定义:查询一个根本不存在的数据, 缓存层和存储层都不会命中
结果:导致不存在的数据每次请求都要到存储层去查询, 失去了缓存保护后端存储的意义。高并发情况下造成服务崩溃。
解决方案:
1. 缓存空对象
if productid不存在,set key null缓存;
思考:若后期上架了productid一样的产品,会有什么结果?
Answer:可能会导致后上架的产品一直查不到数据
方案:缓存空对象时,设置超时时间
2. 布隆过滤器
布隆过滤器:实现了一种bitMap的过滤器,对于不存在的key数据布隆过滤器一般都能够过滤掉,不让请求再往后端发送。(当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在)
这种方法适用于数据命中不高、 数据相对固定、 实时性低(通常是数据集较大) 的应用场景, 代码维护较为 复杂, 但是缓存空间占用很少。
布隆过滤器不能修改其中的数据,例如key删除以后,布隆过滤器中数据还在。优化:定期重建布隆过滤器。
实现 redisson
缓存击穿(缓存失效)
定义:由于大批量缓存在同一时间失效可能导致大量请求同时穿透缓存直达数据库
结果:会造成数据库瞬间压力过大甚至挂掉
解决方案:在批量增加缓存时最好将这一批数据的缓存过期时间设置为一个时间段内的不同时间(random)
缓存雪崩
定义:是缓存层支撑不住或宕掉后,流量会打向后端存储层(原因:大并发访问,redis设计不合理)
结果:存储层的调用量会暴增,造成存储层也会级联宕机
解决方案:
1. 改良Redis缓存设计:保证缓存层服务高可用性,比如使用Redis Sentinel或Redis Cluster
2. 在服务中使用隔离组件为后端服务限流/熔断并降级(微服务相关内容Spring Cloud),比如使用Sentinel或Hystrix限流降级组件
例如:非核心数据查询:产品标签,收藏数等,采用服务降级,返回预设定信息或空值或错误提示;暂停从缓存中查询这些数据
核心数据查询:产品库存,价格等,允许查询缓存,如果缓存缺失,也可以继续通过数据库读取
3. 组织进行故障演练,测试环境/生产环境。关键:流量预估,预案设定