設計新聞動態系統 (News Feed)

Medium★★★★★Draft

FromSystem Design Interview

Concepts practiced⚡ 快取策略 (Caching Strategies)📨 訊息佇列 (Message Queue)🗄️ SQL vs NoSQL 選型📈 負載均衡 (Load Balancing)

Convention: read the requirements & constraints first, sketch your own design, then expand the reference to compare.

📚 From the Books

設計新聞動態系統 (News Feed)ProblemMediumSocial & Feed

使用者發佈貼文,並在首頁看到朋友的貼文(依時間倒序)。難點在於「發佈」與「建構」兩個流程如何解耦,以及貼文要在何時 fanout 給朋友。

📋 Requirements

🧠 Core Ideas

TIP

拆成兩個流程:feed 發佈(貼文寫入快取與資料庫、並填到朋友的 feed)與 news feed 建構(把朋友的貼文以時間倒序聚合)。關鍵決策是 fanout 要在寫入時還是讀取時做。

兩個主要 API:發佈用 POST /v1/me/feed(帶 content、auth_token),取得用 GET /v1/me/feed(帶 auth_token)。

⚖️ Reference Design

Feed 發佈流程
  • Load balancer 把流量分到網頁伺服器。
  • 網頁伺服器負責身份驗證與速率限制(限制單位時間發文數,防垃圾訊息)。
  • Post service 把貼文持久化到資料庫與快取。
  • Fanout service 把新內容推播到朋友的 news feed 快取。
  • Notification service 通知朋友有新內容。
Fanout 兩種模型
  • 寫入時 fanout(push model):發佈時就把貼文預先送進朋友快取。取得快、feed 即時,但朋友多時產生 feed 既慢又耗資源(hotkey 問題),且對不活躍使用者浪費運算。
  • 讀取時 fanout(pull model):使用者載入首頁時才拉取最近貼文。對不活躍使用者省資源、無 hotkey 問題,但取得慢。
  • 混合方法:多數使用者用 push;名人/追隨者眾多者讓追隨者按需拉取,避免系統過載。一致性雜湊有助更平均分散請求/資料,緩解 hotkey 問題。
Fanout service 運作
  • 從圖形資料庫取得朋友 ID,再從使用者快取取得朋友資訊並依設定過濾(如靜音、選擇性分享)。
  • 把朋友清單與新貼文 ID 送進訊息佇列
  • Fanout workers 從佇列取資料,把 <post_id, user_id> 存進 news feed 快取。
  • 只存 ID 不存整個物件,並設可調上限以控制記憶體;因多數人只看最新內容,cache miss 率低。
Newsfeed 建構與快取架構
  • 取得時:Newsfeed service 先從 news feed 快取拿貼文 ID 清單,再從 user cache 與 post cache 取完整物件,組出**完整充水(fully hydrated)**的 feed,以 JSON 回傳渲染。
  • 媒體(圖片/影片)放 CDN 加速取得。
  • 快取分 5 層:News Feed(feed ID)、Content(貼文資料,熱門進 hot cache)、Social Graph(關係)、Action(按讚/回覆等)、Counters(讚數、追隨數等)。詳見快取策略

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading