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):监听驱逐或无效操作的监听器

相关文章
|
13天前
|
缓存 NoSQL Java
SpringBoot的三种缓存技术(Spring Cache、Layering Cache 框架、Alibaba JetCache 框架)
Spring Cache 是 Spring 提供的简易缓存方案,支持本地与 Redis 缓存。通过添加 `spring-boot-starter-data-redis` 和 `spring-boot-starter-cache` 依赖,并使用 `@EnableCaching` 开启缓存功能。JetCache 由阿里开源,功能更丰富,支持多级缓存和异步 API,通过引入 `jetcache-starter-redis` 依赖并配置 YAML 文件启用。Layering Cache 则提供分层缓存机制,需引入 `layering-cache-starter` 依赖并使用特定注解实现缓存逻辑。
SpringBoot的三种缓存技术(Spring Cache、Layering Cache 框架、Alibaba JetCache 框架)
|
19天前
|
开发框架 缓存 NoSQL
基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理
基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理
|
20天前
|
存储 缓存 开发框架
Winform框架中窗体基类的用户身份信息的缓存和提取
Winform框架中窗体基类的用户身份信息的缓存和提取
|
22天前
|
存储 缓存 监控
性能利器Caffeine缓存全面指南
通过以上指南,您应该能够有效利用Caffeine缓存来优化您的Java应用程序。Caffeine的强大功能和灵活性,使它成为提升应用性能的理想选择。
47 4
|
5天前
|
存储 缓存 Java
Java本地高性能缓存实践问题之定义Caffeine的缓存的问题如何解决
Java本地高性能缓存实践问题之定义Caffeine的缓存的问题如何解决
|
5天前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot引入Caffeine作为缓存库的问题如何解决
|
5天前
|
缓存 Java Spring
Java本地高性能缓存实践问题之的Caffeine设置刷新机制问题如何解决
Java本地高性能缓存实践问题之的Caffeine设置刷新机制问题如何解决
|
5天前
|
缓存 Java
Java本地高性能缓存实践问题之Caffeine缓存库中时间设置的问题如何解决
Java本地高性能缓存实践问题之Caffeine缓存库中时间设置的问题如何解决
|
1月前
|
存储 缓存 NoSQL
GuavaCache、EVCache、Tair、Aerospike 缓存框架比较
**摘要:** Guava Cache、EVCache、Tair 和 Aerospike 是不同的缓存解决方案。Guava Cache 是轻量级的本地缓存,适用于Java应用,提供丰富的配置选项和自动加载功能。EVCache 基于 Memcached,适合分布式场景,高并发访问。Tair,阿里巴巴的分布式缓存,支持多种数据结构,适用于大规模系统。Aerospike 是高性能NoSQL数据库,结合缓存和持久化,适用于低延迟和大数据量的场景。选择时要考虑应用场景、性能需求和数据规模。
GuavaCache、EVCache、Tair、Aerospike 缓存框架比较