提示:本网站现在为维护调试状态

Redis 缓存设计模式

Choyeon
Choyeon
2026年8月28日 1 分钟阅读 320 阅读
475 字 1,595 字符 更新于 2026年11月8日
Redis 缓存设计模式
目录

缓存是提升系统性能最有效的手段之一,但选择错误的模式或缺乏异常处理反而会引入不一致和稳定性问题。

Cache-Aside 旁路缓存

读时先查缓存,miss 再查 DB 并回填;写时先更新 DB 再删除缓存(推荐删除而非更新,避免并发脏读)。实现简单但需处理击穿穿透雪崩。

import redis, json, hashlib, random
from functools import wraps
from typing import Callable, Any

r = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True)

def cache_aside(ttl: int = 300, jitter: float = 0.1):
    def decorator(fn: Callable):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            k = f"c:{fn.__name__}:{hashlib.md5(str((args,sorted(kwargs.items()))).encode()).hexdigest()[:10]}"
            cached = r.get(k)
            if cached == "__NULL__": return None
            if cached is not None: return json.loads(cached)
            result = fn(*args, **kwargs)
            t = int(ttl * (1 + random.uniform(-jitter, jitter)))
            if result is None: r.setex(k, max(30, t//5), "__NULL__")
            else: r.setex(k, max(1, t), json.dumps(result, default=str))
            return result
        return wrapper
    return decorator

def write_through(key: str, value: Any, db_update: Callable, ttl: int = 300):
    pipe = r.pipeline()
    pipe.setex(key, ttl, json.dumps(value, default=str))
    try:
        db_update(value)
        pipe.execute()
    except Exception:
        pipe.reset(); raise

bg_queue: list[tuple[str, Any]] = []
def write_behind(key: str, value: Any):
    bg_queue.append((key, value))
    r.setex(key, 60, json.dumps(value, default=str))

def flush_bg(db_update: Callable):
    while bg_queue:
        k, v = bg_queue.pop(0)
        try: db_update(k, v)
        except Exception: bg_queue.insert(0, (k, v)); break

@cache_aside(ttl=600)
def get_product(pid: int):
    return {"id": pid, "name": f"Product {pid}", "price": 99.99}

Write-Through / Write-Behind

Write-Through 写缓存同时同步写 DB,原子性强但延迟高。Write-Behind 先写缓存,异步批量刷 DB,吞吐高但存在短窗口数据丢失风险。

模式 一致性 读性能 写性能 适用场景
Cache-Aside 最终一致 高 中 读多写少
Write-Through 强一致 高 低延迟差 一致性要求高
Write-Behind 弱一致/最终 高 极高 日志/统计写多读少
Refresh-Ahead 最终一致 极高 中 热点Key可预测

最佳实践

设置随机 TTL ±10% 防止雪崩,热点 Key 加互斥锁或逻辑过期防击穿,不存在的数据写空值防穿透。

X微博Telegram

本文作者

投票

你最希望 Rosetta 优先加入哪项功能?

社区投票(演示数据,可后台删除)

评论 (5)

0 / 3000
云端漫步
云端漫步cloud-notes.cloud2026年9月20日

补充一点:实际使用中如果遇到 MySQL 的 8 小时超时问题,可以在连接串里加 autoReconnect=true 参数,虽然官方不推荐但挺好用的。

机器学习萌新
机器学习萌新2026年9月20日

受益匪浅,感谢大佬分享!

游戏策划阿哲
游戏策划阿哲2026年9月20日

有个小问题:你文中用的是 @Async 注解,这个默认用的是 SimpleAsyncTaskExecutor,生产环境是不是最好手动配一个线程池?

奶茶味程序媛
奶茶味程序媛2026年9月20日

好文!但是我觉得第三部分那个消息队列选型对比表有点偏向 Kafka 了,RocketMQ 在事务消息这块其实优势挺明显的。

独立开发者阿明
独立开发者阿明aming.dev2026年9月20日

太及时了,正好项目里要上 Redis 集群,照着来一遍省了好多事,谢谢!

相关文章

Go 语言并发:goroutine + channel + sync.WaitGroup

Go 语言并发:goroutine + channel + sync.WaitGroup

完整掌握 Go 原生并发模型:轻量级协程 goroutine(KB 级开销)、CSP 模式 channel 通信、sync.WaitGroup 生命周期管理,加上 Context 取消、工作池模式,以及 goroutine 泄漏防护。

1 分钟阅读
Node.js 性能诊断:clinic.js + flamegraph

Node.js 性能诊断:clinic.js + flamegraph

系统学习 Node.js 性能定位工具链:clinic.js 一键生成分析报告,解读火焰图热点函数、阻塞事件循环的同步代码、内存泄漏对象栈,精准定位 CPU/内存瓶颈。

1 分钟阅读
Python 并发:asyncio vs ThreadPool vs ProcessPool

Python 并发:asyncio vs ThreadPool vs ProcessPool

深度对比 Python 三大并发模型:GIL 限制下的线程池(IO 密集)、进程池(绕 GIL 适合 CPU 密集)、asyncio 协程(超高并发 IO)。从原理/性能/复杂度四维度给出选型决策树。

1 分钟阅读
CQRS + Event Sourcing 架构模式解析

CQRS + Event Sourcing 架构模式解析

透彻解析两种高复杂度分布式架构模式:CQRS 读写模型分离实现查询极致性能、Event Sourcing 以事件作为唯一真相源实现全量审计与时间回溯,讨论一致性/快照/幂等难点与反模式。

1 分钟阅读
Rust 所有权与借用机制:彻底理解生命周期

Rust 所有权与借用机制:彻底理解生命周期

系统攻克 Rust 最独特概念:所有权规则、可变/不可变借用约束、引用生命周期标注。通过编译错误示例 + 修复方案,彻底掌握借用检查器思维方式,写出安全零抽象开销的系统代码。

1 分钟阅读
测试金字塔:单元/集成/E2E 测试比例与落地

测试金字塔:单元/集成/E2E 测试比例与落地

系统解析测试金字塔架构:从底层单元测试(大量快速、Mock 隔离依赖)、中层集成测试(服务/数据库/消息协作真实交互)、顶层 E2E 测试(真实用户路径少量精测)的推荐比例 70% / 20% / 10%,附项目覆盖率指标与落地实践。

1 分钟阅读