Skip to content

缓存失效通知

缓存失效通知是 Symphra Cache 提供的高级功能,用于在数据更新时主动清除或更新缓存中的过期数据,确保数据一致性。

概述

缓存失效通过以下方式确保数据一致性:

  • 主动失效:在数据更新时主动清除相关缓存
  • 模式匹配:基于键模式批量清除缓存
  • 依赖管理:清除主键时同时清除相关依赖键
  • 延迟失效:在指定时间后自动清除缓存

基础用法

键级失效

from symphra_cache import CacheManager, MemoryBackend
from symphra_cache.invalidation import CacheInvalidator

# 创建缓存管理器
cache = CacheManager(backend=MemoryBackend())

# 创建失效器
invalidator = CacheInvalidator(cache)

# 失效特定键
keys_to_invalidate = ["user:123", "user:456", "user:789"]
await invalidator.invalidate_keys(keys_to_invalidate)

模式匹配失效

# 失效所有用户数据
await invalidator.invalidate_pattern("user:*")

# 失效特定前缀的数据
await invalidator.invalidate_prefix("session:")

# 使用通配符模式
await invalidator.invalidate_pattern("product:*:price")

条件失效

# 基于条件失效数据
def should_invalidate(key, value):
    """检查是否应该失效该键值对"""
    return "temp" in key or value is None

await invalidator.invalidate_by_condition(should_invalidate)

高级功能

缓存组管理

# 创建用户组失效器
user_group = invalidator.create_cache_group_invalidator("user:")

# 失效整个用户组
await user_group.invalidate_all()

# 失效用户组中的特定模式
await user_group.invalidate_pattern("*:profile")

# 失效用户组中的特定键
await user_group.invalidate_keys(["profile", "settings"])

依赖失效

# 定义依赖解析函数
def resolve_user_dependencies(user_keys):
    """解析用户相关的所有依赖键"""
    dependencies = []
    for key in user_keys:
        if key.startswith("user:profile:"):
            user_id = key.split(":")[-1]
            dependencies.extend([
                f"user:posts:{user_id}",
                f"user:followers:{user_id}",
                f"user:following:{user_id}",
                f"stats:user:{user_id}",
            ])
    return dependencies

# 失效用户及其所有依赖
primary_keys = ["user:profile:123"]
await invalidator.invalidate_with_dependencies(
    primary_keys,
    resolve_user_dependencies
)

延迟失效

# 2秒后失效特定键
keys_to_delay = ["temp:data1", "temp:data2"]
task = await invalidator.schedule_invalidation(keys_to_delay, delay=2.0)

# 等待延迟失效完成
await task

条件延迟失效

# 当条件满足时才失效
def check_condition():
    return some_global_flag is True

task = await invalidator.conditional_invalidation(
    condition=check_condition,
    keys=["conditional:key"],
    check_interval=1.0  # 每秒检查一次
)

批量操作优化

大数据集失效

# 大量键的分批失效
all_keys = [f"key:{i}" for i in range(10000)]

# 使用自定义批量大小
invalidator = CacheInvalidator(cache, batch_size=500)
await invalidator.invalidate_keys(all_keys)

性能监控

# 监控失效操作性能
start_time = time.time()
invalidated_count = await invalidator.invalidate_pattern("temp:*")
elapsed = time.time() - start_time

print(f"失效 {invalidated_count} 个键,耗时 {elapsed:.3f} 秒")

统计和监控

失效统计

stats = invalidator.get_invalidation_stats()
print(f"总操作数: {stats['total_operations']}")
print(f"总失效键数: {stats['total_invalidated_keys']}")
print(f"最后操作时间: {stats['last_invalidation_time']}")
print(f"最后操作详情: {stats['last_operation']}")

失效历史

# 获取最近10次失效操作历史
history = invalidator.get_invalidation_history(limit=10)
for i, record in enumerate(history, 1):
    print(f"操作 {i}:")
    print(f"  时间: {record['timestamp']}")
    print(f"  方法: {record['method']}")
    print(f"  详情: {record['details']}")
    print(f"  失效键数: {record['invalidated_count']}")

实际应用场景

用户数据更新

async def update_user_profile(user_id, profile_data):
    """更新用户资料并失效相关缓存"""
    # 1. 更新数据库
    await database.update_user(user_id, profile_data)

    # 2. 失效用户相关缓存
    invalidator = CacheInvalidator(cache)

    # 失效用户资料缓存
    await invalidator.invalidate_keys([f"user:profile:{user_id}"])

    # 失效用户统计缓存
    await invalidator.invalidate_pattern(f"user:stats:{user_id}:*")

    # 失效用户动态缓存
    await invalidator.invalidate_pattern(f"feed:user:{user_id}:*")

# 使用示例
await update_user_profile(123, {"name": "New Name", "avatar": "new_avatar.jpg"})

商品价格更新

async def update_product_price(product_id, new_price):
    """更新商品价格并失效相关缓存"""
    # 1. 更新数据库
    await database.update_price(product_id, new_price)

    # 2. 失效价格相关缓存
    invalidator = CacheInvalidator(cache)

    # 失效商品价格缓存
    await invalidator.invalidate_keys([f"product:price:{product_id}"])

    # 失效商品详情缓存
    await invalidator.invalidate_keys([f"product:detail:{product_id}"])

    # 失效分类价格缓存
    category = await database.get_product_category(product_id)
    await invalidator.invalidate_pattern(f"category:{category}:products:*")

# 使用示例
await update_product_price(101, 2999.99)

配置更新

async def update_app_config(config_key, config_value):
    """更新应用配置并失效相关缓存"""
    # 1. 更新配置
    await config_service.update(config_key, config_value)

    # 2. 失效配置缓存
    invalidator = CacheInvalidator(cache)

    # 失效特定配置
    await invalidator.invalidate_keys([f"config:{config_key}"])

    # 失效所有配置缓存
    await invalidator.invalidate_prefix("config:")

    # 失效依赖该配置的功能缓存
    await invalidator.invalidate_pattern("feature:*")

# 使用示例
await update_app_config("maintenance_mode", True)

会话管理

async def logout_user(user_id):
    """用户登出并清理会话缓存"""
    # 1. 清理会话状态
    await session_service.clear_session(user_id)

    # 2. 失会话缓存
    invalidator = CacheInvalidator(cache)

    # 失效用户会话
    await invalidator.invalidate_pattern(f"session:user:{user_id}:*")

    # 失效用户权限缓存
    await invalidator.invalidate_keys([f"permissions:user:{user_id}"])

    # 失效用户状态缓存
    await invalidator.invalidate_keys([f"status:user:{user_id}"])

# 使用示例
await logout_user(123)

最佳实践

1. 失效策略

  • 及时失效:数据更新后立即失效相关缓存
  • 精确失效:只失效必要的键,避免过度清除
  • 批量失效:大量键使用批量操作提高效率
  • 异步失效:非关键失效使用异步操作避免阻塞

2. 依赖管理

  • 建立依赖图:明确数据间的依赖关系
  • 级联失效:主数据变更时自动失效依赖数据
  • 避免循环:防止依赖关系形成循环

3. 性能优化

  • 批量操作:使用批量失效减少网络往返
  • 模式匹配:利用模式匹配提高失效效率
  • 延迟失效:非紧急失效可以延迟执行

4. 错误处理

  • 优雅降级:失效失败时记录错误但不中断业务
  • 重试机制:重要失效操作实现重试逻辑
  • 监控告警:监控失效操作的成功率

5. 分布式考虑

  • 一致性:在分布式环境中确保所有实例的缓存一致性
  • 通知机制:使用消息队列通知其他实例
  • 版本控制:使用版本号避免并发更新问题

错误处理

异常捕获

async def safe_invalidate(invalidator, keys):
    """安全失效,包含错误处理"""
    try:
        return await invalidator.invalidate_keys(keys)
    except Exception as e:
        print(f"失效失败: {e}")
        # 记录错误日志
        # 实施降级策略
        return 0

降级策略

async def invalidate_with_fallback(invalidator, keys):
    """带降级策略的失效"""
    try:
        return await invalidator.invalidate_keys(keys)
    except Exception:
        # 降级:使用单个键失效
        invalidated = 0
        for key in keys:
            try:
                if await invalidator.invalidate_keys([key]):
                    invalidated += 1
            except Exception:
                continue
        return invalidated

性能监控

失效性能指标

class InvalidationMonitor:
    def __init__(self, invalidator):
        self.invalidator = invalidator
        self.metrics = {}

    async def monitored_invalidate(self, method, *args, **kwargs):
        """监控失效操作性能"""
        start_time = time.time()

        if method == "keys":
            result = await self.invalidator.invalidate_keys(*args, **kwargs)
        elif method == "pattern":
            result = await self.invalidator.invalidate_pattern(*args, **kwargs)
        # ... 其他方法

        elapsed = time.time() - start_time

        # 记录性能指标
        self.metrics[method] = {
            "last_duration": elapsed,
            "last_result": result,
            "avg_duration": self._calculate_avg(method, elapsed)
        }

        return result

通过合理使用缓存失效通知功能,可以确保缓存数据的一致性,避免脏数据问题,提升系统的可靠性和用户体验。