背景
最近阅读了数据密集型设计这本书,书中的tweet的架构设计引起了我的兴趣,今天就来了解下tweet的架构设计
架构图
一.当一个用户有非常多的被关注者时,比如特朗普有上千万的粉丝,tweet采用的架构设计如图:
从这个图我们可以知道,当这些名人发布一条微博的时候,只需要把这个微博插入到tweets主表中,当其他用户登录时,如果这个用户关注了这个名人,会根据表的连接关系把名人的微博推送给用户,这个方案的缺点是:读取用户的关注微博内容需要通过表连接操作,当有大量用户登录时,对于DB而言是一个巨大的压力,该方案的特点是:写入负载低,数据没有冗余,但是读取负载相对较高.
二 普通用户发送推文时的架构图,普通用户一般来说拥有的关注者比较少,比如几十或者几百,所以一般采用如下架构图:
这里每个用户都有属于自己的收件箱,用来存放关注者的推文,当用户登录时,直接从收件箱中取出推文即可,不需要进行表连接操作,发布者发送推送时,会往所有订阅者的收件箱中插入一条推文内容,该方案的优点是:读取非常简单,只需要一条简单的sql语句,然而写入负载较大,因为写入推文时需要往所有订阅者的收件箱插入一条推文,当发布者有上千万的订阅者时(比如特朗普),那么写入的代价巨大,并且数据有冗余,所以采用该方案读取获得的性能提升需要能远远大于写入的性能消耗以及采取数据冗余导致的存储空间浪费
小结
tween综合了上述的两种方案:首先针对方案二对于名人写入负载高的特点,他把用户分成了两类,一种是名人(订阅者比较多),一种是普通用户(订阅者较小),对于名人,他会采用方案一,因为方案一的写入负载低,读的负载也还能接受,而大部分普通用户采用方案二,因为方案二读取性能高,写入代价也不大.
开放性话题
普通用户登录时,他是怎么知道要读取收件箱的内容,还是通过关联数据表的方式读取推文的内容?
我个人认为,单独读取收件箱的内容或者单独通过表连接读取推文的内容都是不完整的,如果用户关注的用户里面,有名人,也有普通的用户的话,需要把两者结合起来才是完整的内容,也就是说如果存在普通用户,那么第一步是读取收件箱的内容,然后第二步是通过表连接读取名人的推文,两者组合后返回,或者你认为如果这种架构下,如何用最简单的方式读取用户的推文数据呢?