JVM级别的本地缓存框架Guava Cache:探寻实现细节与核心机制

本文详细探讨了Guava Cache的回源策略,包括CacheLoader和Callable两种方式,以及数据清理与加载刷新机制。Guava Cache采用惰性删除策略,数据过期后并非立即删除,而在访问时触发。数据刷新通过refreshAfterWrite实现,支持非阻塞加载。文章还分析了expire和refresh的区别与应用场景,并讨论了Guava Cache的并发能力,如分段锁和佛系抢锁策略,最后预告了Caffeine Cache的相关内容。
摘要由CSDN通过智能技术生成

数据回源与回填策略

前面我们介绍过,Guava Cache提供的是一种穿透型缓存模式,当缓存中没有获取到对应记录的时候,支持自动去源端获取数据并回填到缓存中。这里回源获取数据的策略有两种,即CacheLoader方式与Callable方式,两种方式适用于不同的场景,实际使用中可以按需选择。

下面一起看下这两种方式。

CacheLoader

CacheLoader适用于数据加载方式比较固定且统一的场景,在缓存容器创建的时候就需要指定此具体的加载逻辑。常见的使用方式如下:

public LoadingCache<String, User> createUserCache() {
   
    return CacheBuilder.newBuilder()
            .build(new CacheLoader<String, User>() {
   
                @Override
                public User load(String key) throws Exception {
   
                    System.out.println(key + "用户缓存不存在,尝试CacheLoader回源查找并回填...");
                    return userDao.getUser(key);
                }
            });
    }

上述代码中,在使用CacheBuilder创建缓存容器的时候,如果在build()方法中传入一个CacheLoader实现类的方式,则最终创建出来的是一个LoadingCache具体类型的Cache容器:
在这里插入图片描述
默认情况下,我们需要继承CacheLoader类并实现其load抽象方法即可。
在这里插入图片描述
当然,CacheLoader类中还有一些其它的方法,我们也可以选择性的进行覆写来实现自己的自定义诉求。比如我们需要设定refreshAfterWrite来支持定时刷新的时候,就推荐覆写reload方法,提供一个异步数据加载能力,避免数据刷新操作对业务请求造成阻塞。
在这里插入图片描述
另外,有一点需要注意下,如果创建缓存的时候使用refreshAfterWrite指定了需要定时更新缓存数据内容,则必须在创建的时候指定CacheLoader实例,否则执行的时候会报错。因为在执行refresh操作的时候,必须调用CacheLoader对象的reload方法去执行数据的回源操作。

在这里插入图片描述

Callable

与CacheLoader不同,Callable的方式在每次数据获取请求中进行指定,可以在不同的调用场景中,分别指定并使用不同的数据获取策略,更加的灵活。

public static void main(String[] args) {
   
    try {
   
        GuavaCacheService cacheService = new GuavaCacheService();
        Cache<String, User> cache = cacheService.createCache();
        String userId = "123";
        // 获取userId, 获取不到的时候执行Callable进行回源
        User user = cache.get(userId, () -> cacheService.queryUserFromDb(userId));
        System.out.println("get对应用户信息:" + user);
    } catch (Exception e) {
   
        e.printStackTrace();
    }
}

通过提供Callable实现函数并作为参数传递的方式,可以根据业务的需要,在不同业务调用场景下,指定使用不同的Callable回源策略。

回源查询
前面介绍了基于CacheLoader方式自动回源,或者基于Callable方式显式回源的两种策略。但是实际使用缓存的时候,并非是缓存中获取不到数据时就一定需要去执行回源操作。

比如下面这个场景:

用户论坛中维护了个黑名单列表,每次用户登录的时候,需要先判断下是否在黑名单中,如果在则禁止登录。

因为论坛中黑名单用户占整体用户量的比重是极少的,也就是几乎绝大部分登录的时候去查询缓存都是无法命中黑名单缓存的。这种时候如果每次查询缓存中没有的情况下都去执行回源操作,那几乎等同于每次请求都需要去访问一次DB了,这显然是不合理的。

所以,为了支持这种场景的访问,Guava cache也提供了一种不会触发回源操作的访问方式。如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值