🔬 Saturday Deep Dive: Design a News Feed (Twitter/Facebook) (15 min read)
📊 NeetCode: 23/150 · SysDesign: 22/40 · Behavioral: 22/40 · Frontend: 22/50 · AI: 11/30
🔥 26-day streak!
Overview / 概述
Designing a news feed is a classic system design interview question. It tests your ability to handle massive scale, balance read/write heavy workloads, and make trade-offs between latency and consistency.
设计信息流(News Feed)是一道经典的系统设计面试题。它考察你处理海量并发、平衡读写重负载以及在延迟和一致性之间做出权衡的能力。
Part 1: Theory / 理论基础 (5 min)
At its core, a news feed system has two main flows:
- Feed Publishing (Fan-out): When a user publishes a post, it must be pushed to all their followers' feeds.
- Feed Retrieval: When a user opens the app, they retrieve their pre-computed or on-the-fly generated feed.
Fan-out on Write (Push Model): Pre-compute the feed during the write phase. Fast reads, but slow writes for users with millions of followers (Justin Bieber problem).
Fan-out on Read (Pull Model): Generate the feed when the user requests it. Fast writes, but slow reads.
Hybrid Model: Push for normal users, pull for celebrities.
核心理论包括两个主要流程:
- 发布(Fan-out): 用户发布动态时,推送到所有粉丝的信息流中。
- 读取: 用户打开应用时,获取预先计算好或实时生成的信息流。
写时扩散(推模式): 在写入时预先计算信息流。读取快,但对于拥有数百万粉丝的用户(如明星)写入极慢。
读时扩散(拉模式): 在用户请求时生成信息流。写入快,但读取慢。
混合模式: 普通用户使用推模式,明星使用拉模式。
Part 2: Step-by-Step Implementation / 一步一步实现 (8 min)
[Client] --> [Load Balancer] --> [Web Servers]
|
+--------------------+--------------------+
| |
[Post Service] [Feed Service]
| |
[Fan-out Workers] [Feed Cache (Redis)]
| |
+------------+------------+ |
| | |
[Post DB] [Graph DB] [User Feed DB]
(Cassandra) (Followers) (Cassandra/Redis)
Flow Trace:
- User A posts a message -> Post Service.
- Post Service saves to Post DB, sends event to Fan-out Workers.
- Fan-out Workers fetch User A's followers from Graph DB.
- Workers push the post ID to each follower's Feed Cache.
- User B (a follower) requests feed -> Feed Service.
- Feed Service reads User B's Feed Cache (list of post IDs), fetches post details from Post DB, and returns to Client.
代码模拟 (Python-like Pseudocode):
class NewsFeedSystem:
def __init__(self):
self.post_db = {} # post_id -> post_data
self.feed_cache = {} # user_id -> list of post_ids
self.followers_db = {} # user_id -> list of follower_ids
def publish_post(self, user_id, post_id, content):
# 1. Save post
self.post_db[post_id] = {"author": user_id, "content": content}
# 2. Fan-out (Push model)
followers = self.followers_db.get(user_id, [])
for follower in followers:
if follower not in self.feed_cache:
self.feed_cache[follower] = []
# Prepend to feed cache
self.feed_cache[follower].insert(0, post_id)
def get_feed(self, user_id):
# 1. Fetch post IDs from cache
post_ids = self.feed_cache.get(user_id, [])
# 2. Hydrate posts
feed = []
for pid in post_ids:
feed.append(self.post_db[pid])
return feed
Part 3: Edge Cases & Gotchas / 边界情况 (2 min)
- The Celebrity Problem (Hotkey issue): A celebrity with 100M followers posting a tweet will crash the fan-out workers. Use a hybrid approach: don't push celebrity posts; instead, when a user loads their feed, pull the celebrity's recent posts and merge them.
- Cache Eviction: Only keep the top ~1000 posts in the Redis feed cache. Older posts can be fetched from the database if the user scrolls that far.
- 明星问题(热点问题): 拥有上亿粉丝的明星发帖会压垮 Fan-out 工作节点。解决方案是混合模式:不主动推送明星的帖子,而是在用户刷信息流时,拉取明星的最新帖子并进行合并。
- 缓存淘汰: Redis 中只保留最近的 1000 条动态。如果用户继续向下滚动,再从数据库中读取。
Part 4: Real-World Application / 实际应用 (2 min)
- Twitter / X: Uses a massive Redis cluster for timeline caching. They heavily optimize the fan-out process for different tiers of users.
- Instagram / Facebook: Uses similar hybrid models but with complex machine learning ranking algorithms on top of the chronological feed.
- Twitter / X: 使用庞大的 Redis 集群进行时间线缓存,并针对不同层级的用户深度优化 fan-out 流程。
- Instagram / Facebook: 使用类似的混合模式,但在时间线基础上增加了复杂的机器学习排序算法。
Part 5: Interview Simulation / 面试模拟 (3 min)
- Q: How do you handle media (images/videos) in posts?
A: Store media in object storage (S3) and use a CDN. The Post DB only stores URLs to the media.
- Q: What database is best for storing the feed?
A: Cassandra or DynamoDB (NoSQL) is excellent for heavy write workloads and time-series data.
- Q: How do you implement feed ranking (non-chronological)?
A: The feed service passes the fetched posts to a Ranking Service (ML model) before returning them to the user.
- Q: What happens if a fan-out worker fails?
A: Use a message queue (Kafka/RabbitMQ) for fan-out tasks. If a worker dies, another worker picks up the unacknowledged message.
- Q: How to reduce memory usage in the feed cache?
A: Store only [post_id, user_id] in the cache, not the full post content. Hydrate the content during the read phase.