为什么高级缓存是 TypeScript 应用程序的必需品
在现代高负载系统中,缓存已不再是一个选项——它是架构中必不可少的元素。对于使用 Node.js 的 TypeScript 开发人员来说,选择正确的缓存策略可以将 API 响应时间从 200 毫秒降低到 2 毫秒,并将数据库负载减少 80-90%。在本文中,我们将从高级层面探讨三种缓存方法:Redis、Memcached 和 TypeScript 内置解决方案。
1. TypeScript 内置缓存:从简单的 Map 到 LRU 缓存
内置解决方案非常适合单体应用或不需要分布式缓存的微服务。最原始的选择是使用 Map,但由于缺乏 TTL 和内存控制,它不适合生产环境。
实现带 TTL 的 LRU 缓存
让我们来看一个带有自动清理功能的高级 LRU(最近最少使用)缓存实现:
interface CacheEntry<T> { value: T; expiresAt: number;}
class LRUCache<T> { private cache: Map<string, CacheEntry<T>>; private readonly maxSize: number; private readonly ttlMs: number;
constructor(maxSize: number = 100, ttlMs: number = 60000) { this.cache = new Map(); this.maxSize = maxSize; this.ttlMs = ttlMs; }
get(key: string): T | undefined { const entry = this.cache.get(key); if (!entry) return undefined;
if (Date.now() > entry.expiresAt) { this.cache.delete(key); return undefined; }
// 将键移动到末尾(最新) this.cache.delete(key); this.cache.set(key, entry); return entry.value; }
set(key: string, value: T): void { if (this.cache.has(key)) { this.cache.delete(key); } else if (this.cache.size >= this.maxSize) { // 删除最旧的(第一个)元素 const oldestKey = this.cache.keys().next().value; this.cache.delete(oldestKey); }
this.cache.set(key, { value, expiresAt: Date.now() + this.ttlMs, }); }
clear(): void { this.cache.clear(); }}
// 使用示例const userCache = new LRUCache<User>(500, 300000); // 500 个元素,TTL 5 分钟高级模式:缓存装饰器
为了代码整洁,我们使用 TypeScript 装饰器:
function Cached(ttlMs: number = 60000) { const cache = new LRUCache<any>(100, ttlMs);
return function ( target: any, propertyKey: string, descriptor: PropertyDescriptor ) { const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) { const key = `${propertyKey}_${JSON.stringify(args)}`; const cached = cache.get(key); if (cached !== undefined) return cached;
const result = await originalMethod.apply(this, args); cache.set(key, result); return result; };
return descriptor; };}
class UserService { @Cached(120000) // 2 分钟 async getUser(id: string): Promise<User> { // 昂贵的数据库查询 return db.findUser(id); }}2. Redis:使用高级数据结构的分布式缓存
Redis 不仅仅是一个键值存储。它对复杂数据结构(Hash、List、Set、Sorted Set)的支持为实现高级缓存策略提供了可能性。
带标签失效的缓存
问题:更新一个实体时,需要使多个缓存失效。解决方案——标签:
import Redis from 'ioredis';
class TaggedCache { private redis: Redis; private readonly keyPrefix: string;
constructor(redisUrl: string, prefix: string = 'cache') { this.redis = new Redis(redisUrl); this.keyPrefix = prefix; }
async get<T>(key: string,