本地缓存GuavaCache

来源:互联网 发布:unity3d 视频教程 编辑:程序博客网 时间:2024/06/05 22:43

为什么使用本地缓存?

最近在项目中需要使用一个员工组件,通过一个员工接口做模糊查询,通过员工id得到员工姓名头型等信息,可是对于员工的编辑和展示用到的地方特别多,即项目中会频繁的调用一个接口。这个问题走了一些弯路,比如在表中增加展示字段,数据返回前调员工接口做转换,或者列表展示时由前端并发处理,最后证明这些办法都不是很好。最后想到了本地缓存。

在系统中,一些访问量大但是数据量小、与业务无关的缓存适合采用本地缓存。为什么不采用分布式缓存呢?分布式集群缓存的构建、维护成本较高,不太适合做紧急的项目。而本地缓存访问速度快,使用方便,劣势是数据更新的一致性难以保证,使用范围有所限制,但是这种场景下的使用足够了。

在GuavaCache中缓存的容器被定义为接口Cache<K, V>的实现类,这些实现类都是线程安全的,因此通常定义为一个单例

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()        .maximumSize(1000)        .expireAfterWrite(10, TimeUnit.MINUTES)        .removalListener(MY_LISTENER)        .build(            new CacheLoader<Key, Graph>() {                public Graph load(Key key) throws AnyException {                    return createExpensiveGraph(key);                }        });

以上是官方给的demo

通常来说,Guava Cache适用于:
你愿意消耗一些内存空间来提升速度。
你预料到某些键会被查询一次以上。
缓存中存放的数据总量不会超出内存容量。(Guava Cache是单个应用运行时的本地缓存。它不把数据存放到文件或外部服务器。如果这不符合你的需求,请尝试Memcached这类工具)
如果你的场景符合上述的每一条,Guava Cache就适合你。

回收策略

常用定时回收:

expireAfterAccess(long, TimeUnit):缓存项在给定时间内没有被读/写访问,则回收。请注意这种缓存的回收顺序和基于大小回收一样。expireAfterWrite(long, TimeUnit):缓存项在给定时间内没有被写访问(创建或覆盖),则回收。如果认为缓存数据总是在固定时候后变得陈旧不可用,这种回收方式是可取的。

与spring结合使用

@Servicepublic class GuavaCache {    public LoadingCache<String, User> userCache;    @Autowired    private UserDao userDao;    @PostConstruct    public void init() {         userCache = CacheBuilder.newBuilder()                .maximumSize(1000)                .expireAfterWrite(10, TimeUnit.MINUTES)                .build(                        new CacheLoader<String, User>() {                            public User load(String key) throws Exception {                                return userDao.findUserByMobile(key);                            }                        });    }}