那些年我们一起追过的缓存写法(一)
那些年我们一起追过的缓存写法(一)在编程的世界里缓存就像是一个神奇的魔法盒子——它能让你曾经计算过的结果迅速重现避免重复劳动。从初学时的简单字典到后来复杂的多级缓存我们走过的每一步都充满了探索的乐趣。今天就让我们一起回顾那些年我们一起追过的缓存写法从最基础的概念讲起逐步走向更高级的用法。## 什么是缓存为什么需要它想象一下你每次去图书馆找一本特定的小说都要从头翻遍所有书架。这显然很浪费时间。如果你把这本书放在书桌上下次想看时直接拿起来是不是快多了这就是缓存的核心思想把频繁访问的数据存放在高速存取的地方。在程序中缓存可以- 减少重复计算提升性能- 降低数据库或API的负载- 改善用户体验## 初阶用字典实现最简单的缓存最朴素的缓存方式就是使用一个字典或哈希表来存储键值对。我们用Python写一个简单的缓存函数python# 一个简单的计算器带缓存功能def fib_with_cache(n, cache{}): 计算斐波那契数列的第n项并使用字典缓存中间结果。 if n in cache: # 如果结果已在缓存中 return cache[n] # 直接返回 if n 2: result n else: result fib_with_cache(n-1, cache) fib_with_cache(n-2, cache) cache[n] result # 将计算结果存入缓存 return result# 测试print(fib_with_cache(10)) # 输出55print(fib_with_cache(100)) # 即便计算大数也不卡顿这段代码利用了Python中默认参数只初始化一次的特性使得cache字典在多次调用间共享。它的优点是非常简单缺点也很明显缓存会无限增长而且不支持并发安全。## 中阶使用functools.lru_cache自动管理Python标准库为我们提供了更优雅的解决方案functools.lru_cache装饰器。它自动实现了**最近最少使用LRU**淘汰策略当缓存满了会移除最久未使用的数据。pythonfrom functools import lru_cachelru_cache(maxsize128) # 最多缓存128个结果def fib_lru(n): 使用lru_cache装饰的斐波那契函数。 当缓存满时自动淘汰最久未使用的条目。 if n 2: return n return fib_lru(n-1) fib_lru(n-2)# 测试print(fib_lru(10)) # 55print(fib_lru(100)) # 354224848179261915075瞬间返回print(fib_lru.cache_info()) # 查看缓存状态CacheInfo(hits?, misses?, maxsize128, currsize?)lru_cache的优点- 自动管理缓存大小- 支持统计信息命中率等- 线程安全在Python 3.8中- 可设置typedTrue区分不同类型参数但注意lru_cache仅适用于**纯函数**无副作用输出仅由输入决定并且参数必须是可哈希的。## 进阶自定义TTL生存时间缓存有时候我们需要缓存数据在特定时间后自动失效比如从数据库读取的用户信息5分钟后应该刷新。lru_cache不支持TTL我们可以自己构建一个带过期时间的缓存pythonimport timefrom functools import wrapsdef ttl_cache(ttl_seconds300, maxsize128): “” 自定义TTL缓存装饰器。 - ttl_seconds: 缓存生存时间秒 - maxsize: 最大缓存条目数 “” def decorator(func): cache {} # 使用有序字典维护访问顺序便于LRU淘汰 from collections import OrderedDict wraps(func) def wrapper(*args, **kwargs): # 生成缓存键注意这里简化了kwargs的处理 key (args, tuple(sorted(kwargs.items()))) now time.time() # 检查缓存是否有效 if key in cache: value, timestamp cache[key] if now - timestamp ttl_seconds: # 缓存命中且未过期更新访问顺序 cache.move_to_end(key) return value else: # 缓存过期删除旧条目 del cache[key] # 计算新值 result func(*args, **kwargs) # 如果超出最大容量淘汰最久未使用的条目 if len(cache) maxsize: cache.popitem(lastFalse) # 移除最早访问的条目 cache[key] (result, now) return result return wrapper return decorator# 使用示例ttl_cache(ttl_seconds10, maxsize5)def get_user_info(user_id): “” 模拟从数据库获取用户信息耗时操作 “” print(f正在从数据库获取用户 {user_id} 的信息…“) time.sleep(2) # 模拟耗时 return {“id”: user_id, “name”: fUser_{user_id}”, “time”: time.time()}# 测试print(get_user_info(1)) # 第一次等待2秒print(get_user_info(1)) # 第二次立即返回缓存命中time.sleep(11) # 等待超过TTLprint(get_user_info(1)) # 第三次缓存过期重新计算这个自定义缓存虽然功能强大但仍有不足**不支持并发安全**、**未处理异常情况**、**键生成不够健壮**。在实际项目中建议使用成熟的第三方库如cachetools。## 高级用法多级缓存策略在大型系统中单层缓存往往不够用。常见的是**多级缓存**例如- **一级缓存**本地进程内缓存如lru_cache速度最快但容量有限- **二级缓存**分布式缓存如Redis速度较快容量大- **三级缓存**数据库或外部API速度最慢一个简化的多级缓存实现pythonimport redisfrom functools import lru_cacheclass MultiLevelCache: “” 多级缓存示例本地LRU Redis “” definit(self, local_size100, redis_clientNone): self.local_cache lru_cache(maxsizelocal_size)(self._get_from_redis) self.redis redis_client or redis.Redis(host‘localhost’, port6379, db0) def _get_from_redis(self, key): “”“从Redis获取数据如果不存在则返回None”“” return self.redis.get(key) def get(self, key): “”“获取数据先查本地缓存再查Redis”“” result self.local_cache(key) # 先查本地 if result is None: # 本地没有从数据库加载实际中需实现 result self._load_from_db(key) # 回填到Redis self.redis.set(key, result, ex300) # 5分钟过期 # 清除本地缓存强制下次重新加载 self.local_cache.cache_clear() return result defload_from_db(self, key): “”“模拟从数据库加载”“” print(f从数据库加载 {key}) return fdata{key}这种设计结合了本地缓存的快速和Redis的容量优势是生产环境中的常见模式。## 总结从最简单的字典缓存到标准库的lru_cache再到自定义TTL缓存最后到多级缓存架构我们见证了缓存写法的进化之路。每一步都体现了对性能、内存管理、并发安全的追求。关键要点1. 缓存不是银弹——需要权衡内存占用与性能提升2. 选择合适的淘汰策略LRU、LFU、TTL等3. 注意缓存的失效与更新缓存穿透、雪崩、击穿4. 生产环境中优先使用成熟库cachetools、redis-py等下期预告我们将深入探讨缓存的常见陷阱——缓存穿透、雪崩和击穿以及如何用布隆过滤器、互斥锁等技巧来应对。敬请期待—缓存的世界深似海但每一次优化都让我们离完美更近一步。希望这篇文章能帮助你回顾那些年我们一起追过的缓存写法也为未来的探索埋下种子。

相关新闻

HarmonyOS开发实战:笔友-Hamock 组件 Mock 在页面单元测试中的应用

HarmonyOS开发实战:笔友-Hamock 组件 Mock 在页面单元测试中的应用

前言 在 ArkUI 应用中,组件 Mock 是页面单元测试的关键技术。xiexin 在 oh-package.json5 中引入了 ohos/hamock 工具,用于在测试中替换真实组件,验证组件交互逻辑。 本文将以 AddPenPalPage.ets 和 CommonComponents.ets 为蓝本&#xff0…

2026/7/26 21:16:07 阅读更多 →
screen_capture_lite常见问题解答:解决跨平台捕获的8大痛点

screen_capture_lite常见问题解答:解决跨平台捕获的8大痛点

screen_capture_lite常见问题解答:解决跨平台捕获的8大痛点 【免费下载链接】screen_capture_lite cross platform screen/window capturing library 项目地址: https://gitcode.com/gh_mirrors/sc/screen_capture_lite screen_capture_lite是一款强大的跨平…

2026/7/26 21:16:07 阅读更多 →
C++项目CI/CD中静态与动态代码质量分析的整合实践

C++项目CI/CD中静态与动态代码质量分析的整合实践

1. 项目概述:为什么C项目的CI/CD必须整合代码质量分析?在C开发领域,尤其是涉及系统底层、游戏引擎、高频交易或嵌入式等对性能和稳定性要求极高的场景,代码质量从来都不是一个“锦上添花”的选项,而是项目存续的生命线…

2026/7/26 21:16:07 阅读更多 →

最新新闻

基于JavaWeb的美食交流宣传系统的设计与实现开题报告

基于JavaWeb的美食交流宣传系统的设计与实现开题报告

、项目研究背景与意义 随着互联网与新媒体技术的快速普及,美食文化传播、美食探店分享、大众美食交流已成为网民日常娱乐生活的重要组成部分。传统的美食宣传模式多依赖线下门店推广、短视频零散分享、纸质美食杂志等形式,存在传播碎片化、内容留存率低、…

2026/7/26 21:41:20 阅读更多 →
深入解析CC13x2/CC26x2无线MCU:电源管理与Cortex-M4F内核实战

深入解析CC13x2/CC26x2无线MCU:电源管理与Cortex-M4F内核实战

1. 项目概述:深入无线MCU的“心脏”与“能量站”在嵌入式无线设备的世界里,尤其是那些对功耗和性能都极为苛刻的物联网终端,我们常常面临一个核心矛盾:如何让设备在保持强大计算和无线通信能力的同时,还能在单颗纽扣电…

2026/7/26 21:41:20 阅读更多 →
WandEnhancer:为WeMod用户提供高级体验的终极增强工具

WandEnhancer:为WeMod用户提供高级体验的终极增强工具

WandEnhancer:为WeMod用户提供高级体验的终极增强工具 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/GitHub_Trending/we/Wand-Enhancer WandEnhancer是一款专为WeMod游戏…

2026/7/26 21:41:20 阅读更多 →
DSSM模型解析:电商搜索语义匹配实战指南

DSSM模型解析:电商搜索语义匹配实战指南

1. 从零理解DSSM的核心价值第一次听说DSSM(Deep Structured Semantic Model)时,我正为一个电商搜索项目头疼——用户搜索"苹果手机充电器"时,系统总把水果苹果和充电宝排在前面。传统文本匹配就像拿着放大镜对比字符&am…

2026/7/26 21:41:20 阅读更多 →
深入解析Arm Cortex-M4F TPIU寄存器:从原理到实战配置

深入解析Arm Cortex-M4F TPIU寄存器:从原理到实战配置

1. 项目概述:为什么需要深入理解TPIU寄存器在嵌入式开发,尤其是基于Arm Cortex-M4F这类高性能MCU的项目中,调试的深度和效率直接决定了解决复杂问题的能力。当你的代码在RTOS环境下出现偶发性死锁,或者某个中断服务程序的执行时间…

2026/7/26 21:41:19 阅读更多 →
AI驱动企业数字化转型:技术痛点与实施框架

AI驱动企业数字化转型:技术痛点与实施框架

1. 技术变革的临界点:从传统到智能的跨越2025年注定成为技术发展史上的分水岭。作为一名见证过多次技术迭代的从业者,我清晰地感受到传统技术范式正在经历前所未有的重构。过去一年里,我参与了37个企业数字化转型项目,其中89%的案…

2026/7/26 21:40:19 阅读更多 →

日新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

月新闻