Caffeine使用指南

Caffeine基于java8的高性能,接近最优的缓存库。Caffeine提供的内存缓存使用参考Google guava的API。Caffeine是基于Google guava和 ConcurrentLinkedHashMap的设计经验上改进的成果。

Caffeine可以通过建造者模式灵活的组合以下特性:

通过异步自动加载实体到缓存中
基于大小的回收策略
基于时间的回收策略
自动刷新
key自动封装虚引用
value自动封装弱引用或软引用
实体过期或被删除的通知
写入外部资源
统计累计访问缓存

加载策略

Caffeine提供了3种加载策略:手动加载,同步加载,异步加载
手动加载

Cache<Key, Graph> cache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(10_000)
.build();
// 检索一个entry,如果没有则为null
Graph graph = cache.getIfPresent(key);
// 检索一个entry,如果entry为null,则通过key创建一个entry并加入缓存
graph = cache.get(key, k -> createExpensiveGraph(key));
// 插入或更新一个实体
cache.put(key, graph);
// 移除一个实体
cache.invalidate(key);

1
2
3
4
5
6
7
8
9
10
11
12

同步加载

构造Cache时候,build方法传入一个CacheLoader实现类。实现load方法,通过key加载value。

LoadingCache<Key, Graph> cache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(key -> createExpensiveGraph(key));
//如果缓存种没有对应的value,通过createExpensiveGraph方法加载
Graph graph = cache.get(key);

Map<Key, Graph> graphs = cache.getAll(keys);

1
2
3
4
5
6
7
8

异步加载

AsyncLoadingCache<Key, Graph> cache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.buildAsync((key, executor) -> createExpensiveGraphAsync(key, executor));
CompletableFuture graph = cache.get(key);
CompletableFuture<Map<Key, Graph>> graphs = cache.getAll(keys);

1
2
3
4
5
6

AsyncLoadingCache 是 LoadingCache 的变体, 可以异步计算实体在一个线程池(Executor)上并且返回 CompletableFuture.
回收策略

Caffeine提供了3种回收策略:基于大小回收,基于时间回收,基于引用回收
基于大小回收

// 基于实体数量淘汰实体
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.maximumSize(10_000)
.build(key -> createExpensiveGraph(key));

// 通过权重来计算,每个实体都有不同的权重,总权重到达最高时淘汰实体。
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.maximumWeight(10_000)
.weigher((Key key, Graph graph) -> graph.vertices().size())
.build(key -> createExpensiveGraph(key));

1
2
3
4
5
6
7
8
9
10

到达最大大小时淘汰最近最少使用的实体
基于时间回收

实体被访问之后,在实体被读或被写后的一段时间后过期

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.expireAfterAccess(5, TimeUnit.MINUTES)
.build(key -> createExpensiveGraph(key));

1
2
3基于写之后,在实体被写入后的一段时间后过期

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(key -> createExpensiveGraph(key));

1
2
3自定义策略Expiry,可以自定义在实体被读,被更新,被创建后的时间过期。

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.expireAfter(new Expiry<Key, Graph>() {
public long expireAfterCreate(Key key, Graph graph, long currentTime) {
// Use wall clock time, rather than nanotime, if from an external resource
long seconds = graph.creationDate().plusHours(5)
.minus(System.currentTimeMillis(), MILLIS)
.toEpochSecond();
return TimeUnit.SECONDS.toNanos(seconds);
}
public long expireAfterUpdate(Key key, Graph graph,
long currentTime, long currentDuration) {
return currentDuration;
}
public long expireAfterRead(Key key, Graph graph,
long currentTime, long currentDuration) {
return currentDuration;
}
})
.build(key -> createExpensiveGraph(key));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

基于引用回收

java种有四种引用:强引用,软引用,弱引用和虚引用,caffeine可以将值封装成弱引用或软引用。
软引用:如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。
弱引用:弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.weakKeys()
.weakValues()
.build(key -> createExpensiveGraph(key));

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.softValues()
.build(key -> createExpensiveGraph(key));

1
2
3
4
5
6
7
8
9
10

自动刷新

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.maximumSize(10_000)
.refreshAfterWrite(1, TimeUnit.MINUTES)
.build(key -> createExpensiveGraph(key));

1
2
3
4

在写后的持续时间过后,调用createExpensiveGraph刷新
移除通知

Cache<Key, Graph> graphs = Caffeine.newBuilder()
.removalListener((Key key, Graph graph, RemovalCause cause) ->
System.out.printf(“Key %s was removed (%s)%n”, key, cause))
.build();

1
2
3
4

通过removalListener添加实体移除监听器
写到外部存储

通过CacheWriter 可以将缓存回写的外部存储中。

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
.writer(new CacheWriter<Key, Graph>() {
@Override public void write(Key key, Graph graph) {
// 写入到外部存储或二级缓存
}
@Override public void delete(Key key, Graph graph, RemovalCause cause) {
// 删除外部存储或者二级缓存
}
})
.build(key -> createExpensiveGraph(key));

1
2
3
4
5
6
7
8
9
10
11

使用场景

缓存同步数据库
多级缓存同步

注意,CacheWriter不能与弱键或AsyncLoadingCache一起使用
统计缓存使用情况

Cache<Key, Graph> graphs = Caffeine.newBuilder()
.maximumSize(10_000)
.recordStats()
.build();

1
2
3
4

通过使用Caffeine.recordStats(), 可以转化成一个统计的集合. 通过 Cache.stats() 返回一个CacheStats。CacheStats提供以下统计方法

hitRate(): 返回缓存命中率
evictionCount(): 缓存回收数量
averageLoadPenalty(): 加载新值的平均时间

Caffeine使用指南相关推荐

  1. Caffeine入门

    Caffeine使用指南 Caffeine基于java8的高性能,接近最优的缓存库.Caffeine提供的内存缓存使用参考Google guava的API.Caffeine是基于Google guav ...

  2. (很全面)SpringBoot 使用 Caffeine 本地缓存

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 作者:超级小豆丁 http://www.mydlq.club/article/56/ 目录 ...

  3. 程序员学习指南_程序员管理压力指南

    程序员学习指南 by Daragh Byrne 达拉·伯恩(Daragh Byrne) 程序员管理压力指南 (A programmer's guide to managing stress) 我几乎一 ...

  4. 前端通用SEO技术优化指南

    本文字数:2585字 预计阅读时间:8分钟 背景 近期团队开发的新产品的官网上线了,随之而来的问题就是如何让网站更快更好的传播出去.当然SEO就是最常见的手段之一,对官网的SEO工作有利于产品的网络传 ...

  5. 极客假日礼物指南(我们喜欢的极客资料)

    Welcome to the very first How-To Geek Holiday Gift Guide, where we've put together a list of our abs ...

  6. IHERB上待产包准备指南-妈妈篇

    准妈妈怀孕期间会出现很多皮肤问题,比如皮肤长斑,黑色素沉积,脸色暗黄,颈纹加深,皮肤干燥或者皮肤出油等,因此这个特殊时期的皮肤护理是非常关键的.这时准妈妈们要放弃自己平时用的护肤品了,安全性很重要.准 ...

  7. Spring Boot参考指南

    Spring Boot参考指南 作者 菲利普·韦伯,戴夫 Syer,约什 长,斯特凡 尼科尔,罗布 绞车,安迪·威尔金森,马塞尔 Overdijk,基督教 杜普伊斯,塞巴斯蒂安·德勒兹,迈克尔·西蒙斯 ...

  8. 缓存之王Caffeine Cache,性能比Guava更强,命中率更高!

    点击上方"服务端思维",选择"设为星标" 回复"669"获取独家整理的精选资料集 回复"加群"加入全国服务端高端社群「后 ...

  9. Spring指南之使用Spring缓存数据(Spring Framework官方文档之缓存抽象详解)

    1.请参见官方文档Spring指南之使用 Spring 缓存数据 2.请参见Spring官方文档之缓存抽象 3.参见github代码 文章目录 一.简介 二.你将创造什么(What You Will ...

最新文章

  1. 怎么选?阿里P7 or 副处级干部?
  2. 编程语言python特点-Python程序特点
  3. Fragment专辑(三):Fragment的添加(add)和替换(replace)的不同
  4. 购买过php,【已解决】PHP项目需求:用户购买商品时,给上级发送一条通知(无限级下级会员)...
  5. Fedora 快捷键
  6. word2vec训练词向量 python_使用Gensim word2vector训练词向量
  7. python编码在哪里看_python怎么换编码
  8. linux内核C -- 第10课:内联函数探究
  9. 【C语言】数组 - 冒泡排序法
  10. Java自学指南一、找一个开始并能坚持下去的理由
  11. c语言 计算整数n的阶乘之和,c语言求阶乘之和是多少
  12. 服务器如何连接多屏显示器,电脑设置两个显示器多屏显示
  13. 本人亲身实践,不要给软屏幕笔记本贴钢化膜(T_T)
  14. CTFshow-萌新
  15. 服务器启动时创建文件夹,技术|entr:文件更改时重新运行构建
  16. 《《《翻译》》》Navigation Through Cluttered Environments
  17. 经纬财富:乌海黄金白银暂缓跌势
  18. 时钟源系统(时统系统)GPTP对自动驾驶的重要性
  19. NBA表格_1970到2019年NBA各赛季总冠军获得球队汇总!让你印象深刻的赛季
  20. 我是Papi酱,一个集才华与美貌于一身的过气网红

热门文章

  1. 故乡,生活十多年的地方
  2. Linux系统信号定义
  3. 用Java实现递归与分治系列(二)
  4. 用树莓派(等)为 USB Midi 键盘增添连接方式
  5. jQuery File Upload
  6. 正大国际期货:做期货主帐户有什么风险?
  7. SCCB协议介绍与应用和OV7670摄像头的寄存器配置
  8. C语言数据结构一元多项式
  9. cisco3560及二层交换机配置vlan及常用命令
  10. VOIP信号传输过程