SpringBoot2.x—SpringCache(5)使用多级缓存(进程内缓存+分布式缓存)

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会发生如下两个问题:

  1. Redis会有一定的网络I/O及序列化的问题,即使Protostuff方式进行序列化,也没有进程内的缓存快。
  2. 系统太过于依赖Redis,如果Redis挂掉,那么我们只能去访问DB,容易造成雪崩。

所以我们需要使用进程内的缓存来实现多级缓存。

SpringBoot2.x—SpringCache(5)使用多级缓存(进程内缓存+分布式缓存)_第1张图片
多级缓存架构.png

说起进程内缓存,对于我们并不陌生,例如我们常用的 ConcurrentHashMap。但是 ConcurrentHashMap一般适合缓存 数量较少大部分情况下不变的元素。

2. 进程内缓存需要满足的要求

大多数场景下进程内缓存需要满足如下几个要求:

  1. 热点数据优先缓存,即缓存实现LRU算法。
  2. 若要发生内存溢出时,应清除缓存。即虚引用持有缓存对象。
  3. 可以设置缓存失效时间,来确保数据一致性。

下面借助一幅图来比较下流行的进程内缓存的优劣:

SpringBoot2.x—SpringCache(5)使用多级缓存(进程内缓存+分布式缓存)_第2张图片
进程内缓存的优劣.png

图片来源于:如何优雅的使用缓存?

一般我们选择Guava CacheCaffeine来实现进程内的缓存,而Caffeine在读写性能和命中率上一般比Guava Cache高,所以比较推荐使用Caffeine

3. 进程内缓存需要解决的问题

使用缓存,首先需要考虑的问题是数据一致性问题!特别是对于进程内的缓存,即使有数据更新,也只能删除更新数据的那台机器上的缓存,其他机器进程内缓存只能通过超时机制来清除缓存。

  1. 主动模式:依赖Redis发布/订阅解决主动通知各进程;
  2. 被动模式:依靠Caffeine和Redis的超时机制来兜底;
SpringBoot2.x—SpringCache(5)使用多级缓存(进程内缓存+分布式缓存)_第3张图片
Redis的发布订阅模型解决数据一致性问题.png

你可能感兴趣的:(SpringBoot2.x—SpringCache(5)使用多级缓存(进程内缓存+分布式缓存))