TypeScript 中的缓存:Redis、Memcached 和内置解决方案(高级)

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么高级缓存是 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,

博客

书籍推荐