如何实现多级缓存?


一、什么是多级缓存?

多级缓存指的是在系统的不同环节都添加缓存,以提高系统性能

我们一般工作中提到的多级缓存一般是本地缓存+分布式缓存:

  • 本地缓存:指在当前服务里使用到的缓存,一般使用的是Guava和Caffeine框架,都提供了缓存的过期等机制
  • 分布式缓存:指在多个服务里使用到的缓存,一般使用的是Redis和Memcached框架

二、为什么要用到多级缓存?

正常情况下,我们不使用本地缓存而直接使用分布式缓存的话,就会涉及网络调用,会出现一定的性能消耗,所以在大型项目中,一般使用多级缓存也就是本地缓存+分布式缓存来实现缓存查询

使用本地缓存的优点:

  • 减少网络调用,提高性能
  • 减少分布式缓存的读压力

使用本地缓存的缺点:

  • 可能会存在与分布式缓存数据不一致的问题
  • 可能会存在与其他服务集群数据不一致的问题
  • 重启服务数据会丢失
  • 进程空间有限,不支持大数据量存储

三、如何实现多级缓存?

多级缓存的调用链路一般是:

  • 先查询本地缓存,如果存在则直接返回
  • 再查询分布式缓存,如果存在则同步到本地缓存并返回

四、Q&A

1、如何解决本地缓存不支持大数据量存储的问题?

一般在项目中,我们不应该把所有数据都存储到本地缓存里,而是只把热点数据存储到本地缓存里即可,这样可以有效解决本地缓存空间受限问题

2、如何解决本地缓存和分布式缓存数据不一致问题?

通常我们使用缓存来分担读压力,就可能会出现数据不一致问题,这种是很难避免的,所以一般情况下我们只需要保证数据的最终一致性即可

最终一致性方案:如使用Guava框架,使用超时过期、定时更新机制,可以保证数据在一定时间后会进行数据的同步,从而保证数据最终一致性

public class CacheTest {
    public static void main(String[] args) {
        LoadingCache<String,Object> cache = CacheBuilder.newBuilder()
                .refreshAfterWrite(5, TimeUnit.SECONDS)  //5分钟定时刷新
                .expireAfterAccess(5, TimeUnit.SECONDS)  //5分钟自动过期
                .build(new CacheLoader<String, Object>() {
                           @Override
                           public Object load(String key) throws Exception {
                               return xxx;
                           }
                       }
                ); 
    }
}

文章作者: GaryLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GaryLee !
  目录