前言
系統擴展到一定程度後,雖然資料庫沒有崩潰,但因為資料被分片(Sharding)散落在不同伺服器,使用者每次打開首頁都要跨多台伺服器撈資料再重新排序,導致延遲(Latency)非常高。
這篇文章延續前兩篇,同樣透過五維度分析法,拆解如何利用快取(Cache)與推拉模型(Push/Pull Model)打造低延遲時間線架構。
這篇你可以帶走什麼
- Sharding 後為什麼會出現高延遲的 Scatter and Gather 成本
- 如何估算 Timeline Cache 容量,理解 36GB 量級的可行性
- Push 與 Pull 各自最容易失效的邊界條件
- 為什麼混合模型(Hybrid Model)是更穩定的實務解
維度一、可直接觀察的事實:Sharding 後延遲為何暴增
在分片後,生成單一使用者時間線通常需要:
- 向多個分片送查詢(Scatter)
- 在應用層回收結果(Gather)
- 合併、排序、分頁後回傳
這個流程會放大延遲,尤其在高峰流量時更明顯。
再看快取空間估算。若假設:
- 一億用戶
- 每人每天產生 2 篇貼文
- 只快取貢獻 80% 流量的前 20% 熱門內容
- 保留 3 天
可得到約 36GB 的快取需求,現代伺服器或小型快取叢集通常可承受。
另外,為了追求極低延遲,可以預先構建時間線(Pre-computing Timeline Cache):
- 發文時由 Fan-out 服務把貼文 ID 寫入所有追蹤者的 Timeline Cache
- 使用者登入時直接讀自己的快取,不必即時回資料庫做大查詢
重點:Sharding 解決的是容量與寫入分攤;時間線延遲問題往往要靠快取與查詢策略一起解。
維度二、條件檢查:Push 與 Pull 何時有效?
一般情況下的最佳解
一般使用者發文時,最常見做法是:
- 發文事件先進 Message Queue(MQ)
- 由 Worker Pool 非同步處理 Fan-out
- 把貼文推送(Push)到追蹤者的 Timeline Cache
這能兼顧發文 API 響應與讀取速度。
邊界條件(名人效應大屠殺)
如果發文者是超級大 V(例如 1 億粉絲),Push 會在單篇貼文觸發 1 億次快取寫入:
- 寫入放大(Write Amplification)急遽上升
- MQ 積壓
- Fan-out 服務過載
結果是整體時間線服務延遲反而惡化。
重點:Push 對一般場景很有效,但對極端粉絲規模會失效。
維度三、反證檢查:全推或全拉都不是完美解
只選單一模型通常都會出問題。
- 全 Push:讀取很快,但大 V 場景容易出現 Hotspot,且會浪費資源替低活躍或殭屍帳號維護快取。
- 全 Pull:沒有寫入放大,但使用者每次登入都要即時拉取與排序,延遲高,也不利即時通知(Notification)。
因此實務上常採混合模型(Hybrid Model):
- 一般使用者採 Push(確保讀取快)
- 超級大 V 採 Pull(粉絲登入時才去拉取大 V 的貼文並合併到時間線中)
維度四、不確定性與假設分析
區分觀察事實與經驗推論:
- 觀察事實:Push 模型在寫入時消耗資源,Pull 模型在讀取時消耗資源。
- 經驗推論:假設 20% 的貼文貢獻了 80% 的流量(八二法則)。這個比例在不同性質的平台(如 Twitter 偏向公域廣播、Facebook 偏向私域社交)會有很大的差異,直接影響 Cache Size 的估算。
核心假設:整個 Timeline Cache 架構的成立,依賴於「記憶體(Memory)足夠便宜且容量夠大」這個硬體發展事實,才能用空間換取時間(Latency)。
維度五、最終結論與行動建議
破關路線圖(信心度 95%)
- 先導入 Redis 或 Memcached 作為時間線快取層
- Fan-out 流程務必經過 MQ 非同步解耦,避免發文 API 被鎖死。
- 建立使用者分級策略(例如追蹤者大於 10 萬視為大 V)
- 對大 V 切換 Pull,在 Timeline Service 層次進行即時合併(Merge)。
這套混合架構正是早期 Twitter 解決「小賈斯汀發文導致系統崩潰」的真實解決方案。
脆弱點提示
混合模型最脆弱的地方在閥值設定與結構演化:
- 若大 V 判定閥值設錯,可能同時壓垮 Push 與 Pull 兩側。
- 若平台成長後大 V 數量顯著上升,Pull 模型在應用層的即時合併排序運算(Merge Sort)會成為下一個延遲瓶頸。
一句話總結
時間線優化不是 Push 或 Pull 二選一,而是用混合模型在讀取速度、寫入成本與擴展性之間取得平衡。