目的
使用caffeine
+redis
构建二级缓存,并且可以同步过期时间。
-
redis
可以视为集中式外部缓存,缓存及ttl只需设置一次; -
caffeine
集成在分布式程序内部,需要通过懒加载同步redis
缓存及ttl.
代码实现
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Expiry;
import java.util.concurrent.TimeUnit;
import lombok.Getter;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.redisson.api.RedissonClient;
@Getter
public class CacheHelper {
private Cache<String, Object> localCache;
private RedissonClient redissonClient;
public CacheHelper(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
initLocalCache();
}
private void initLocalCache() {
this.localCache = Caffeine.newBuilder().expireAfter(new Expiry<String, Object>() {
@Override
public long expireAfterCreate(@NonNull String key, @NonNull Object value, long currentTime) {
// query ttl by redisson, you can use another redis client instead
long ttlMillis = redissonClient.getBucket(key).remainTimeToLive();
return TimeUnit.MILLISECONDS.toNanos(Math.max(ttlMillis, 0));
}
@Override
public long expireAfterUpdate(@NonNull String key, @NonNull Object value, long currentTime,
@NonNegative long currentDuration) {
return currentDuration;
}
@Override
public long expireAfterRead(@NonNull String key, @NonNull Object value, long currentTime,
@NonNegative long currentDuration) {
return currentDuration;
}
}).build(key -> redissonClient.getBucket(key).get());
}
}