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

Backend2026-10-05TryQuickToolBox

你已經建立了一個逐漸受到關注的 Web 應用程式,但隨著流量成長,你注意到資料庫查詢變慢,偶爾還會發生逾時。伺服器在負載下苦苦掙扎,使用者抱怨延遲。你需要一個快速的記憶體內資料儲存,來卸載重複性任務並管理流量高峰。Redis 是許多後端挑戰的首選解決方案,在本文中,我們將探討三個實際應用案例:快取、佇列和速率限制。

為什麼選擇 Redis?

Redis 是一個開源的記憶體內鍵值儲存,以其速度和多功能性著稱。它支援字串、雜湊、列表、集合和有序集合等資料結構,適用於各種任務。與傳統資料庫不同,Redis 將資料保存在 RAM 中,提供亞毫秒級的延遲。它還提供持久化選項、複製和叢集,以實現高可用性。

1. 使用 Redis 進行快取

快取是最常見的 Redis 應用案例。透過將頻繁存取的資料儲存在 Redis 中,你可以減輕主要資料庫的負載並加快回應時間。例如,如果你的應用程式顯示熱門產品列表,你可以將查詢結果快取幾分鐘。

如何實作快取

  1. 檢查快取:在查詢資料庫之前,檢查資料是否存在於 Redis 中。
  2. 如果找到(快取命中):回傳快取的資料。
  3. 如果未找到(快取未命中):查詢資料庫,將結果儲存在 Redis 中並設定過期時間(TTL),然後回傳資料。

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

import redis
import json

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

def get_products():
    cache_key = 'products:popular'
    cached = r.get(cache_key)
    if cached:
        return json.loads(cached)
    # 模擬資料庫查詢
    products = [{'id': 1, 'name': 'Product A'}, {'id': 2, 'name': 'Product B'}]
    r.setex(cache_key, 300, json.dumps(products))  # 快取 5 分鐘
    return products

最佳實踐:使用有意義的快取鍵,設定適當的 TTL,並考慮快取失效策略。對於頻繁變更的資料,使用較短的 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 列表很簡單,但缺乏如確認等進階功能。對於更穩健的需求,請考慮 Redis Streams,它支援消費者群組和訊息確認。

3. 使用 Redis 進行速率限制

速率限制可保護你的 API 免於濫用,並確保公平使用。Redis 的原子操作使其成為實作速率限制器的理想選擇。常見的演算法是滑動視窗計數器,但更簡單的固定視窗方法也同樣有效。

固定視窗速率限制器

為每個使用者遞增計數器並設定過期時間。如果計數器超過限制,則拒絕請求。

def is_allowed(user_id, limit=100, window=60):
    key = f'rate_limit:{user_id}'
    current = r.incr(key)
    if current == 1:
        r.expire(key, window)
    return current