microwind/ai-skills/cache-invalidation

Claude Code and agent skill by microwind/ai-skills

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

当设计缓存失效时,分析失效模式,优化数据一致性,解决缓存雪崩。验证缓存架构,设计失效策略,和最佳实践。

Install

npx vskill@latest install microwind/ai-skills/cache-invalidation

SKILL.md

缓存失效策略技能

概述

缓存失效是缓存系统中的关键问题,决定了数据的一致性和系统的可用性。不当的失效策略会导致数据不一致、缓存雪崩、性能下降。选择合适的失效策略对系统性能和数据一致性至关重要。

核心原则: 好的失效策略应该保证数据一致性、避免缓存雪崩、提高命中率、减少性能影响。坏的失效策略会导致数据不一致或系统不稳定。

何时使用

始终:

  • 设计缓存系统时
  • 处理数据一致性时
  • 优化缓存性能时
  • 解决缓存雪崩时
  • 实现分布式缓存时
  • 处理热点数据时

触发短语:

  • "如何设计缓存失效?"
  • "缓存一致性问题"
  • "避免缓存雪崩"
  • "缓存失效策略选择"
  • "分布式缓存失效"
  • "热点数据处理"

缓存失效策略技能功能

失效模式
  • 主动失效
  • 被动失效
  • 定时失效
  • 版本失效
  • 事件驱动失效
一致性保证
  • 强一致性
  • 最终一致性
  • 写入失效
  • 读取失效
  • 双写一致性
性能优化
  • 批量失效
  • 异步失效
  • 分级失效
  • 预热策略
  • 防雪崩机制
监控管理
  • 命中率监控
  • 失效率统计
  • 性能指标
  • 告警机制
  • 容量规划

常见问题

一致性问题
  • 问题: 缓存与数据库不一致
  • 原因: 失效策略不当,并发更新
  • 解决: 使用合适的失效策略,保证一致性
  • 问题: 分布式缓存不一致
  • 原因: 网络延迟,失效传播失败
  • 解决: 使用分布式失效机制
性能问题
  • 问题: 缓存雪崩
  • 原因: 大量缓存同时失效
  • 解决: 使用随机过期时间,错峰失效
  • 问题: 缓存穿透
  • 原因: 查询不存在的数据
  • 解决: 缓存空值,使用布隆过滤器
可用性问题
  • 问题: 缓存故障影响系统
  • 原因: 过度依赖缓存
  • 解决: 降级策略,熔断机制

代码示例

基础缓存失效实现
java
// 缓存管理器
@Component
public class CacheManager {
private final Map<String, CacheEntry> cache = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public CacheManager() {
// 定期清理过期缓存
scheduler.scheduleAtFixedRate(this::cleanExpiredEntries, 1, 1, TimeUnit.MINUTES);
}
// 设置缓存
public void put(String key, Object value, long ttlMillis) {
CacheEntry entry = new CacheEntry(value, System.currentTimeMillis() + ttlMillis);
cache.put(key, entry);
}
// 获取缓存
public Object get(String key) {
CacheEntry entry = cache.get(key);
if (entry == null) {
return null;
}
if (entry.isExpired()) {
cache.remove(key);
return null;
}
return entry.getValue();
}
// 主动失效
public void invalidate(String key) {
cache.remove(key);
}
// 批量失效
public void invalidateBatch(Set<String> keys) {
keys.forEach(cache::remove);
}
// 模式匹配失效
public void invalidateByPattern(String pattern) {
cache.keySet().removeIf(key -> matchesPattern(key, pattern));
}
// 清理过期条目
private void cleanExpiredEntries() {
long currentTime = System.currentTimeMillis();
cache.entrySet().removeIf(entry -> entry.getValue().isExpired(currentTime));
}
private boolean matchesPattern(String key, String pattern) {
// 简单的通配符匹配
return key.matches(pattern.replace("*", ".*"));
}
@PreDestroy
public void destroy() {
scheduler.shutdown();
}
private static class CacheEntry {
private final Object value;
private final long expireTime;
public CacheEntry(Object value, long expireTime) {
this.value = value;
this.expireTime = expireTime;
}
public Object getValue() {
return value;
}
public boolean isExpired() {
return isExpired(System.currentTimeMillis());
}
public boolean isExpired(long currentTime) {
return currentTime > expireTime;
}
}
}
// 缓存失效策略
public enum InvalidationStrategy {
IMMEDIATE, // 立即失效
DELAYED, // 延迟失效
BATCH, // 批量失效
EVENT_DRIVEN // 事件驱动
}
// 缓存失效服务
@Service
public class CacheInvalidationService {
private final CacheManager cacheManager;
private final ApplicationEventPublisher eventPublisher;
private final Queue<InvalidationTask> invalidationQueue = new ConcurrentLinkedQueue<>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
public CacheInvalidationService(CacheManager cacheManager,
ApplicationEventPublisher eventPublisher) {
this.cacheManager = cacheManager;
this.eventPublisher = eventPublisher;
// 启动批量失效任务
scheduler.scheduleAtFixedRate(this::processBatchInvalidation, 100, 100, TimeUnit.MILLISECONDS);
}
// 立即失效
public void invalidateImmediately(String key) {
cacheManager.invalidate(key);
eventPublisher.publishEvent(new CacheInvalidatedEvent(key, InvalidationStrategy.IMMEDIATE));
}
// 延迟失效
public void invalidateDelayed(String key, long delayMillis) {
scheduler.schedule(() -> {
cacheManager.invalidate(key);
eventPublisher.publishEvent(new CacheInvalidatedEvent(key, InvalidationStrategy.DELAYED));
}, delayMillis, TimeUnit.MILLISECONDS);
}
// 批量失效
public void invalidateBatch(Set<String> keys) {
keys.forEach(key -> invalidationQueue.offer(new InvalidationTask(key, System.currentTimeMillis())));
}
// 模式失效
public void invalidateByPattern(String pattern) {
cacheManager.invalidateByPattern(pattern);
eventPublisher.publishEvent(new PatternInvalidationEvent(pattern));
}
// 处理批量失效
private void processBatchInvalidation() {
List<InvalidationTask> batch = new ArrayList<>();
// 收集批量任务
InvalidationTask task;
while ((task = invalidationQueue.poll()) != null && batch.size() < 100) {
batch.add(task);
}
if (!batch.isEmpty()) {
Set<String> keys = batch.stream()
.map(InvalidationTask::getKey)
.collect(Collectors.toSet());
cacheManager.invalidateBatch(keys);
eventPublisher.publishEvent(new BatchInvalidationEvent(keys));
}
}
@PreDestroy
public void destroy() {
scheduler.shutdown();
}
private static class InvalidationTask {
private final String key;
private final long timestamp;
public InvalidationTask(String key, long timestamp) {
this.key = key;
this.timestamp = timestamp;
}
public String getKey() {
return key;
}
public long getTimestamp() {
return timestamp;
}
}
}
Redis分布式缓存失效
java
// Redis缓存管理器
@Component
public class RedisCacheManager {
private final RedisTemplate<String, Object> redisTemplate;
private final StringRedisTemplate stringRedisTemplate;
public RedisCacheManager(RedisTemplate<String, Object> redisTemplate,
StringRedisTemplate stringRedisTemplate) {
this.redisTemplate = redisTemplate;
this.stringRedisTemplate = stringRedisTemplate;
}
// 设置缓存
public void set(String key, Object value, Duration ttl) {
redisTemplate.opsForValue().set(key, value, ttl);
}
// 获取缓存
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
// 删除缓存
public void delete(String key) {
redisTemplate.delete(key);
}
// 批量删除
public void delete(Collection<String> keys) {
redisTemplate.delete(keys);
}
// 模式删除
public void deleteByPattern(String pattern) {
Set<String> keys = stringRedisTemplate.keys(pattern);
if (!keys.isEmpty()) {
redisTemplate.delete(keys);
}
}
// 检查是否存在
public boolean exists(String key) {
return Boolean.TRUE.equals(redisTemplate.hasKey(key));
}
// 设置过期时间
public void expire(String key, Duration ttl) {
redisTemplate.expire(key, ttl);
}
// 获取剩余过期时间
public Duration getTtl(String key) {
Long ttl = redisTemplate.getExpire(key);
return ttl != null && ttl > 0 ? Duration.ofSeconds(ttl) : Duration.ZERO;
}
}
// 分布式缓存失效服务
@Service
public class DistributedCacheInvalidationService {
private final RedisCacheManager redisCacheManager;
private final ApplicationEventPublisher eventPublisher;
private final RedisTemplate<String, Object> redisTemplate;
@Value("${cache.invalidation.channel:cache:invalidation}")
private String invalidationChannel;
public DistributedCacheInvalidationService(RedisCacheManager redisCacheManager,
ApplicationEventPublisher eventPublisher,
RedisTemplate<String, Object> redisTemplate) {
this.redisCacheManager = redisCacheManager;
this.eventPublisher = eventPublisher;
this.redisTemplate = redisTemplate;
}
// 本地失效并广播
public void invalidateAndBroadcast(String key) {
// 本地失效
redisCacheManager.delete(key);
// 广播失效事件
InvalidationMessage message = new InvalidationMessage(key, InvalidationType.SINGLE, System.currentTimeMillis());
redisTemplate.convertAndSend(invalidationChannel, message);
// 发布本地事件
eventPublisher.publishEvent(new CacheInvalidatedEvent(key, InvalidationStrategy.IMMEDIATE));
}
// 批量失效并广播
public void invalidateBatchAndBroadcast(Set<String> keys) {
// 本地失效
redisCacheManager.delete(keys);
// 广播失效事件
InvalidationMessage message = new InvalidationMessage(keys, InvalidationType.BATCH, System.currentTimeMillis());
redisTemplate.convertAndSend(invalidationChannel, message);
// 发布本地事件
eventPublisher.publishEvent(new BatchInvalidationEvent(keys));
}
// 模式失效并广播
public void invalidatePatternAndBroadcast(String pattern) {
// 本地失效
redisCacheManager.deleteByPattern(pattern);
// 广播失效事件
InvalidationMessage message = new InvalidationMessage(pattern, InvalidationType.PATTERN, System.currentTimeMillis());
redisTemplate.convertAndSend(invalidationChannel, message);
// 发布本地事件
eventPublisher.publishEvent(new PatternInvalidationEvent(pattern));
}
// 监听失效消息
@RedisMessageListener(topic = "${cache.invalidation.channel:cache:invalidation}")
public void handleInvalidationMessage(InvalidationMessage message) {
switch (message.getType()) {
case SINGLE:
redisCacheManager.delete(message.getKey());
break;
case BATCH:
redisCacheManager.delete(message.getKeys());
break;
case PATTERN:
redisCacheManager.deleteByPattern(message.getPattern());
break;
}
// 发布本地事件
eventPublisher.publishEvent(new RemoteInvalidationEvent(message));
}
// 失效消息
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class InvalidationMessage implements Serializable {
private String key;
private Set<String> keys;
private String pattern;
private InvalidationType type;
private long timestamp;
// 单个key构造
public InvalidationMessage(String key, InvalidationType type, long timestamp) {
this.key = key;
this.type = type;
this.timestamp = timestamp;
}
// 批量keys构造
public InvalidationMessage(Set<String> keys, InvalidationType type, long timestamp) {
this.keys = keys;
this.type = type;
this.timestamp = timestamp;
}
// 模式构造
public InvalidationMessage(String pattern, InvalidationType type, long timestamp) {
this.pattern = pattern;
this.type = type;
this.timestamp = timestamp;
}
}
public enum InvalidationType {
SINGLE, BATCH, PATTERN
}
}

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
51
Repository forks
13
7-day trend score
20

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/microwind/ai-skills/cache-invalidation/badge)](https://verified-skill.com/skills/microwind/ai-skills/cache-invalidation)

Something wrong with this skill or its page? Tell us.