快速上手 Caffeine:Java 缓存库初学者指南

一、背景

  1. 简介: Caffeine 是一个高性能的 Java 缓存库,旨在为现代应用程序提供快速、高效的缓存解决方案。它由 Google Guava Cache 的创始人之一开发,具备基于时间的过期、基于大小的回收、异步加载、统计信息等多种特性。Caffeine的性能有多么强大呢?以下是官方给出的基准测试图(在该基准测试中,8 个线程同时从配置了最大容量的高速缓存中读取数据。)

在这里插入图片描述

  1. 应用场景

    • Web 应用的会话管理:缓存用户会话信息,以减少数据库查询次数。

    • 配置和数据的本地缓存:缓存配置文件或常用数据,以减少对外部系统的访问延迟。

    • 计算结果缓存:缓存频繁计算的结果,如搜索结果、数据分析结果等,以提高响应速度。

    • 分布式系统中的中间缓存层:在分布式系统中使用本地缓存,减轻数据库或其他后端服务的负载。

  2. 示例代码

    • 导入依赖:
    <dependency>
        <groupId>com.github.ben-manes.caffeine</groupId>
        <artifactId>caffeine</artifactId>
    </dependency>
    
    • 测试代码:
    import com.github.benmanes.caffeine.cache.Cache;
    import com.github.benmanes.caffeine.cache.Caffeine;
    
    import java.util.concurrent.TimeUnit;
    
    public class CaffeineExample {
    
        public static void main(String[] args) {
            // 创建一个Caffeine缓存
            Cache<String, String> cache = Caffeine.newBuilder()
                    .maximumSize(100) // 设置缓存的最大条目数
                    .expireAfterWrite(10, TimeUnit.MINUTES) // 设置写入后10分钟过期
                    .build();
    
            // 放入一个条目
            cache.put("key1", "value1");
    
            // 获取一个条目
            String value = cache.getIfPresent("key1");
            System.out.println("key1: " + value);
    
            // 使用计算函数获取一个条目(如果不存在,则计算并放入缓存)
            value = cache.get("key2", k -> "computedValue");
            System.out.println("key2: " + value);
    
            // 删除一个条目
            cache.invalidate("key1");
        }
    }
    
    

二 、Caffeine 常见缓存淘汰策略

缓存淘汰策略用于在缓存空间有限时,确保频繁访问和最近使用的条目得以保留,同时移除不常用的条目,从而优化内存使用和缓存命中率。

  1. 基于容量的清理
    • Caffeine 允许配置缓存的最大容量,当缓存容量达到上限时,Caffeine 会根据其内部的策略自动清理一些缓存项。
    • 这种策略通常采用窗口TinyLFU算法(Least Frequently Used)来判断条目的使用频率。
// 创建一个最大容量为3的缓存
Cache<String, String> cache = Caffeine.newBuilder()
    .maximumSize(3)
    .build();
  1. 基于时间的清理
    1. TTL(Time to Live):在缓存项创建的时指定一段时间,到期进行自动清理。
    2. TTR(Time to Refresh):在缓存项最后一次访问一段时间后进行自动清理。
// 创建一个写入后2秒过期的缓存
Cache<String, String> cache = Caffeine.newBuilder()
    .expireAfterWrite(2, TimeUnit.SECONDS)
    .build();
// 创建一个访问后2秒过期的缓存
Cache<String, String> cache = Caffeine.newBuilder()
    .expireAfterAccess(2, TimeUnit.SECONDS)
    .build();
  1. 显式移除:可以通过API手动移除缓存中的条目。
// 创建一个缓存
Cache<String, String> cache = Caffeine.newBuilder()
    .maximumSize(100)
    .build();

// 放入一个条目
cache.put("key1", "value1");

// 缓存应该包含条目
System.out.println("Initial Cache: " + cache.getIfPresent("key1"));

// 显式移除条目
cache.invalidate("key1");

// 缓存应该不包含条目
System.out.println("After Removal: " + cache.getIfPresent("key1"));

三、常见API

  1. 创建缓存:

    • Caffeine.newBuilder(): 创建一个新的缓存构建器,可以设置各种缓存参数。
  2. 缓存配置:

    • maximumSize(long size): 设置缓存的最大容量,超过这个容量后会触发缓存回收。

    • expireAfterWrite(long duration, TimeUnit unit): 设置缓存项在写入后多长时间过期。

    • expireAfterAccess(long duration, TimeUnit unit): 设置缓存项在访问后多长时间过期。

  3. 缓存操作:

    • put(K key, V value): 将一个键值对放入缓存。

    • getIfPresent(Object key): 获取缓存中指定键的值,如果不存在则返回null

    • get(K key, Function<? super K, ? extends V> mappingFunction): 获取缓存中指定键的值,如果不存在则使用提供的映射函数计算值并放入缓存。

    • invalidate(Object key): 移除缓存中指定键的条目。

    • invalidateAll(Iterable<?> keys): 移除缓存中指定键集合的所有条目。

    • invalidateAll(): 移除缓存中的所有条目。

四、Redis 与 Caffeine

1. 适用 Caffeine 的场景

  1. 本地缓存需求:适合数据量小且仅需本地缓存的场景,如单节点应用或无需共享缓存的多节点应用。
  2. 高性能和低延迟要求:适用于需要极低访问延迟和高吞吐量的应用,因为Caffeine运行在本地内存中,访问速度快。
  3. 简化架构:无需引入额外组件,只需在应用中引入相应库即可,简化系统架构。
  4. 不需要持久化:适用于无需持久化的缓存数据,如缓存计算结果或短时间内频繁访问的数据。

2. 适用 Redis 的场景

  1. 分布式缓存需求:适合多个应用服务器共享缓存,作为独立的分布式缓存系统,支持多个客户端访问。
  2. 大数据量缓存:适用于缓存数据量超出单个服务器内存限制的场景,通过分布式特性将数据分布到多个节点。
  3. 持久化需求:需要持久化缓存数据以防数据丢失,提供数据持久化功能确保数据可靠性。
  4. 丰富的数据结构:支持多种数据结构,如字符串、哈希、列表、集合和有序集合,适用于复杂缓存场景。

3. 综合比较

  1. 访问速度:Caffeine 本地缓存访问速度更快,但 Redis 可通过分片和集群提高读写性能。
  2. 数据共享:Redis 适合需要多个应用实例共享数据的场景,而 Caffeine 仅适用于单实例缓存。
  3. 数据持久化:Redis 提供持久化机制,适合需要持久保存缓存数据的应用。Caffeine 不支持持久化。
  4. 运维复杂度:Caffeine 易于使用和集成,无需额外运维工作。Redis 需要独立部署和运维。
  • 36
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值