微博feed系统的推(push)模式和拉(pull)模式和时间分区拉模式架构探讨

转载自:http://www.cnblogs.com/sunli/archive/2010/08/24/twitter_feeds_push_pull.htmlhtml

 

sns系统,微博系统都应用到了feed(每条微博或者sns里的新鲜事等咱们称做feed)系统,不论是twitter.com或者国内的新浪微博,人人网等,在各类技术社区,技术大会上都在分享本身的feed架构,也就是推拉模式(timyang上次也分享了新浪微薄的模式)。下面咱们就微博的feed推拉(push,pull)模式作一下探讨,并提出新的时间分区拉模式。数据库

      众所周知,在微博中,当你发表一篇微博,那么全部关注你的followers(粉丝)都会在必定的时间内收到你的微薄,这有点像群发一封邮件,全部的抄送者都会在必定的时间内收到。到这里,你可能以为没有什么难度。咱们看下下面的截图:缓存

     

       图一:新浪微博姚晨
数据结构

         图二:twitter上冯大辉架构

     新浪微博的姚晨粉丝有2594751,她发表任何一篇微博,都须要2594751个粉丝在必定的时间内收到,twitter的冯大辉发表一篇的话,须要19868个followers收到。memcached

     相反,姚晨须要收到他关注的545我的的全部更新,冯大辉须要收到他关注的2525我的的全部更新。到这里,你是否是感受到有那么一点点小挑战呢?性能

     下面咱们看下微博通常的总体结构图:优化

      

                 图三:微博总体结构ui

       图中展现了微博的总体数据流程,先了解下总体的数据结构,没有涉及到followers等的推拉模式处理。下面咱们再看下推模式(push):spa

          图四:推模式结构

   推模式须要把一篇微博推送给全部关注他的人(推给全部的粉丝),好比姚晨,咱们就须要推送给2594751个用户的feeds表中。固然,feeds表能够很好的进行sharding(数据库分片),存储也都是一些数字型的字段,存储空间可能不是很大,用户在查询本身关注的全部人的feed时,速度快,性能很是高(查询快),可是推送量会很是大,姚晨发表一篇,就会产生200多万条数据(写扩散)。试想,一个大量用户的微薄系统经过使用推模式,是否是会产生很是惊人的数据呢?

    下面看下拉模式(pull)

            图五:拉模式

     拉模式只须要用户发表微博时,存储一条微博数据到feeds表中(feeds表能够是一个临时表,只保存近期可接受范围的数据).用户每次查询feed时都会去查询feeds表(读扩散)。好比姚晨打开本身的微薄首页,就产生:SELECT id FROM feeds where uid in(following uid list) ORDER BY id DESC LIMIT n(查询最新的n条),缓存到memcached

uidlist=>{data:id list,timeline:上次查询出来的最新的一条数据的时间}

再次刷新:SELECT id FROM feeds where uid in(following uid list) AND timeline>(memcached存储的上次的timeline) ORDER BY id DESC LIMIT n

 

    这种模式实现起来也是比较简单和容易的,只是在查询的时候须要多考虑下缓存的结构。可是feeds表会产生很大的压力,怎么说feeds表也要保存最近十天半个月的数据吧,对于一个大点的系统,这会产生比较大的数据,若是following的人数比较多,数据库的压力就会很是大。并且通常在线的用户,客户端都会按期扫描,又会增长很大的压力,这在查询性能上没有推模式的效率高。

     下面咱们在对拉模式作一下改进优化

     

           图五:拉模式(pull)-改进(时间分区拉模式)

           拉模式的改进主要是在feeds的存储上,使用按照时间进行分区存储。分为最近时间段(好比最近一个小时),近期的,比较长时期等等。咱们再来看下查询的流程,好比姚晨登录微博首页,假设缓存中没有任何数据,那么咱们能够查询比较长时期的feeds表,而后进入缓存。下一次查询,经过查询缓存中的数据的timeline,若是timeline还在最近一个小时内,那么只须要查询最近一个小时的数据的feed表,最近一个小时的feeds表比图四的feeds表可要小不少,查询起来速度确定快几个数量级了。

          改进模式的重点在于feeds的时间分区存储,根据上次查询的timeline来决定查询应该落在那个表。通常状况下,常常在线的用户,频繁使用的客户端扫描操做,常常登陆的用户,都会落在最近的feeds表区间,查询都是比较高效的。只有那些十天,半个月才登陆一次的用户须要去查询比较长时间的feeds大表,一旦查询过了,就又会落在最近时间区域,因此效率也是很是高的。

         关于时间的分区,须要根据数据量,用户访问特色进行一个合理的切分。若是数据发表量很是大,能够进行更多的分区。

        上面介绍的推模式和拉模式都有各自的特色,我的以为时间分区拉模式弥补了图四的拉模式的很大的不足,是一个成本比较低廉的解决方案。固然,时间分区拉模式也能够结合推模式,根据某些特色来增长系统的性能。

        后记:本文的目的是介绍时间分区拉模式,本人对新浪微博和twitter等的推拉模式的细节并不清楚。

相关文章
相关标签/搜索