系统设计面试:设计Twitter

「设计Twitter」是动态生成问题的经典代表。它看起来很简单——发一条推文、读一条时间线——但真正有趣的部分,是如何在规模化场景下生成每个用户的主时间线,而正确答案是一种混合扇出策略。面试官想看到你发现两种朴素方案都会失效,并一步步推理出这种混合方案。

按部就班地推进:先明确需求,再估算读写比例,设计推文存储,然后设计时间线——比较写时扇出与读时扇出,并得出能处理名人问题的混合方案。下面的讲解遵循这条路径。

1. 明确需求

把范围限定在核心的动态问题上。用户发推文,关注他人,并阅读一条把所有关注对象的推文按最新优先合并起来的主时间线。

  • 功能性:发推文、关注/取消关注、主时间线(你关注的人)、用户时间线(某一位作者);基础搜索除非被要求,否则不在范围内。
  • 非功能性:读取非常密集、时间线读取低延迟、高可用性;时间线的最终一致性是可以接受的。
  • 需要澄清:媒体内容、回复/话题串以及排序——认可它们的存在,然后将本轮范围限定为按时间顺序排列的动态。

2. 估算规模与读写比例

这个比例驱动了整个设计。读取远远超过写入——用户刷时间线的频率远高于发帖的频率。在拥有数亿用户的情况下,系统必须让时间线读取变得廉价,即使这会让写入变得更昂贵。这一个观察就指向了预计算时间线这一方向。

3. 推文存储

推文本身是简单的、以追加写入为主的数据。把它们存储在按推文ID分区的水平分片存储中(使用类似Snowflake ID这样可按时间排序的ID,使顺序天然内嵌其中)。一个单独的社交图存储保存关注者/被关注者关系。

  • 推文:分布式存储,按推文ID分片;可按时间排序的ID能以低成本提供按时间顺序的排序。
  • 社交图:谁关注谁,针对「获取X的所有关注者」和「获取X关注的所有人」这两类查询做了优化。
  • 缓存(Redis)保存热数据——最近的推文和预计算好的时间线。

4. 时间线生成:写时扇出 对 读时扇出

这是问题的核心。写时扇出(推送)会在发帖时把每条新推文插入每个关注者预计算好的时间线列表中——时间线读取变成一次廉价的缓存查询,但拥有数百万关注者的人发一条帖子就会触发数百万次写入。读时扇出(拉取)会在读取时,把你关注的所有人最近的推文合并起来构建时间线——写入廉价,但对于关注大量账号的用户来说,读取会变得缓慢且昂贵。

  • 写时扇出:读取快,写入昂贵;非常适合普通用户。
  • 读时扇出:写入便宜,读取昂贵;对拥有海量关注者的账号是必要的。

5. 名人问题与混合方案

两种纯粹的方案都无法单独取胜,因此要把它们结合起来。对绝大多数用户使用写时扇出,但对拥有极大量关注者的「名人」账号,在写入时不要对其推文做扇出。相反,在读取时,把某个关注者预计算好的时间线与他所关注的少数几位名人的实时拉取结果合并起来。这样既能限制写入放大,又能保持读取速度——这正是面试官想听到的答案。

6. 需要说出来的权衡取舍

最后点明这些张力:写入放大与读取延迟(整个扇出决策)、预计算时间线的存储成本与重新计算它们之间的取舍,以及一致性——推文出现在关注者时间线中有几秒延迟是可以接受的,因此最终一致性让你能够扩展规模。明确说出混合方案的阈值(你如何界定「名人」)体现了资深的判断力。

借助实时辅助练习Twitter的系统设计

Natively的系统设计面试助手可以在实际面试中帮你保持结构清晰——实时建议接下来该覆盖哪个维度,并呈现权衡取舍,一切都在你自己的设备上完成。

Put it on your own machine.

A live-conversation assistant that runs locally. Nothing leaves your machine.

macOS 12+ · Windows 10/11

© 2026 Natively AI Private Limited

Source-available under the Natively Personal Use Source License v1.0 · IP geolocation by DB-IP