Node.js Redis:極速記憶體快取與實務應用場景

當你的應用程式造訪次數(Traffic)逐漸增加時,頻繁地向磁碟型資料庫(如 MySQL/MongoDB)發送查詢會導致回應延遲變長。這時我們需要 Redis —— 一個高效能的記憶體資料結構存儲系統,作為資料庫前方的「緩衝層 (Caching Layer)」。

核心策略:快取旁路模式 (Cache-aside)

這是最通用且穩定的快取架構:

  1. 讀取:先檢查 Redis。
    • 若命中 (Hit):直接傳回,速度最快。
    • 若失效 (Miss):從主要資料庫讀取,並異步存入 Redis 以供下次使用。
  2. 寫入:直接寫入資料庫,並刪除或更新對應的 Redis Key。

在 Node.js 中使用 Redis

安裝官方推薦的新版套件:npm install redis

const { createClient } = require('redis');

const client = createClient({
  url: 'redis://localhost:6379',
});

client.on('error', (err) => console.error('Redis 連線錯誤', err));

async function setupRedis() {
  await client.connect();
  console.log('✅ Redis 連線成功');
}

setupRedis();

實戰範例:快取 API 請求結果

async function getProductInfo(productId) {
  const cacheKey = `product:${productId}`;

  // 1. 嘗試從 Redis 獲取
  const cachedData = await client.get(cacheKey);
  if (cachedData) {
    console.log('🚀 命中快取');
    return JSON.parse(cachedData);
  }

  // 2. 失效:從資料庫讀取 (模擬)
  const product = await db.queryProduct(productId);

  // 3. 存入 Redis 並設定過期時間 (TTL) 為 1 小時 (3600 秒)
  // 設定過期時間非常重要,能防止記憶體被陳舊資料塞滿
  await client.set(cacheKey, JSON.stringify(product), {
    EX: 3600,
  });

  return product;
}

進階資料類型與應用

Redis 不只是 K-V 對照表,它還支援豐富的資料結構:

  • Hashes:適合存放物件型態(如 user:profile),節省序列化開銷。
  • Lists:適合做簡單的訊息佇列 (Message Queue)。
  • Sorted Sets (ZSET):適合製作「排行榜」,自動依照分數排序。
  • HyperLogLog:適合進行大規模的網頁不重複訪客 (UV) 統計,極度節省空間。

專業開發建議

  1. 快取雪崩 (Cache Avalanche):避免大量 Key 在同一時間點失效。建議在設定過期時間時,加上一個隨機的偏移量。
  2. 資料一致性:記住 Redis 是「複製品」。關鍵的金融或餘額資料,永遠以主要資料庫為準。
  3. 序列化開銷JSON.stringify 在處理極大物件時會消耗 CPU,必要時可考慮壓縮資料或使用二進位序列化(如 Protobuf)。

總結

  1. Redis 是讓 Node.js 應用撐住高流量壓力的秘密武器。
  2. 透過 TTL (Time-To-Live) 機制,讓快取能自動維護其「新鮮度」。
  3. 掌握 Cache-aside 模式是進入中大型系統開發的門票。