TypeScript 中的缓存:Redis 及其他工具
缓存是优化 Web 应用性能的关键策略之一。在 TypeScript 和 Node.js 生态系统中,有多个强大的库可以高效管理数据缓存。本文将详细介绍流行的工具、它们的应用以及最佳实践。
为什么需要缓存?
缓存允许将频繁请求的数据临时存储在快速存储中,从而避免每次都执行昂贵的操作(如数据库查询、计算、外部 API 调用)。这可以降低服务器负载并减少响应时间。
TypeScript 中主要的缓存工具
1. 通过 ioredis 库使用 Redis
Redis 是一个高性能的内存数据存储,支持多种数据结构。对于 TypeScript,最佳选择是 ioredis——一个完全支持类型和 Promise 的客户端。
import Redis from 'ioredis';
// 创建客户端const redis = new Redis({ host: 'localhost', port: 6379,});
// 带 TTL 的缓存函数async function cacheGet(key: string): Promise<string | null> { const data = await redis.get(key); return data;}
async function cacheSet(key: string, value: string, ttl: number = 3600): Promise<void> { await redis.setex(key, ttl, value);}
// 使用示例async function getUserData(userId: string) { const cacheKey = `user:${userId}`; const cached = await cacheGet(cacheKey); if (cached) { return JSON.parse(cached); } // 模拟昂贵查询 const userData = { id: userId, name: 'John Doe' }; await cacheSet(cacheKey, JSON.stringify(userData), 3600); return userData;}2. node-cache——适用于小型项目的内存缓存
node-cache 是一个简单的内存库,无需外部依赖。非常适合原型和小型微服务的数据量较小的场景。
import NodeCache from 'node-cache';
const myCache = new NodeCache({ stdTTL: 600, checkperiod: 120 });
// 存储数据myCache.set('key', { data: 'value' });
// 获取数据const value = myCache.get('key');if (value) { console.log('来自缓存:', value);} else { console.log('缓存为空,正在请求数据...');}
// 按键删除myCache.del('key');
// 清空所有缓存myCache.flushAll();3. async-cache-dedupe——防止重复请求
该库解决了“缓存雪崩”问题(当大量请求同时尝试填充缓存时)。它会自动对同一键的并行请求进行去重。
import { createCache } from 'async-cache-dedupe';
const cache = createCache({ ttl: 60, // 生存时间(秒) stale: 10, // 数据被视为过期但仍可返回的时间});
// 包装异步函数const getData = cache.define('getData', async (id: number) => { // 昂贵请求 const result = await fetch(`https://api.example.com/data/${id}`); return result.json();});
// 使用const result = await getData(42);缓存失效策略
缓存中最困难的任务之一是失效——更新过时的数据。让我们看看主要方法:
- TTL(生存时间)——数据在指定时间后自动删除。简单可靠的方法。
- 惰性失效——每次请求时检查数据的有效性(例如,通过版本号)。
- 事件驱动失效——当数据库中的数据发生变化时,发送事件以清除相应的缓存。
- Write-through——在写入主存储的同时更新缓存。