函数缓存 (Function Cache)
版本: v1.1.4+
功能: 为任意异步函数添加缓存能力
📋 目录
概述
函数缓存是 monSQLize v1.1.4 新增的功能,允许你为任意异步函数添加缓存能力,不仅限于数据库查询。
特性
- ✅ 零侵入:通过装饰器模式,不修改原函数
- ✅ 自动序列化:支持复杂参数(对象、数组、Date、ObjectId 等)
- ✅ TTL 过期:灵活的缓存时间控制
- ✅ 并发控制:防止缓存击穿
- ✅ 条件缓存:基于返回值决定是否缓存
- ✅ 命名空间隔离:多模块缓存互不干扰
- ✅ 统计监控:命中率、调用次数等
- ✅ 复用基础设施:自动继承 monSQLize 的缓存配置(本地/Redis/双层)
快速开始
安装
方式 1:装饰器模式
⚠️ 重要提示: 缓存适合有明显开销的函数(数据库查询、API调用等)。对于简单计算(如 x => x * 2),使用缓存会让性能变差。
方式 2:FunctionCache 类
核心 API
withCache(fn, options)
装饰器函数,为异步函数添加缓存能力。
参数
返回值
返回包装后的函数,附带 invalidate() / invalidateAll() / stats() 方法。
示例
FunctionCache 类
构造函数
方法
register(name, fn, options)
注册函数。
execute(name, ...args)
执行函数。
invalidate(name, ...args)
失效缓存。
invalidatePattern(pattern)
批量失效缓存。
getStats(name?)
获取统计信息。
list()
列出所有已注册的函数。
resetStats(name?)
重置统计信息。
clear()
清空所有已注册的函数。
使用场景
场景 1:复杂业务逻辑
性能提升: 从 50ms → 0.001ms(50000x 加速)
场景 2:外部 API 调用
性能提升: 从 200-500ms → 0.001ms(200000-500000x 加速)
场景 3:复杂计算
性能提升: 从 100ms → 0.001ms(100000x 加速)
场景 4:条件缓存
场景 5:命名空间隔离
最佳实践
1. 合理设置 TTL
2. 识别适合缓存的函数 ⚠️ 重要
✅ 适合使用缓存:
- 数据库查询(> 1ms)
- 外部 API 调用(> 50ms)
- 复杂计算(> 10ms)
- 文件 I/O 操作
❌ 不适合使用缓存:
- 简单计算(< 0.01ms):如
x => x * 2 - 纯内存操作(< 0.01ms):如数组简单遍历
- 已经很快的函数(< 0.01ms)
性能测试建议:
3. 使用命名空间隔离
4. 使用命名函数
5. 监控缓存命中率
5. 及时失效缓存
性能对比
实际性能数据
基于真实测试(Intel CPU, Node.js v20):
场景对比
性能测试示例
常见问题
Q1: 如何选择缓存类型?
A: 根据应用场景选择:
- 单实例应用 → 仅本地缓存
- 多实例应用 → 本地 + Redis 双层缓存
- 微服务架构 → Redis 缓存(共享)
Q2: 匿名函数会导致键冲突吗?
A: 会。建议:
Q3: 如何复用 monSQLize 的缓存配置?
A: 使用 msq.getCache():
Q4: 支持哪些参数类型?
A: 支持所有可序列化类型:
- ✅ 基础类型(string、number、boolean)
- ✅ 对象、数组
- ✅ Date、RegExp
- ✅ MongoDB 类型(ObjectId、Decimal128 等)
- ❌ 函数、Symbol
Q5: 如何处理缓存穿透?
A: 使用条件缓存:
TypeScript 支持
相关文档
文档结束