网站的消息提醒一般都是采用的是刷新页面,查询消息表,看是否有新信息。或者使用ajax轮询、长轮询等。再就是近年兴起的Html5中的websocket。
文章来自ruesin.com
我们本文只是肤浅的猜测学习一下新浪微博发送和新微博大概模式。至于架构和服务器的负载等,持续学习中。
本文只是大概学习了下,文章最后的参考文档讲的更详尽细致,一味的复制过来,显得啰嗦又反感,倒不如留给有心人士继续研究。
前段时间看微博的新微博提醒,firebug中看不到请求,未读微博就过来了。然后用网络抓包看了下,其实页面打开之后有定时请求 http://rm.api.weibo.com/remind/unread_count.json 这个地址。
本文来自Ruesin博客http://rm.api.weibo.com/2/remind/push_count.json?trim_null=1&with_settings=1&exclude_attitude=1&with_common_cmt=1&with_comment_attitude=1&with_common_attitude=1&with_moments=1&with_dm_unread=1&msgbox=true&with_page_group=1&with_chat_group=1&with_chat_group_notice=1&_pid=1&count=3&source=3818214747&status_type=0&callback=STK_143020455030438
查到的大部分文章说的理论都是:推和拉(按时间分区)的结合。
推的模式:
一条微博在我们系统发布之后,我们把它放在一个消息队列里面,然后会有一个消息队列的处理程序把它拿过来,处理以后放到db里面,然后程序会将数据传送到后台引擎里,引擎会把用户的关系拿过来,然后按照用户关系马上推送给他相应的粉丝。
假设一个用户A,有100W粉丝,A发表一条微博,这就触发了一个事件,服务将这条微博消息的时间点攒成100W份多播分发下去,放入缓存。
拉的模式:
某粉丝B登录微博首页后,会将所有关注好友的微博拉出来。定时请求缓存,按时间偏移查出未读微博数量。
简单看这个例子应该很容易理解,可能也觉得恍然大悟,我们继续看文档,会发现这些仅仅算是最初版本的设计,后续各版本的更新都做了很大的优化,而我们本文只对着发送和接受微博学习,其他的稍后研究。
以下仅仅是我将原文中的自己理解的点转化成自己的话来复述了一遍。
一、投递模式的优化
推模式的优化,主要做的就是把粉丝分为的有效用户和无效用户。及时推送的只是给有效用户,另外不在线或者近期不活跃的用户,就不做推送,而是等他们登录或活跃后采取拉的模式拉去信息。
二、数据的拆分
微博用户及数据量那么大,你很难想像将数据集中在一起会产生怎样的结果。我们平时做产品,数据拆分大部分都是按照主键ID进行拆的。而微博新鲜事等都是按照时间来分的,所以微博的数据也是按照时间进行拆分的。比如说一个月发一张表,这样就解决了我们不同时间的惟度可以有不同的拆分方式。
然后我们惯用的招数也就是将内容和索引拆表。拆分之后的内容就简单的变成了一种key-value的方式,key-value是最容易扩展的一种数据。
最后在原来索引的基础上,做了二次索引,数据还是按照时间拆分,但是会把每个月记录的偏移记下来,也就是每月发表了多少条微博。这样可以为前端分页很快的定位那一页发表的是哪些内容。
三、异步处理
微博发表是一个非常繁重的操作,它要入库、统计索引、进入后台,如果我们要把所有的索引都做完用户需要前端等待很长的时间,如果有一个环节失败的话,用户得到的提示是发表失败,但是入库已经成功。所以我们做了一个异步操作,就是发表成功我们就提示成功, 后台任务继续进行投递,消息队列里慢慢完成。
四、未读微博计数器的改进
新版我们改成了基于偏移的思路,就是一个用户他原来读的一个ID比如说是10000,系统最系的ID是10002的话,我们和清楚他有两条未读。原来的版本是采用绝对技术的,这个用户有几条未读都是用一个存储结构的话,就容易产生一致性的问题,采用这种偏 移的技术基本上不会出错。
用户的关注关系,我们改成一个多惟度的索引结构, 性能极大的提高。
微博第一版解决发布规模问题,第二版是解决数据规模的问题,第三版是解决服务化的问题。
参考文档:
微博feed系统的push和pull模式和时间分区拉模式架构探
请把最起码的版权请留给博主,谢谢!
转载请注明:微博推、拉结合按时间分区消息提醒模式的学习