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

Backend2026-09-15TryQuickToolBox

您已經建立了一個在開發環境中運作良好的網頁應用程式,但隨著流量增長,您注意到回應時間變慢和資料庫超載。罪魁禍首通常是重複的昂貴操作:從資料庫取得相同的資料、同步處理任務,或允許濫用性的請求速率。Redis 是一個記憶體內資料儲存庫,為這些問題提供了優雅的解決方案。在本文中,我們將探討三個實用的 Redis 使用案例:快取、佇列和速率限制。您將透過程式碼範例學習如何實作每個模式,並了解何時應用它們。

為什麼選擇 Redis?

Redis 是一個開源、記憶體內的鍵值儲存庫,以其速度和多功能性而聞名。它支援字串、列表、集合和雜湊等資料結構,使其適合簡單快取之外的各種任務。由於它將資料保存在記憶體中,Redis 提供亞毫秒級的延遲,這對於高效能場景來說是理想的。它還提供持久化選項,因此您不會在重新啟動時遺失資料。讓我們深入探討這三個使用案例。

1. 使用 Redis 進行快取

快取是最常見的 Redis 使用案例。這個想法很簡單:將昂貴操作(如資料庫查詢或 API 呼叫)的結果儲存在 Redis 中,並在後續請求中直接提供它們。這減少了主要資料庫的負載並加快了回應時間。

如何實作快取

  1. 檢查快取:在存取資料庫之前,使用唯一鍵(例如 user:123)查詢 Redis 以取得資料。
  2. 如果找到(快取命中):立即回傳快取的資料。
  3. 如果未找到(快取未命中):從資料庫取得資料,將其儲存在 Redis 中並設定過期時間(TTL),然後回傳。

以下是使用 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

最佳實務:選擇有意義的鍵,設定適當的 TTL 以避免過時資料,並考慮快取失效策略。對於讀取密集型工作負載,快取可以將資料庫負載減少幾個數量級。

2. 使用 Redis 的佇列

佇列將耗時的任務與請求-回應週期分離。例如,發送電子郵件、處理圖片或產生報告可以非同步完成。Redis 列表或串流非常適合實作簡單佇列。

實作基本佇列

使用 LPUSH 將任務新增到列表的左側,並使用 BRPOP 從右側阻塞並彈出。這會建立一個 FIFO 佇列。

# 生產者:新增任務
r.lpush('email_queue', json.dumps({'to': 'user@example.com', 'subject': 'Welcome'}))

# 消費者:處理任務
while True:
    _, job = r.brpop('email_queue', timeout=30)
    if job:
        process_email(json.loads(job))

對於更進階的需求,Redis Streams 提供消費者群組、確認和可重播性,使其適合穩健的訊息處理。

3. 使用 Redis 的速率限制

速率限制保護您的 API 免受濫用並確保公平使用。Redis 的原子操作使得實作自動過期的計數器變得容易。

固定視窗速率限制

在固定視窗方法中,您允許每個時間視窗 N 個請求(例如,每個 IP 每小時 100 個請求)。使用 INCR 和 EXPIRE:

def is_allowed(ip, limit=100, window=3600):
    key = f'rate:{ip}'
    current = r.incr(key)
    if current == 1:
        r.expire(key, window)
    return current