|
|
@@ -19,9 +19,12 @@ public class RetrieverService {
|
|
|
private final StringRedisTemplate redis;
|
|
|
private final boolean redisAvailable;
|
|
|
|
|
|
- // Embedding 缓存 key 前缀 + TTL(7 天)
|
|
|
+ // Embedding 缓存 key 前缀 + TTL(7 天,续期 3 次后不再续)
|
|
|
private static final String EMBED_CACHE_PREFIX = "aiyaodian:embed:";
|
|
|
+ private static final String EMBED_RENEW_PREFIX = "aiyaodian:embed:renew:";
|
|
|
private static final Duration EMBED_CACHE_TTL = Duration.ofDays(7);
|
|
|
+ private static final Duration EMBED_MAX_TTL = Duration.ofDays(30);
|
|
|
+ private static final int MAX_RENEWALS = 3;
|
|
|
|
|
|
private static final List<String> NEGATION_PATTERNS = List.of(
|
|
|
"不是", "没有", "并非", "算不上", "怎么会是", "不可能", "不会",
|
|
|
@@ -85,7 +88,20 @@ public class RetrieverService {
|
|
|
String key = cacheKey(query);
|
|
|
try {
|
|
|
String cached = redis.opsForValue().get(key);
|
|
|
- if (cached != null) return decodeVec(cached);
|
|
|
+ if (cached != null) {
|
|
|
+ // 滑动续期:最多续 3 次,总时长不超 30 天
|
|
|
+ var renewKey = EMBED_RENEW_PREFIX + key.substring(EMBED_CACHE_PREFIX.length());
|
|
|
+ try {
|
|
|
+ var ops = redis.opsForValue();
|
|
|
+ var cntVal = ops.get(renewKey);
|
|
|
+ int renewals = cntVal != null ? Integer.parseInt(cntVal) : 0;
|
|
|
+ if (renewals < MAX_RENEWALS) {
|
|
|
+ redis.expire(key, EMBED_CACHE_TTL);
|
|
|
+ ops.set(renewKey, String.valueOf(renewals + 1), EMBED_MAX_TTL);
|
|
|
+ }
|
|
|
+ } catch (Exception ignored) {}
|
|
|
+ return decodeVec(cached);
|
|
|
+ }
|
|
|
} catch (DataAccessException ignored) {
|
|
|
// Redis 异常时降级到远程调用
|
|
|
}
|