如何基于自定义时间戳实现Apache Ignite缓存条目级过期?
Apache Ignite 条目级过期实现方案
你其实记错了,Apache Ignite完全支持条目级过期,针对你这种值中自带过期时间戳的场景,有以下几种落地实现方式:
1. 自定义过期策略(ExpiryPolicy)
Ignite允许为单个缓存条目指定自定义ExpiryPolicy,可以直接基于你值中的时间戳计算过期时间,利用Ignite原生机制自动清理过期条目。
实现示例:
// 定义你的缓存值对象 class CacheValue { private Set<Boolean> booleanSet; private long expireTimestamp; // 构造器、getter/setter 省略 } // 基于时间戳的自定义过期策略 class TimestampExpiryPolicy implements ExpiryPolicy { @Override public Duration getExpiryForCreation() { return null; // 由自定义逻辑控制过期,此处返回null } @Override public Duration getExpiryForAccess() { return Duration.ZERO; // 访问不续期 } @Override public Duration getExpiryForUpdate() { return Duration.ZERO; // 更新不续期 } @Override public Duration getExpiry(CacheEntry<?, ?> entry) { CacheValue value = (CacheValue) entry.getValue(); if (value == null) return Duration.ZERO; long remainingTime = value.getExpireTimestamp() - System.currentTimeMillis(); return remainingTime > 0 ? Duration.ofMillis(remainingTime) : Duration.ZERO; } } // 存入缓存时绑定自定义策略 IgniteCache<String, CacheValue> cache = ignite.getOrCreateCache("myCache"); CacheValue value = new CacheValue(/* 初始化Boolean集合和过期时间戳 */); cache.put("key1", value, new TimestampExpiryPolicy());
2. 定时扫描清理任务
如果不想依赖Ignite的过期策略,可以用Ignite自带的调度器定期扫描缓存,手动移除过期条目。
实现示例:
Ignite ignite = Ignition.start(); IgniteScheduler scheduler = ignite.scheduler(); // 每分钟执行一次清理任务(可根据需求调整Cron表达式) scheduler.schedule(() -> { IgniteCache<String, CacheValue> cache = ignite.cache("myCache"); long currentTime = System.currentTimeMillis(); // 分页扫描缓存,避免大缓存场景下OOM ScanQuery<String, CacheValue> scanQuery = new ScanQuery<>(); scanQuery.setPageSize(1000); try (QueryCursor<Cache.Entry<String, CacheValue>> cursor = cache.query(scanQuery)) { for (Cache.Entry<String, CacheValue> entry : cursor) { if (entry.getValue().getExpireTimestamp() < currentTime) { cache.remove(entry.getKey()); } } } }, "0 * * * * ?");
3. 访问时自动校验清理
在获取缓存条目时,先检查时间戳是否过期,若过期则原子性移除并返回空,确保用户不会拿到过期数据。可以用CacheEntryProcessor实现:
实现示例:
class ExpiryCheckProcessor implements CacheEntryProcessor<String, CacheValue, CacheValue> { @Override public CacheValue process(MutableEntry<String, CacheValue> entry, Object... args) { CacheValue value = entry.getValue(); if (value == null) return null; if (value.getExpireTimestamp() < System.currentTimeMillis()) { entry.remove(); return null; } return value; } } // 获取条目时自动执行过期校验 CacheValue validValue = cache.invoke("key1", new ExpiryCheckProcessor());
内容的提问来源于stack exchange,提问作者Shreyas Bhandare
相关产品推荐
相关产品推荐

