springboot进阶

Caffeine的基础使用

2020-09-27  本文已影响0人  农民工进城

一、简介

Caffeine是基于Java 8的高性能接近最佳的缓存工具库。Caffeine使用Google Guava启发的API提供内存缓存。所以它的使用成本较低,跟Guava的API大致一致。

它主要有以下几个功能:

二、常见API

Cache分为LoadingCache(同步缓存),AsyncLoadingCache(异步缓存)。

        <dependency>
            <groupId>com.github.benmanes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
            <version>2.8.5</version>
        </dependency>
2.1 人工加载策略
Cache<Object, Object> cache = Caffeine.newBuilder()
        .expireAfterWrite(1, TimeUnit.SECONDS)
            .expireAfterAccess(1, TimeUnit.SECONDS)
        .maximumSize(10)//最大条数
        .build();//定义cache
User user1=(User) cache.get(id, v-> userDao.getOne(id));//如果cache不存在,查询数据库
2.2 自动加载同步
  LoadingCache<String, User> userDaoCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.SECONDS)
            .expireAfterAccess(1, TimeUnit.SECONDS).maximumSize(10).build(key -> userDao.getOne(key))
    User user = userDaoCache.get("1");
2.3 自动加载异步
  AsyncLoadingCache<String, User> asynUserDaoCache = Caffeine.newBuilder()
            .expireAfterWrite(1, TimeUnit.SECONDS).expireAfterAccess(1, TimeUnit.SECONDS).maximumSize(10)
            .buildAsync(key -> userDao.getOne(key));
  User user = asynUserDaoCache.get("1").get();

三、其他API

3.1 统计缓存信息
Cache<Object, Object> cacheStats = Caffeine.newBuilder()
            .expireAfterWrite(1000, TimeUnit.SECONDS)
            .expireAfterAccess(1000, TimeUnit.SECONDS)
             .recordStats()//记录统计信息
            .weakKeys()//key弱引用
            .weakValues()//value 弱引用
            .maximumSize(10).build()
CacheStats stats = cacheStats.stats();//获取统计信息
3.2 CacheWriter
    LoadingCache<String, User> cacheWriter = Caffeine.newBuilder().expireAfterAccess(3, TimeUnit.SECONDS)
            .writer(new CacheWriter<String, User>() {
                @Override
                public void write(String id, User user) {
                    System.out.println("***写入***" + id);//当混存数据时,调用此方案
                }

                @Override
                public void delete(String id, User user, RemovalCause cause) {
                    System.out.println("***delete***" + id);//当手动删除数据时,调用此方法
                }
            }).build(id -> userDao.getOne(id));
3.3RemovalListener监听(手动删除)
        LoadingCache<String, User> removalListener = Caffeine.newBuilder()
            .removalListener(new RemovalListener<String, User>() {

                @Override
                public void onRemoval(@Nullable String key, @Nullable User value, @NonNull RemovalCause cause) {
                    System.out.println(key + "*****" + value);
                }
            }).expireAfterAccess(3, TimeUnit.SECONDS).build(id -> userDao.getOne(id));

四、缓存淘汰机制

常见缓存机制有:LRU(Least Recently Used)最近最少使用跟LFU(Least Frequently Used)最不经常使用。

4.1 LRU
4.2 LFU
4.3 W-TinyLFU

为了弥补LRU跟LFU的不足与缺点,产生了W-TinyLFU算法。
W-TinyLFU算法大致思想:缓存有窗口缓存跟主缓存两部门组成。窗口缓存没有淘汰策略,从而解决了突发流量时不达标不缓存的问题。而TinyLFU维护了近期访问记录的频率信息,作为一个过滤器,当新记录来时,只有满足TinyLFU要求的记录才可以被插入缓存,也因此解决了缓存超过容量轻易淘汰问题。

caffeine采用的就是这种策略。对算法的具体过程感兴趣,可以自行网上找资料了解下。

五、参数总结

maximumSize:设置缓存最大条目数,超过条目则触发回收 
maximumWeight:设置缓存最大权重,设置权重是通过weigher方法, 需要注意的是权重也是限制缓存大小的参数,并不会影响缓存淘汰策略,也不能和maximumSize方法一起使用。 
weakKeys:将key设置为弱引用,在GC时可以直接淘汰
weakValues:将value设置为弱引用,在GC时可以直接淘汰
softValues:将value设置为软引用,在内存溢出前可以直接淘汰
expireAfterWrite:写入后隔段时间过期
expireAfterAccess:访问后隔断时间过期
refreshAfterWrite:写入后隔断时间刷新
removalListener:缓存淘汰监听器,配置监听器后,每个条目淘汰时都会调用该监听器
writer:writer监听器其实提供了两个监听,一个是缓存写入或更新是的write,一个是缓存淘汰时的delete,每个条目淘汰时都会调用该监听器

上一篇 下一篇

猜你喜欢

热点阅读