缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要。但是将缓存加入应用架构后也会带来一些问题,本章将针对这些问题介绍缓存使用技巧和设计方案,包含如下方案:
缓存的收益和成本分析。
缓存更新策略的选择和使用场景。
缓存粒度控制方法。
穿透问题优化。
无底洞问题优化。
雪崩问题优化。
热点key重建优化。
缓存的收益和成本
下图左侧为客户端直接调用存储层的架构,右侧为比较典型的缓存层+存储层架构,下面分析一下缓存加入后带来的收益和成本。
收益如下:
加速读写:因为缓存通常都是全内存的(例如Redis、Memcache),而存储层通常读写性能不够强悍(例如MySQL),通过缓存的使用可以有效地加速读写,优化用户体验。
降低后端负载:帮忙后端减少访问量和复杂计算(例如很复杂的SQL语句),在很大程度降低了后端的负载。
成本如下:
数据不一致性:缓存层和存储层的数据存在着一定时间窗口的不一致性,时间窗口跟更新策略有关。
代码维护成本:加入缓存后,需要同时处理缓存层和存储层的逻辑,增大了开发者维护代码的成本。
运维成本:以Redis Cluster为例,加入后无形中增加了运维成本。
缓存的使用场景基本包含如下两种:
开销大的复杂计算:以MySQL为例子,一些复杂的操作或者计算(例如大量联表操作、一些分组计算),如果不加缓存,不但无法满足高并发量,同时也会给MySQL带来巨大的负担。
加速请求响应:即使查询单条后端数据足够快(例如select * from table where id = ?),那么依然可以使用缓存,以Redis为例子,每秒可以完成数万次读写,并且提供的批量操作可以优化整个IO链的响应时间。