# KV 模式与最佳实践
## 多级缓存
typescript
// 内存 → KV → 源站 (3级缓存)
const memoryCache = new Map();
async function getCached(env: Env, key: string): Promise {
const now = Date.now();
// L1: 内存缓存 (最快)
const cached = memoryCache.get(key);
if (cached && cached.expires > now) {
return cached.data;
}
// L2: KV 缓存 (快)
const kvValue = await env.CACHE.get(key, "json");
if (kvValue) {
memoryCache.set(key, { data: kvValue, expires: now + 60000 }); // 内存中缓存 1 分钟
return kvValue;
}
// L3: 源站 (慢)
const origin = await fetch(`https://api.example.com/${key}`).then(r => r.json());
// 回填缓存
await env.CACHE.put(key, JSON.stringify(origin), { expirationTtl: 300 }); // KV 中缓存 5 分钟
memoryCache.set(key, { data: origin, expires: now + 60000 });
return origin;
}
## API 响应缓存
typescript
async function getCachedData(env: Env, key: string, fetcher: () => Promise): Promise {
const cached = await env.MY_KV.get(key, "json");
if (cached) return cached;
const data = await fetcher();
await env.MY_KV.put(key, JSON.stringify(data), { expirationTtl: 300 });
return data;
}
const apiData = await getCachedData(
env,
"cache:users",
() => fetch("https://api.example.com/users").then(r => r.json())
);
## 会话管理
typescript
interface Session { userId: string; expiresAt: number; }
async function createSession(env: Env, userId: string): Promise {
const sessionId = crypto.randomUUID();
const expiresAt = Date.now() + (24 * 60 * 60 * 1000);
await env.SESSIONS.put(
`session:${sessionId}`,
JSON.stringify({ userId, expiresAt }),
{ expirationTtl: 86400, metadata: { createdAt: Date.now() } }
);
return sessionId;
}
async function getSession(env: Env, sessionId: string): Promise {
const data = await env.SESSIONS.get(`session:${sessionId}`, "json");
if (!data || data.expiresAt < Date.now()) return null;
return data;
}
## 合并冷键 (Coalesce Cold Keys)
typescript
// ❌ 差:多个独立键
await env.KV.put("user:123:name", "John");
await env.KV.put("user:123:email", "
[email protected]");
// ✅ 好:单个合并对象
await env.USERS.put("user:123:profile", JSON.stringify({
name: "John",
email: "
[email protected]",
role: "admin"
}));
// 优势:热键缓存、单次读取、减少操作