Redis 應用案例:快取、佇列與速率限制

Backend2026-10-03TryQuickToolBox

你已經建置了一個可運作的網頁應用,但隨著流量成長,你注意到頁面載入變慢、資料庫瓶頸,以及偶爾的停機。這些都是常見的擴展痛點。Redis 是一種記憶體內資料儲存,能優雅地解決許多這類問題。在本文中,我們將探討三個實用的 Redis 應用案例:快取、佇列與速率限制。你將透過程式碼範例與最佳實務,學習如何實作每一個案例。

為什麼選擇 Redis?

Redis 是一個開源的記憶體內鍵值儲存,以其速度與多功能性著稱。它支援字串、列表、集合、雜湊與有序集合等資料結構,使其適用於各種任務。由於資料保存在記憶體中,讀寫速度極快——通常低於一毫秒。雖然它不是主要資料庫的替代品,但作為效能與協調的輔助工具,它表現出色。

1. 使用 Redis 進行快取

快取是最常見的 Redis 應用案例。將經常存取的資料儲存在 Redis 中,可減輕主要資料庫的負載並加速回應。

如何實作快取

  1. 先檢查 Redis:當請求進來時,使用唯一鍵在 Redis 中尋找資料。
  2. 快取未命中時:如果 Redis 中沒有資料,則從資料庫取得。
  3. 儲存至 Redis:將結果存入 Redis 並設定過期時間(TTL),以避免資料過期。
  4. 回傳資料:將資料傳送給客戶端。

以下是使用 redis-py 的簡單 Python 範例:

import redis
import json

r = redis.Redis(host='localhost', port=6379, db=0)

def get_user(user_id):
    cache_key = f"user:{user_id}"
    cached = r.get(cache_key)
    if cached:
        return json.loads(cached)
    # 模擬資料庫查詢
    user = fetch_user_from_db(user_id)
    r.setex(cache_key, 3600, json.dumps(user))  # 快取 1 小時
    return user

最佳實務:

2. 使用 Redis 進行佇列

Redis 列表與串流非常適合建置簡單的訊息佇列。它們讓你能將耗時任務(如寄送電子郵件或處理圖片)與主要請求流程解耦,提升回應速度。

使用列表作為佇列

Redis 列表支援原子性的推入與彈出操作。使用 LPUSH 將工作加入左側,並使用 BRPOP 阻塞並從右側彈出,形成 FIFO 佇列。

# 生產者:加入一項工作
r.lpush('job_queue', json.dumps({'task': 'send_email', 'to': 'user@example.com'}))

# 消費者:處理工作
while True:
    _, job_data = r.brpop('job_queue', timeout=30)
    job = json.loads(job_data)
    process_job(job)

注意事項:

3. 使用 Redis 進行速率限制

速率限制可保護你的 API 免於濫用,並確保公平使用。Redis 的原子操作與過期機制使其成為實作速率限制器的理想選擇。

固定視窗速率限制

在固定視窗中,你允許每個時間視窗內有 N 個請求(例如每小時 100 個請求)。使用 INCR 與 EXPIRE 來追蹤計數。

def is_rate_limited(user_id, limit=100, window=3600):
    key = f"rate:{user_id}"
    current = r.incr(key)
    if current == 1:
        r.expire(key, window)
    return current > limit

使用有序集合的滑動視窗提供更平滑的限制。將請求的時間戳記儲存在有序集合中,並移除舊的項目。

def is_rate_limited_sliding(user_id, limit=100, window=3600):
    key = f"rate:{user_id}"
    now = time.time()
    pipeline = r.pipeline()
    pipeline.zremrangebyscore(key, 0, now - window)
    pipeline.zadd(key, {now: now})
    pipeline.zcard(key)
    pipeline.expire(key, window)
    _, _, count, _ = pipeline.execute()
    return count > limit

最佳實務:

應用案例比較

應用案例 Redis 資料結構 主要優勢
快取 String, Hash 減少資料庫負載、加快讀取
佇列 List, Stream 解耦任務、提升回應速度
速率限制 String, Sorted Set 保護 API、確保公平使用

常見問題

Redis 是持久性的嗎?

Redis 透過 RDB 快照與 AOF 日誌提供持久化,但它主要是一個記憶體內儲存。對於關鍵資料,請務必備份或使用主要資料庫。

我可以使用 Redis 進行工作階段儲存嗎?

可以,Redis 由於其速度與自動過期特性,常被用於工作階段儲存。它讓你能夠在多台伺服器之間共享工作階段。

如果 Redis 當掉會發生什麼事?

如果 Redis 無法使用,你的應用應該優雅地退回資料庫,或從本機快取回傳資料。實作斷路器以避免連鎖故障。

準備好最佳化你的網頁應用了嗎?從整合 Redis 進行快取、佇列或速率限制開始。對於格式化 JSON 或分析日誌等快速任務,請參考我們的 JSON Formatter 與 Nginx Log Analyzer。