問題背景
在電商系統中,我們經常需要回滾訂單資料讓用戶取得過去的訂單作為「鋪底」。原本的做法是每隔 5 分鐘往前打一次訂單 API,看似合理的設計卻埋下了災難的種子。
災難是怎麼發生的?
當我們要回滾 30 天的資料時:
- 每 5 分鐘切一個時間段 = 一天 288 個 Queue
- 30 天 = 8,640 個 Queue 瞬間湧入 Kafka
- 每個 Queue 產生約 300 張訂單 = 250 萬筆訂單等待處理
雪上加霜
更糟的是,正式環境有多台 Job 機同時消化 Queue,導致:
- 平台 API 被我們打到 Error
- 幾乎所有平台都把我們 Ban 掉
- 不知道哪些 Queue 成功、哪些失敗
解決方案演進
| 版本 | 作法 | Queue 數量 | 問題 |
|---|---|---|---|
| 原始 | 每 5 分鐘一個 Queue | 8,640 | 根本做不完,打爆平台 |
| 2月後 | 每半天一個 Queue | 60 | 短時間塞住其他工作 |
| 8月後 | 每天一個 Queue + 間隔 5 分鐘 | 30 | 時間長但穩定 |
關鍵學習
1. Queue 內容設計很重要
如果把整張訂單塞入 Queue,會造成:
- 資料庫大量 I/O
- 程式更新後要等舊 Queue 處理完才生效
2. 批次處理要考慮下游承受能力
不是 Queue 發得越快越好,要考慮:
- 平台 API 的 Rate Limit
- 自己系統的處理能力
- 多台機器同時打的總流量
最佳實踐
- 漸進式發送:Queue 之間加入間隔時間
- 流量控制:限制同時處理的 Job 機數量
- 監控機制:建立 Queue Lag 告警
這次經驗讓我們學到:在分散式系統中,「快」不一定是好事,「穩」才是王道。
發佈留言