Redis 使用案例:快取、佇列與速率限制
你已經建立了一個逐漸受到關注的網頁應用程式,但現在每次頁面載入都會存取資料庫,背景工作堆積如山,而且有幾個使用者正在猛打你的 API。你需要一個快速、記憶體內的資料儲存來應對這些挑戰。Redis 是快取、佇列和速率限制的首選解決方案。在本文中,我們將透過實用範例和最佳實踐來探討這三個核心使用案例。
為什麼選擇 Redis 進行快取、佇列和速率限制?
Redis 是一個記憶體內的鍵值儲存,以其速度和多功能性而聞名。它支援豐富的資料結構,如字串、列表、集合、有序集合和雜湊,使其成為各種任務的理想選擇。其原子操作和發布/訂閱功能進一步擴展了其用途。無論你是要減少資料庫負載、解耦服務,還是保護 API,Redis 都提供了一個簡單而強大的工具組。
1. 使用 Redis 進行快取
快取是 Redis 最常見的使用案例。透過將頻繁存取的資料儲存在記憶體中,你可以減少延遲和資料庫負載。Redis 的 TTL(存活時間)功能會自動使過期資料失效。
如何實作快取
- 檢查快取:在查詢資料庫之前,檢查資料是否存在於 Redis 中。
- 快取未命中時:從資料庫取得資料,並將結果儲存在 Redis 中,設定過期時間。
- 快取命中時:直接傳回快取的資料。
以下是使用 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)
# Simulate DB fetch
user = fetch_user_from_db(user_id)
r.setex(cache_key, 3600, json.dumps(user)) # Cache for 1 hour
return user
快取的最佳實踐
- 設定適當的 TTL:平衡資料新鮮度和命中率。對於易變的資料使用較短的 TTL,對於靜態內容使用較長的 TTL。
- 使用快取失效:當資料變更時,刪除或更新快取鍵,以避免讀取到過期資料。
- 處理快取雪崩:使用鎖或機率性提前過期,以防止在快取未命中時大量請求同時湧向資料庫。
- 監控命中率:目標是達到高命中率(例如 >80%),以確保快取有效。
2. 使用 Redis 進行佇列
Redis 列表和有序集合可實現簡單但強大的訊息佇列。它們非常適合背景工作、任務佇列和事件處理。與專用的訊息代理相比,Redis 佇列輕量且易於設定。
實作基本佇列
使用 LPUSH 新增工作,並使用 BRPOP 以阻塞方式取用它們:
# Producer
r.lpush('job_queue', json.dumps({'task': 'send_email', 'to': 'user@example.com'}))
# Consumer
while True:
_, job = r.brpop('job_queue', timeout=30)
if job:
process_job(json.loads(job))
使用有序集合的進階佇列
對於延遲工作或優先級佇列,使用以時間戳記作為分數的有序集合。取用者取得分數符合條件的工作