深入浅出系统设计面试——Design Twitter Timeline

如何 design 一个 Twitter 类型的系统,尤其是其中的 timeline/tweets 的部分,这是很多朋友都会在面试中遇到的问题,包子君今天与大家快速分享一下。

首先,Twitter 绝对不是我们能在45分钟之内 design 出来的,除非你是 Twitter 的人出去面试……所以主要就是聊聊难点在哪里。

Home Timeline

社交类产品的一个最重要的 feature 就是 home timeline, 不管是微博、朋友圈、Facebook、Twitter, 只要你关注的人发了一条新消息,你的 home page 就应该快速更新显示。

当然,最 naive 的方案大家都能猜到:把消息存储设计成一个大 database, 每次用户刷新时就一堆 table 互相 join 来 join 去,然后 select + index. 但是你马上会发现当有大量用户同时刷新、或有大V发一条消息的时候,事情就变得比较微妙了,那么解决方案是什么呢?

下面的分析来自与 2012 年 Raffi 大神关于 twitter 设计的公开视频,点击“阅读原文”可查看 youtube 视频,还有包子君的大连话版的 leetcode 讲解哟。

  • 社交产品的一个重要特点就是 consumption heavy, but not production heavy. 举个例子:100 个用户在一个社交网络中,大约10个人主动发更新状态,10个人愿意评论别人的状态,剩下80个人则是默默的刷呀刷。这就是社交网络的特点,也决定了社交产品的系统架构应该集中优化“读”这个操作。
  • 既然每次刷新的速度越快越好,那么最快的方式自然是从服务器的内存中直接读取。事实上 twitter 就是这么干的:简单来说每个 user maintain 一个 queue 来保存用户收到的 tweet id / metadata,这个 queue 放在 redis cluster 里面 (redis 是一个in-memory datastore store), 所以读取的速度非常非常快,网络内的调用延迟在 400ms 左右,考虑到 twitter 的用户量,令人满意。
  • 当用户发一条 tweet, twitter 内部有一个 fanout process 来保证这条 twitter id / metadata 被写入每一个 user 的 queue 中 (in redis cluster). 比如 User A 有 10000 followers, 当 A 发一条 tweet, twitter 需要先通过一个单独的 social graph service, 查询 User A 的 10000 followers 以及每个人 queue 所在 redis cluster 的位置,然后插入 tweet id / metadata 到每一个 queue 中。

这种设计的方式最大程度的优化了”读/刷新“操作,但是“写操作”会相对复杂一些,这是典型的系统设计中的 trade-off. 当我们在面试中遇到系统设计类的问题是,一定要想清楚、或者问清楚系统最大的 scability issue 是什么,是读操作还是写操作,还是查询?只有搞清要解决的问题,我们才能更好的切入问题,进而解决之。
转自:包子铺里聊IT