You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于时间戳条件删除Caffeine缓存中的指定条目?

基于时间戳批量删除Caffeine缓存的无遍历方案

有两种无需全量遍历缓存条目的实现方案,具体如下:

方案一:版本标记懒淘汰(性能最优)

核心思路是给每个缓存条目增加写入版本标记,全局维护最小生效版本,无需主动清理旧条目,读请求时自动判定是否失效。

实现步骤

  1. 定义缓存值包装类,额外存储写入时间戳/版本号:
// 也可以直接用写入时间戳作为版本号
record CacheWrapper<V>(long writeTimestamp, V value) {}
  1. 全局维护原子类型的最小生效时间戳:
// 初始值可设为0,代表所有时间写入的条目都生效
private final AtomicLong minValidWriteTime = new AtomicLong(0);
  1. 写入缓存时带上当前时间戳(建议使用System.nanoTime(),和Caffeine内部时间逻辑一致,避免系统时间调整导致的异常):
cache.put(key, new CacheWrapper<>(System.nanoTime(), value));
  1. 读取缓存时做有效性校验,失效条目自动触发重新加载:
public V getCache(String key) {
    CacheWrapper<V> wrapper = cache.getIfPresent(key);
    // 条目不存在或者写入时间早于最小生效时间,都视为缓存失效
    if (wrapper == null || wrapper.writeTimestamp() < minValidWriteTime.get()) {
        V newValue = loadFromDataSource(key);
        cache.put(key, new CacheWrapper<>(System.nanoTime(), newValue));
        return newValue;
    }
    return wrapper.value();
}
  1. 需要淘汰所有T2之前的条目时,仅需修改全局最小生效时间:
// 无任何遍历操作,时间复杂度O(1)
minValidWriteTime.set(T2);

适用场景

适合对性能要求极高,可接受少量未访问的旧条目暂时占用内存的场景,旧条目后续会被Caffeine自带的LRU/LFU驱逐策略自动清理。

方案二:时间分片缓存

核心思路是将缓存按时间窗口拆分为多个独立的Caffeine实例,淘汰指定时间之前的条目时直接销毁对应时间分片的缓存实例即可。

实现逻辑

  • 按固定时间粒度(比如1分钟、5分钟)拆分缓存,每个时间窗口对应一个独立的Caffeine实例
  • 写入时根据当前时间选择对应分片写入
  • 读取时遍历所有未过期的分片查询数据
  • 需要淘汰T2之前的所有条目时,直接销毁所有时间早于T2的分片实例即可,无需遍历条目

适用场景

适合需要精准控制内存占用,淘汰时间窗口固定的场景。


内容的提问来源于stack exchange,提问作者Boss Man

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 03:36:02