lru-cache
概述
一个高性能、功能丰富的 Least Recently Used (LRU) 缓存 实现库,专为 Node.js 环境设计。
LRU (最近最少使用):当缓存达到设定的容量上限时,它会自动淘汰那些最近最少被访问的项,为新数据腾出空间。 这是管理有限内存资源的有效策略。
特性
LRU 缓存:
- 存储键值对 (
key
->value
)。 - 当添加新项导致缓存大小超过
max
或maxSize
限制时,自动淘汰最近最少使用的项。 - 高效的
get
(获取)、set
(设置/更新)、delete
(删除)、has
(检查存在) 操作。
- 存储键值对 (
容量限制:
max
: 设置缓存允许存储的最大 条目数量。最常用的限制方式。maxSize
: 设置缓存允许使用的 最大总大小(字节数或其他单位)。需要配合sizeCalculation
函数使用。sizeCalculation
: 一个函数,用于计算每个缓存项的大小(除了其键所占的内存)。 例如,可以用来计算存储对象或字符串的实际内存占用。这对于精确控制内存使用至关重要。
条目过期 (TTL - Time To Live):
ttl
: 设置全局默认的条目存活时间(毫秒)。超过此时间未访问的条目会被视为过期。ttlAutopurge
: 是否在读取 (get
) 时自动删除已过期的条目 (默认true
)。allowStale
: 允许在读取 (get
) 时返回已过期但尚未被淘汰的条目 (默认false
)。updateAgeOnGet
: 在读取 (get
) 时是否重置条目的“年龄”,将其视为新访问,从而延长它在缓存中的生存时间 (默认false
)。如果为true
,频繁访问的条目几乎不会过期。noDeleteOnStaleGet
: 当allowStale
为true
时,读取过期条目是否不触发异步后台删除 (默认false
,即会触发删除)。ttlResolution
: 过期检查的时间间隔精度(毫秒)。为了性能,内部不会实时检查每个条目,而是按此间隔批量检查 (默认0 ms
,表示尽可能精确,但实际受事件循环影响)。在
set
时指定 TTL: 可以单独为每个set
操作设置该条目的特定 TTL,覆盖全局ttl
。
获取与更新:
fetchMethod
: 当尝试get
一个不存在(或允许过期且已过期)的键时,可以用这个函数去异步获取数据。 它会防止对同一个键的重复并发请求(类似 Single Flight),只发出一个请求并将结果返回给所有等待者。 极大简化了 “缓存未命中则加载” 的模式。async (key, staleValue, { options, signal, context }) => {}
。noDeleteOnFetchRejection
: 如果fetchMethod
拒绝 (reject
),是否不删除该键(默认false
,即会删除占位符)。allowStaleOnFetchRejection
: 如果fetchMethod
拒绝 (reject
) 且allowStale
为true
, 是否返回过期的旧值(如果有) (默认false
)。
安装
npm install lru-cache
pnpm add lru-cache
yarn add lru-cache
使用
import { LRUCache } from 'lru-cache'
const cache = new LRUCache({
max: 500, // 最大缓存条数
// maxSize 和 sizeCalculation 配合使用
maxSize: 5000, // 最大缓存大小
sizeCalculation: (value, key) => value.length, // 计算每个缓存项的大小
ttl: 1000 * 60 * 5, // 存活时间,单位毫秒
allowStale: false, // 在从缓存中移除之前返回过期项?
updateAgeOnGet: false,
updateAgeOnHas: false,
/// 用于cache.fetch()的异步方法,实现
// 类似stale-while-revalidate(后台更新缓存)的行为模式
fetchMethod: async (
key,
staleValue,
{ options, signal, context }
) => {},
})
// 设置值
cache.set('key', 'value')
// 获取值
cache.get('key') // "value"
// 检查是否存在
cache.has('key') // true
// 删除
cache.delete('key')
// 非字符串键名完全支持
// 但需注意必须是同一个对象,而非
// 仅结构等效的JSON对象
let someObject = { a: 1 }
cache.set(someObject, 'a value')
cache.clear() // 清空缓存
性能
- 高度优化: 使用纯 JavaScript 实现,针对 V8 引擎做了优化。
- 零依赖: 不依赖任何其他 npm 包,体积小,安全性高,安装快速。
- O(1) 操作: get, set, delete, has 等核心操作的时间复杂度都是常数级,非常高效。
适用场景
- 数据库查询缓存: 缓存频繁查询的数据库结果。
- API 响应缓存: 缓存外部 API 调用的结果。
- 计算/渲染结果缓存: 缓存耗时的计算结果、模板渲染结果。
- 会话存储 (Session Storage): 在内存中存储用户会话信息(注意持久化和分布式问题)。
- 速率限制: 存储请求计数。
- 任何需要内存中快速键值存储且有容量限制和淘汰策略的地方。