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

Redis 緩存設計模式

Choyeon
Choyeon
2026年8月28日 1 分鐘閱讀 324 閱讀
475 字 1,595 字元 更新於 2026年11月8日
Redis 緩存設計模式
目錄

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 分鐘閱讀