Caffeine 本地缓存框架原理及用法总结

简介: Caffeine 本地缓存框架原理及用法总结

常用缓存算法:
First in first out(FIFO)队列:先进先出,最先进入的数据最先被淘汰,缺点:忽略数据访问频率和访问次数。
Least recently used (LRU):最近最少使用算法,即:如果数据最近被访问过,那么将来被访问的概率也更大。LRU使用一个链表来实现,新插入的数据会被添加到链表的头部;当缓存命中后,就会再将数据移动到链表的头部;如果链表满的时候,就会将链表尾部的数据丢弃。
【命中率】如果存在热点数据,LRU的效率很好,然而对于偶发性的、周期性的批量操作就会导致LRU命中率急剧下降,缓存污染情况比较严重。
【复杂度】实现简单。
【代价】访问数据命中时需要遍历链表,并找到命中的数据块索引位置,然后再将数据移动到链表头部。

LRU.png

Least frequently used (LFU):最近经常使用算法,即:如果数据过去被访问多次,那么将来被访问的频率也更高。

Caffeine缓存算法:它结合了LRU和LFU两种算法来管理缓存。

Caffeine数据结构:
Caffeine采用的是readBuffer和writeBuffer。它使用一个Long数组来存储key的访问频率。Long的64位被分为4个段,每个段占16位。首先,根据key算出hash值,使用hash值来计算处于4段中哪个段;其次,计算出4个段的具体位置,并设定当前位置的频率;最终以这4个频率值的最小值来代表该key的访问频率。
ringbuffer默认为16,其数组大小是256,假设引用大小为4字节(ringbuffer中存储的是引用),缓存行大小为64。所以这里每个缓存行只存一个数据,所以cas操作追加16,即数组中每16个元素只有一个有效存储,以空间换时间。

高性能读写操作:
借鉴数据库的WAL思想,读写操作后,将操作记录(判断数据是否过期;统计频率;记录读写统计命中率等)记载到缓冲区,再异步处理,提高了性能。
WAL(Write-Ahead Logging)的核心思想是:在数据写入到数据库之前,先写入到日志.再将日志记录变更到存储器中。

Caffeine缓存的三种回收策略
基于大小(size-based):maximumSize
基于时间(time-based):

     expireAfterAccess 最后一次访问过期计时
     expireAfterWrite  最后一次写入时过期计时

基于引用(reference-based):仅对软引用、弱引用过期处理

使用方法:

// 初始化Caffeine对象
@Bean
public Cache<String, Object> caffeineCacheInstance() {
Cache<String, Object> caffeineCache = Caffeine.newBuilder().initialCapacity(initialCapacity)
// 设置永不过期,默认300年
.expireAfterAccess(Long.MAX_VALUE, TimeUnit.DAYS)
.expireAfterWrite(Long.MAX_VALUE, TimeUnit.DAYS)
// 设置移除监听器
.removalListener(new CacheRemoveListener())
// 不限容量
//.maximumSize(maximumSize)
.build();
return caffeineCache;
}
// 增加处理缓存移除监听器类CacheRemoveListener
public class CacheRemoveListener implements RemovalListener<Object, Object> {
@Override
public void onRemoval(@Nullable Object key, @Nullable Object value, @Null RemovalCause cause) {
// 缓存被回收或过期时处理
if(cause.equals(RemovalCause.COLLECTED) || cause.equals(RemovalCause.EXPIRED)) {
// 当对象被回收或过期时需要处理
return;
}
// 缓存更新时处理
if(cause.equals(RemovalCause.REPLACED)) {
logger.warn("Caffeine " + cause + " OK, key-value, " + key + ":" + value);
}
}
}

用法:在具体的@Service类中引用
@Autowired
private Cache<String, Object> caffeineCacheInstance;
存放:caffeineCacheInstance.put(key, value);
读取:Object value = caffeineCacheInstance.getIfPresent(key);

使用时需要注意点:
(1)初始化本地缓存数据
(2)容量评估,不要超出内存容量
(3)缓存命中率
(4)垃圾回收
(5)性能测试

相关名词解释:
驱逐(eviction):由于满足了某种驱逐策略,后台自动进行的删除操作
无效(invalidation):表示由调用方手动删除缓存
移除(removal):监听驱逐或无效操作的监听器

相关文章
|
1月前
|
缓存 算法 Java
Caffeine Cache~高性能 Java 本地缓存之王
Caffeine Cache~高性能 Java 本地缓存之王
58 1
|
2月前
|
存储 缓存 关系型数据库
InnoDB 引擎底层存储和缓存原理
InnoDB 引擎底层存储和缓存原理
|
2月前
|
存储 缓存 前端开发
浏览器缓存工作原理是什么?
浏览器缓存工作原理是什么?
|
1月前
|
存储 缓存 Java
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
|
3月前
|
缓存 Go API
Go 实现一个支持多种过期、淘汰机制的本地缓存的核心原理
本文旨在探讨实现一个支持多种 过期、淘汰 机制的 go 本地缓存的核心原理,我将重点讲解如何支持多样化的过期和淘汰策略。
72 0
|
3月前
|
缓存 NoSQL Java
Spring Cache 缓存原理与 Redis 实践
Spring Cache 缓存原理与 Redis 实践
159 0
|
29天前
|
存储 XML 缓存
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南(一)
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南
66 0
|
29天前
|
缓存 应用服务中间件 数据库
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
34 1
|
1月前
|
缓存 Java 数据库连接
mybatis 数据库缓存的原理
MyBatis 是一个流行的 Java 持久层框架,它封装了 JDBC,使数据库交互变得更简单、直观。MyBatis 支持两级缓存:一级缓存(Local Cache)和二级缓存(Global Cache),通过这两级缓存可以有效地减少数据库的访问次数,提高应用性能。
282 1
|
9月前
|
SQL 存储 缓存
MyBatis缓存原理
MyBatis缓存原理
228 1

热门文章

最新文章