一、twitter的核心业务
twitter的核心业务,在于following和be followed
(1)following-关注进入个人主页,会看到你follow的人发表的留言(不超过140个字),这是following的过程;
(2)followed-被关注你发布一条留言,follow你的人将看到这条信息,这是be followed的过程;
二、twitter的业务逻辑
twitter的业务逻辑也不复杂。
following业务,查follow了哪些人,以及这些人发表的留言;
followed业务,前端js轮询后端,看follow了的人有没有新留言,有则更新(更新及时性取决于轮询时间);
三、三层架构(three-tier architecture)
网站的架构设计,传统的做法是三层架构,所谓“传统”不意味着“过时”,新潮的技术不成熟,传统的路子更稳健。
(1)表示层(presentation tier):apache web server,主要任务是解析http协议,将请求分发给逻辑层;
(2)逻辑层(logic tier):mongrel rails server,利用rails现成的模块,降低工作量;
(3)数据层(data tier):mysql;
表示层:表示层的主要职能有2个:(1)http协议处理(http processor);(2)分发器(dispatcher);当然,访问twitter的不仅仅是浏览器,可能还有手机,由于可能存在其他协议,故可能存在其他processor。
逻辑层:当用户发布消息时,依次执行:(1)存消息至msg表;(2)查用户relation表,找出其followed_ids;(3)获取followed_ids中用户的状态;(4)在线的ids,将消息push进一个队列queue;(5)queue中的msg,更新ids的主页;这里面要用到队列,其实现方式有很多种,例如apache mina,twitter团队自己实现了一个kestrel。
数据层:twitter的核心是用户;消息;用户关系。围绕这几个核心,其核心数据的schema设计:(1)用户表userid, name, pass, status, …(2)消息表msgid, author_id, msg, time, …(3)用户关系表relationid, following_ids, followed_ids。
无论如何,架构框架清晰如下:
四、cache=cash即缓存等于收入
cache的使用对大型网站架构至关重要,网站响应速度是影响用户体验最明显的因素,而影响响应速度最大的敌人又是磁盘I/O。twitter工程师认为,良好体验的网站平均响应时间应该在500ms左右,理想的时间是200-300ms。关于cache的使用,是twitter架构的一大看点,带cache的架构清晰如下:
哪里需要cache?IO越频繁的地方,越需要cache。数据库是IO访问最频繁处,三大核心表是否有必要放入内存中?twitter的做法是,将表拆分,将其中访问最频繁的字段装入cache。
(1)vector cache and row cache即数组cache与行cache
数组缓存:新发表消息的msgids,相关作者的ids,这些id的访问频率很高,存放它们的cache称为vector cache;
行缓存:消息正文的行cache;内存有限的情况下,优先vector cache,实际结果vector cache的命中率是99%,row cache为95%;
(2)fragment cache and page cache
访问twitter的用户除了网页(web通道),还有手机(API通道),而后者的比例占总流量的80%-90%。mysql cache之外,cache的重心会在API通道上。手机屏幕的主体,是一屏一屏的消息,不妨把整个页面分割成若干局部,每个局部对应一些/一条消息,这些就是fragment。人气高的作者,缓存其页面的fragment,可以提高读取其发布消息效率,这就是fragment cache的使命。人气旺的作者,人们也会访问其主页,这就是page cache的使命。实际结果,fragment cache的命中率为95%,page cache为40%。虽然page cache的命中率低,但由于是访问主页,其占用的空间是很大的,为了防止两种cache相互影响,这两种cache需要部署在不同的物理机器上。twitter的fragment cache和page cache都是使用的memcached。
(3)http accelerator加速器
web通道的缓存问题也需要解决,分析之后,web通道的压力主要来自搜索。面临突发事件时,读者们会搜索相关信息,而不会理会这些信息的作者是不是自己follow的那些人。为了降低搜索压力,可以将搜索关键词与搜索内容cache起来。这里,twitter的工程师使用了varnish。有趣的是,varnish通常部署在web server外层,先访问varnish,其中没有相关的内容,才访问web server;twitter的工程师却将varnish放在apache web server的内层,原因是他们认为varnish操作复杂,担心varnish崩溃造成系统的瘫痪,故采用了这种保守型部署方式。twitter没有公开varnish的命中率,他们声称,使用了varnish之后,整站的负载下降了50%。
五、抗洪需要隔离
twitter架构的另一大看点是其消息队列:隔离用户的操作,将流量高峰摊平。
餐厅客满时,对于新来的顾客,虽然不能服务,但不是拒之门外,而是让他们现在休息厅等待。
用户访问twitter时,接待他的是apache web server,而apache不能接待无限多的用户。2009年1月20日,奥巴马发表就职演说,twitter流量猛增,此时如何是好。
面对洪峰,如何保证网站不奔溃?迅速接纳,但推迟服务。
apache收到请求,转发给Mongrel,由Mongrel负责实际处理,apache则腾出手来,迎接下一位用户。但apache能够接待的用户数总是有限的,它的并发数受apache能够容纳的工作进程数量,这里不细究apache内部原理,图如下:
六、数据流与控制流
快速接纳,推迟服务,只是缓兵之计,目的是让用户不至于收到503(service unavailable)。
真正的抗洪能力,体现在蓄洪与泄洪两个方面:
(1)twitter有庞大的memcached集群,能大容量蓄洪;
(2)twitter自己的kestrel消息队列,作为引流泄洪手段,传递控制指令(引流和渠道);洪峰到达时,twitter控制数据流,将数据及时疏散到多个机器,避免压力集中,造成系统瘫痪。
下面举例说明twitter内部流程,假设有两个作者,通过浏览器发消息,一个读者也通过浏览器阅读他们的消息。
(1)登陆apache web server,apache分配一个工作进程为其服务,登陆,查id,写cookie等;
(2)上传新写的消息,把作者id,消息等转发给Mongrel,apache等待Mongrel回复,以便更新作者主页,将新写的消息更新上去;
(3)Mongrel收到消息后,分配一个msgid,将msgid与作者id等缓存到vector memcached上去;同时,Mongrel让vector memcached查找作者被哪些人follow,缓存如果没有命中会去后端mysql查找,并入cache;读者ids会返回给Mongrel,Mongrel把msgid与短信正文缓存至row memcached;
(4)Mongrel通知kestrel消息队列服务器,每个作者及读者都有一个队列(没有则创建);Mongrel将msgid放入读者的队列,以及作者本人的队列;
(5)某一台Mongrel,它可能正在处理某一个id的队列,就会往返回该id用户的主页上添加上此条信息;(6)Mongrel将更新后作者的主页给前端等待着的apache,apache则返回浏览器。
七、洪峰与云计算
不细说了,洪峰扛不住时,只能加机器。机器哪里来?租云计算平台公司的设备。当然,设备只需要在洪峰时租用,省钱呀。
八、push与pull的折衷
可以看到,Mongrel的工作流程:
(1)将相关ids放入vector memcached和row memecached就算消息发布成功,而不负责mysql数据库的存入;
(2)将相关msgid放入kestrel消息队列就算消息推送成功;Mongrel没有使用任何方式去通知作者、读者,让他们重新拉取消息。
上述工作方式,反映了twitter架构设计分拆的理念:
(1)将一个完整的流程分拆成独立工作的子流程,一个工作可以由各个服务负责(三层架构本身是一种分拆);
(2)多机器之间协作,细化数据流与控制流,并强调其分离;
twitter业务流程的分隔,是一种事件驱动式的设计,主要体现在两个方面:
(1)Mongrel与mysql的分离,前者不直接插手mysql的操作,而委托memcached全权负责;
(2)上传、下载逻辑分离:只通过kestrel队列来传递指令;
每时每刻都有用户在Twitter上发表内容,Twitter工作是规划如何组织内容并把它发送用户的粉丝。
实时是真正的挑战,5秒内将消息呈现给粉丝是现阶段的目标。
投递意味着内容、投入互联网,然后尽可能快的发送接收。
投递将历时数据放入存储栈,推送通知,触发电子邮件,iOS、黑莓及Android手机都能被通知到,还有短信。
Twitter是世界上活跃中最大的信息发送机。
推荐是内容产生并快速传播的巨大动力。
两种主要的时间轴:用户的及主页的。
用户的时间轴特定用户发送的内容。
主页时间表是一段时间内所有你关注用户发布的内容。
线上规则是这样的:@别人是若被@的人你未关注的话将被隔离出来,回复一个转发可以被过滤掉。
这样在Twitter对系统是个挑战。
1.Pull模式
有针对性的时间轴。像twitter.com主页和home_timeline的API。你请求它才会得到数据。拉请求的不少:通过REST API请求从Twitter获取数据。
查询时间轴,搜索的API。查询并尽可能快的返回所有匹配的推特。
2.Push模式
Twitter运行着一个最大的实时事件系统,出口带宽22MB/秒。
和Twitter建立一个连接,它将把150毫秒内的所有消息推送给你。
几乎任何时候,Push服务簇上大约有一百万个连接。
像搜索一样往出口发送,所有公共消息都通过这种方式发送。
不,你搞不定。(实际上处理不了那么多)
用户流连接。 TweetDeck 和Twitter的Mac版都经过这里。登录的时,Twitter会查看你的社交图,只会推送那些你关注的人的消息,重建主页时间轴,而不是在持久的连接过程中使用同一个时间轴 。
查询API,Twitter收到持续查询时,如果有新的推特发布并且符合查询条件,系统才会将这条推特发给相应的连接。
3.高观点下的基于Pull(拉取方式)的时间轴:
短消息(Tweet)通过一个写API传递进来。通过负载平衡以及一个TFE(短消息前段),以及一些其它的没有被提到的设施。
这是一条非常直接的路径。完全预先计算主页的时间轴。所有的业务逻辑在短消息进入的时候就已经被执行了。
紧接着扇出(向外发送短消息)过程开始处理。进来的短消息被放置到大量的Redis集群上面。每个短息下在三个不同的机器上被复制3份。在Twitter 每天有大量的机器故障发生。
扇出查询基于Flock的社交图服务。Flock 维护着关注和被关注列表。
Flock 返回一个社交图给接受者,接着开始遍历所有存储在Redis 集群中的时间轴。
Redis 集群拥有若干T的内存。
同时连接4K的目的地。
在Redis 中使用原生的链表结构。
假设你发出一条短消息,并且你有20K个粉丝。扇出后台进程要做的就是在Redis 集群中找出这20K用户的位置。接着它开始将短消息的ID 注入到所有这些列表中。因此对于每次写一个短消息,都有跨整个Redis集群的20K次的写入操作。
存储的是短消息的ID, 最初短消息的用户ID, 以及4个字节,标识这条短消息是重发还是回复还是其它什么东东。
你的主页的时间轴驻扎在Redis集群中,有800条记录长。如果你向后翻很多页,你将会达到上限。内存是限制资源决定你当前的短消息集合可以多长。
每个活跃用户都存储在内存中,用于降低延迟。
活跃用户是在最近30天内登陆的twitter用户,这个标准会根据twitter的缓存的使用情况而改变。
只有你主页的时间轴会存储到磁盘上。
如果你在Redis 集群上失败了,你将会进入一个叫做重新构建的流程。
查新社交图服务。找出你关注的人。对每一个人查询磁盘,将它们放入Redis中。
MySQL通过Gizzard 处理磁盘存储,Gizzard 将SQL事务抽象出来,提供了全局复制。
通过复制3次,当一台机器遇到问题,不需要在每个数据中心重新构建那台机器上的时间轴。
如果一条短消息是另外一条的转发,那么一个指向原始短消息的指针将会存储下来。
当你查询你主页的时间轴时候,时间轴服务将会被查询。时间轴服务只会找到一台你的时间轴所在的机器。
高效的运行3个不同的哈希环,因为你的时间轴存储在3个地方。
它们找到最快的第一个,并且以最快速度返回。
需要做的妥协就是,扇出将会花费更多的时间,但是读取流程很快。大概从冷缓存到浏览器有2秒种时间。对于一个API调用,大概400ms。
因为时间轴只包含短消息ID, 它们必须”合成”这些短消息,找到这些短消息的文本。因为一组ID可以做一个多重获取,可以并行地从T-bird 中获取短消息。
Gizmoduck 是用户服务,Tweetypie 是短消息对象服务。每个服务都有自己的缓存。用户缓存是一个memcache集群 拥有所有用户的基础信息。Tweetypie将大概最近一个半月的短消息存储在memcache集群中。这些暴露给内部的用户。
在边界将会有一些读时过滤。例如,在法国过滤掉纳粹内容,因此在发送之前,有读时内容剥离工作。
Twitter,架构
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]