12-Redis缓存策略:提升API响应速度10倍

23 阅读2分钟

Redis缓存策略:提升API响应速度10倍

前言

合理的缓存策略能显著提升API性能。本文介绍如何使用Redis实现高效的缓存系统。

适合读者: 后端开发者、性能优化工程师


一、Redis配置

# cache.py
import redis.asyncio as redis
import json
from typing import Any, Optional

class RedisCache:
    def __init__(self, url: str = "redis://localhost:6379/0"):
        self.redis = redis.from_url(url, decode_responses=True)
    
    async def get(self, key: str) -> Optional[Any]:
        value = await self.redis.get(key)
        return json.loads(value) if value else None
    
    async def set(self, key: str, value: Any, expire: int = 3600):
        await self.redis.set(key, json.dumps(value), ex=expire)
    
    async def delete(self, key: str):
        await self.redis.delete(key)
    
    async def exists(self, key: str) -> bool:
        return await self.redis.exists(key) > 0

cache = RedisCache()

二、缓存策略

2.1 Cache-Aside模式

async def get_user(user_id: int):
    # 1. 尝试从缓存获取
    cache_key = f"user:{user_id}"
    cached = await cache.get(cache_key)
    if cached:
        return cached
    
    # 2. 缓存未命中,从数据库查询
    user = await db_get_user(user_id)
    if not user:
        return None
    
    # 3. 写入缓存
    await cache.set(cache_key, user, expire=300)
    return user

2.2 Write-Through模式

async def update_user(user_id: int, data: dict):
    # 1. 更新数据库
    user = await db_update_user(user_id, data)
    
    # 2. 同时更新缓存
    cache_key = f"user:{user_id}"
    await cache.set(cache_key, user, expire=300)
    
    return user

2.3 缓存失效策略

async def delete_user(user_id: int):
    # 1. 删除数据库记录
    await db_delete_user(user_id)
    
    # 2. 删除缓存
    await cache.delete(f"user:{user_id}")
    
    # 3. 删除相关缓存
    await cache.delete(f"user:{user_id}:conversations")

三、缓存装饰器

import functools
from typing import Callable

def cached(prefix: str, expire: int = 3600):
    def decorator(func: Callable):
        @functools.wraps(func)
        async def wrapper(*args, **kwargs):
            # 生成缓存键
            cache_key = f"{prefix}:{args}:{kwargs}"
            
            # 尝试获取缓存
            cached_value = await cache.get(cache_key)
            if cached_value is not None:
                return cached_value
            
            # 执行函数
            result = await func(*args, **kwargs)
            
            # 存入缓存
            await cache.set(cache_key, result, expire)
            
            return result
        return wrapper
    return decorator

# 使用示例
@cached(prefix="user", expire=300)
async def get_user_profile(user_id: int):
    return await db.get_user(user_id)

四、缓存预热

async def warm_up_cache():
    """预热热门数据"""
    # 获取热门用户
    hot_users = await db.get_hot_users(limit=100)
    
    for user in hot_users:
        cache_key = f"user:{user.id}"
        await cache.set(cache_key, user, expire=3600)

五、缓存穿透防护

async def get_user_safe(user_id: int):
    cache_key = f"user:{user_id}"
    
    # 检查缓存
    cached = await cache.get(cache_key)
    if cached is not None:
        return cached if cached != "NULL" else None
    
    # 查询数据库
    user = await db_get_user(user_id)
    
    if user:
        await cache.set(cache_key, user, expire=300)
    else:
        # 缓存空值,防止穿透
        await cache.set(cache_key, "NULL", expire=60)
    
    return user

下一篇预告: 《JWT双Token机制实现》