A30 · Design Instagram (Feed Generation) A30 · 设计 Instagram(信息流生成)
Verified source经核实出处
小红书 @OA昨日下雨 (2026): Anthropic VO1 System Design was "Design Instagram." The interviewer asked for overall architecture → then pressed hard on feed generation and celebrities with millions of followers. The candidate's accepted answer: hybrid (push for normal accounts, pull for celebrities). Credibility C (candidate-attributed, 2026).来自小红书 @OA昨日下雨(2026):Anthropic VO1 SD 题为 "Design Instagram"。面试官要求整体架构后主打追问 feed 生成 和 百万粉明星 的处理。候选人采纳答案:hybrid(普通用户 push,明星 pull)。可信度 C(候选人自述,2026)。
Scope: focus on the feed, not the whole product范围:聚焦信息流,不是整个产品
Instagram has photo upload, stories, reels, DMs, explore. In a 45-min SD, scope to: post creation, home feed generation, follow/unfollow. Mention others briefly. Explicitly name the bottleneck you're going to design around: home feed read latency at 10⁹ followers / post.Instagram 有图片上传、Stories、Reels、DM、Explore。45 分钟 SD 建议收敛到 发帖、主页信息流生成、关注/取消关注。其他轻提即可。直接点出要优化的瓶颈:头部用户单条帖子的 10⁹ 粉丝主页 feed 读延迟。
Data model数据模型
User(user_id, name, follower_count, is_celebrity)
Post(post_id, author_id, media_url, caption, created_at)
Follow(follower_id, followee_id, created_at) -- partition by follower_id for "whom I follow"
-- secondary partition by followee_id for "my followers"
Feed(user_id, post_id, rank_score, inserted_at) -- materialized home feed (push model)
Feed generation: the three models + whenFeed 生成:三种模式与适用场景
| Model | Write cost | Read cost | Good for |
|---|---|---|---|
| Pull / fan-out-on-read | O(1) | O(F) — fetch from each followee; rank; return.O(F) — 遍历每个关注对象拉取;排序;返回。 | Users who follow few or who read rarely.关注数少或阅读稀疏的用户。 |
| Push / fan-out-on-write | O(followers) — write to each inbox.O(粉丝数) — 写入每个粉丝 inbox。 | O(1) | Normal users (few thousand followers).普通用户(几千粉丝)。 |
| Hybrid | Push for normal; skip push for celebrity posts.普通用户 push;明星帖子不 push。 | Merge materialized inbox + pulled celebrity posts at read time.读时合并已物化 inbox 与拉取的明星帖子。 | Production reality.生产最优解。 |
The exact answer to "how do you handle celebrities?"对「明星怎么办?」的标准答案
"Pure push would make celebrity writes catastrophic — a single post fans out to 10⁸ inboxes. Pure pull hurts every user's read latency. I'd use a hybrid: flag is_celebrity above some follower threshold (e.g., 100K). For celebrities, skip the push: their posts stay in their own timeline only. At feed-read time, take the pre-materialized inbox (normal authors) and pull from celebrities the user follows, merge, rank, paginate. Cache the merged feed per user for 30–60 s.""纯 push 会让名人写入灾难——单帖扇出到 10⁸ inbox。纯 pull 损害每个用户的读延迟。采用 hybrid:超过阈值(如 10 万粉丝)标记为 is_celebrity。名人帖子不做 push,只留在自己的时间线。读 feed 时:取已物化 inbox(普通作者)+ 从用户关注的名人拉取,合并、排序、分页。按用户缓存合并后的 feed 30–60 秒。"
Architecture架构
flowchart LR
U[Uploader] --> MS[Media Service] --> OBJ[(S3 / CDN)]
MS --> PS[Post Service] --> PDB[(Posts DB)]
PS --> K[Kafka: new_post]
K --> FAN{is_celebrity?}
FAN -- No --> FO[Fan-out Workers
batched inserts] --> FDB[(Feed / inbox store)]
FAN -- Yes --> SKIP[(No fan-out; posts stay in author timeline)]
R[Reader] --> FS[Feed Service]
FS --> FDB
FS --> CEL[Celebrity-timeline cache
per user's followed celebs]
FS --> RANK[Ranker
recency + engagement]
FS --> C[(Per-user feed cache)]
Read-scaling the database (the documented follow-up)数据库读扩展(帖子提到的追问)
- Read replicas + routing: most feed reads can tolerate replica lag of seconds; route authenticated "my feed" to replicas.读副本 + 路由:feed 读普遍能容忍秒级副本滞后;鉴权后的「我的 feed」走副本。
- Shard by user_id for Follow and Feed tables (each user's inbox co-located).按 user_id 分片 Follow 与 Feed 表(每用户 inbox 局部化)。
- Hot-key caching: celebrity timelines are the worst hotspots — cache their recent posts in Redis with tight TTL; pre-warm via cache-aside on post.热 key 缓存:名人时间线是最严重热点——用 Redis 短 TTL 缓存近期帖;发帖时 cache-aside 预热。
- Materialize top-N per user: last 500 feed items; beyond that, lazy pull.每用户仅物化 top-N:最近 500 条;更久的惰性拉取。
- Tiered storage: hot (7d) in SSD / KV; warm (90d) in columnar; cold in object store.分层存储:热(7 天)在 SSD/KV;温(90 天)在列存;冷在对象存储。
Ranking (just enough)排序(够用即可)
Score each candidate post with recency × engagement × affinity. Train a lightweight two-tower model offline; serve features from a feature store; score top ~300 candidates per user online, return top 30.每个候选帖子用 时近性 × 互动度 × 亲密度 打分。离线训练轻量双塔;在线从特征平台取特征,打分前 ~300 候选,返回前 30。
Follow-ups追问
- Consistency of follow → feed? Eventual; but show a "Following → latest posts" link that pulls directly for freshness.关注→feed 的一致性?最终一致;UI 上提供「关注者最新」链接直接拉取以保新鲜。
- Unfollow cleanup? Lazy: don't delete existing inbox rows; filter by current follow set at read time (cheap with bloom).取消关注的清理?惰性处理:不清已有 inbox 行;读时按当前关注集过滤(bloom 很便宜)。
- Live sports / event spikes? Same as celebrity: pull-only for event-tagged accounts during the spike; fall back to hybrid post-event.大赛/事件尖峰?与名人同理:尖峰期相关账号仅走 pull;事件后恢复 hybrid。
- DAG-style follow graphs for stories? Separate store; stories aren't materialized per viewer — pulled from author and fanned into ephemeral cache.Stories 的关注图?独立存储;stories 不按观众物化——从作者拉取,fan 进瞬时缓存。
- Multi-device ordering? Client keeps a seen-cursor per device; server returns feed items strictly after cursor.多设备顺序?客户端每设备维护 seen cursor;服务端返回游标之后的 feed。