TypeScript 中的缓存:Redis、Memcached 及内置方案:从 A 到 Z
\n\n缓存是提升 Web 应用和服务性能的关键工具之一。在 TypeScript 和 Node.js 生态系统中,开发者可以在强大的外部系统(Redis、Memcached)和轻量级内置方案之间进行选择。在本文中,我们将详细分析这三种方法,提供 TypeScript 的实用代码示例,并帮助您为项目选择最佳策略。
\n\n为什么需要在 TypeScript 中进行缓存?
\n缓存可以减少服务器响应时间,降低数据库和外部 API 的负载,并减少重复请求的延迟。在基于 Node.js 运行的 TypeScript 中,缓存特别适用于:
\n- \n
- 存储昂贵计算的结果; \n
- 缓存外部 API 的响应; \n
- 保存用户会话; \n
- 减少对数据库的查询次数。 \n
1. TypeScript 中的内置缓存方案
\n对于小型项目或原型,可以使用 Node.js 的内置功能,无需安装额外包。
\n\n1.1. 使用 Map
\n最简单的方法是使用 Map 对象或普通对象。但是,这种缓存仅存在于单个进程的内存中,重启后会丢失。
// 基于 Map 的简单缓存\nclass SimpleCache<T> {\n private cache = new Map<string, T>();\n\n get(key: string): T | undefined {\n return this.cache.get(key);\n }\n\n set(key: string, value: T): void {\n this.cache.set(key, value);\n }\n\n clear(): void {\n this.cache.clear();\n }\n}\n\n// 使用示例\nconst cache = new SimpleCache<string>();\ncache.set('user:1', 'Alice');\nconsole.log(cache.get('user:1')); // Alice\n\n1.2. 带 TTL(生存时间)的缓存
\n更高级的版本是带有自动过期删除功能的缓存。
\n// 带 TTL 的缓存\nclass TtlCache<T> {\n private cache = new Map<string, { value: T; expiry: number }>();\n\n get(key: string): T | undefined {\n const item = this.cache.get(key);\n if (!item) return undefined;\n if (Date.now() > item.expiry) {\n this.cache.delete(key);\n return undefined;\n }\n return item.value;\n }\n\n set(key: string, value: T, ttlMs: number): void {\n this.cache.set(key, {\n value,\n expiry: Date.now() + ttlMs,\n });\n }\n}\n\n// 示例\nconst ttlCache = new TtlCache<number>();\nttlCache.set('price', 100, 5000); // 存活 5 秒\nsetTimeout(() => console.log(ttlCache.get('price')), 6000); // undefined\n\n2. 在 TypeScript 中使用 Redis 进行缓存
\nRedis 是一种流行的内存数据存储,支持高级数据结构、发布/订阅和持久化。对于 TypeScript,使用 ioredis 包。
2.1. 安装和连接
\nnpm install ioredis\nnpm install @types/ioredis --save-dev\nimport Redis from 'ioredis';\n\nconst redis = new Redis({\n host: 'localhost',\n port: 6379,\n});\n\nredis.on('connect', () => console.log('Connected to Redis'));\nredis.on('error', (err) => console.error('Redis error', err));\n\n2.2. 基本 set/get 操作
\n// 保存值\nawait redis.set('user:1:name', 'Alice');\n\n// 获取值\nconst name = await redis.get('user:1:name');\nconsole.log(name); // Alice\n\n// 设置 TTL(以秒为单位)\nawait redis.setex('session:123', 3600, 'active');\n\n2.3. 处理对象(JSON)
\n// 保存对象\nconst user = { id: 1, name: 'Alice', email: 'alice@example.com' };\nawait redis.set('user:1', JSON.stringify(user));\n\n// 读取并解析\nconst r