前言

在我的架構中,API 每次回傳內容幾乎不變,但查詢 SQL 層級較深,導致回應時間較長。由於 Cloudflare Workers 無法直接使用 Redis,因此我尋找替代的快取方案。

Caches.default vs cloudflare kv

對於我的需求來說其實兩種方案對我來說都可以使用 但我覺得 kv 的方案更可控,所以選擇使用 kv

  • caches.default 是 Cloudflare Edge 網路上每個 PoP(Point of Presence)內建的 HTTP 回應快取,每個 PoP 彼此之間不會自動同步,因此使用者從不同地區打到的節點可能命中不同的快取內容,而且 Cloudflare 可能在資源壓力或 TTL 到期時隨時清除它。
  • cloudflare kv 是另一個受管理的 key-value 儲存服務,KV 的資料會在全球資料中心之間同步(最終一致),比 caches.default 更持久,也能設定 TTL 或手動刪除,適合需要跨 PoP 共享或較長時間保存的快取。

建立 Cloudflare KV

我覺得 cloudflare 的 docs 寫得很清楚,非常建議直接閱讀文件。

建立 cloudflare kv

  • 透過 UI 建構 Dashboard -> 儲存空間和資料庫
  • 透過 CLI 建構

Worker 綁定

wrangler.jsonc

{
// ...other config,
	"kv_namespaces": [
		{
			"binding": "{binding-name}",
			"id": "<production-id>",
			"preview_id": "<preview-id>"
		}
	]
}

最小實作 code

在學習新技術時 我通常會請 ai 幫我生成一段這個 flow 的最小實作 code 幫助我快速理解執行架構

// 嘗試從 KV 取出快取
const cached = await SONG_CACHE.get(cacheKey);
if (cached) return new NextResponse(cached, {...});

// 沒有快取 → 執行原始查詢
const response = await actuallyFetchSong(request, params);

// 將結果寫入 KV(TTL = 單位為秒,設定為0則不清除快取)
if (response.ok) {
  await SONG_CACHE.put(cacheKey, await response.clone().text(), { expirationTtl: 3600 });
}

比較

API 請求 減少了 2/3 的請求時間