SpringBoot2.x—SpringCache(1)集成
SpringBoot2.x—SpringCache(2)使用
SpringBoot2.x—SpringCache(3) CacheManager源码
SpringBoot2.x—SpringCache(4)集成SpringCache保证Redis的数据一致性
SpringBoot2.x—SpringCache(5)使用多级缓存
SpringBoot2.x—SpringCache(6)缓存注意事项
1. 多级缓存的背景
一般在我们的系统架构中,使用Redis作为分布式缓存解决热点数据的访问。但是仅仅依赖于Redis会发生如下两个问题:
- Redis会有一定的网络I/O及序列化的问题,即使Protostuff方式进行序列化,也没有进程内的缓存快。
- 系统太过于依赖Redis,如果Redis挂掉,那么我们只能去访问DB,容易造成雪崩。
所以我们需要使用进程内的缓存
来实现多级缓存。
说起进程内缓存,对于我们并不陌生,例如我们常用的
ConcurrentHashMap
。但是ConcurrentHashMap
一般适合缓存数量较少
且大部分情况下不变
的元素。
2. 进程内缓存需要满足的要求
大多数场景下进程内缓存需要满足如下几个要求:
- 热点数据优先缓存,即缓存实现LRU算法。
- 若要发生内存溢出时,应清除缓存。即“软引用”(SoftRefernce)持有缓存对象。
- 可以设置缓存失效时间,来确保数据一致性。
下面借助一幅图来比较下流行的进程内缓存的优劣:
一般我们选择Guava Cache
或Caffeine
来实现进程内的缓存,而Caffeine
在读写性能和命中率上一般比Guava Cache
高,所以比较推荐使用Caffeine
。
3. 进程内缓存需要解决的问题
使用缓存,首先需要考虑的问题是数据一致性问题!特别是对于进程内的缓存,即使有数据更新,也只能删除更新数据的那台机器上的缓存,其他机器进程内缓存只能通过超时机制来清除缓存。
- 主动模式:依赖Redis发布/订阅解决主动通知各进程;
- 被动模式:依靠Caffeine和Redis的超时机制来兜底;