微博首席架构师杨卫华:新浪微博技术架构分析

做为国内微博市场的绝对领军者,新浪微博公布一系列针对开发者的扶持政策,以期与第三方开发者联手推进微博行业的总体发展。前端

 

  如下为演讲实录:java

 

  你们下午好,在座的大部分都是技术开发者,技术开发者每每对微博这个产品很是关心。最晚的一次,是12点多收到一个邮件说想了解一下微博底层是怎么构架的。不少技术人员对微博的构架很是感兴趣,就是一个明星他有300万粉丝,这个技术怎么来实现?今天在这里跟你们分享一下微博的底层机构,让你们对微博的底层技术有更好的了解。另外无论是作客户端、Web 1.0、Web 2.0、论坛、博客都要考虑架构的问题,架构其实是有一些共性的。今天我经过讲解微博里面的一些架构,分析一下架构里面哪些共性你们能够参考。node

 

  首先给你们介绍一下微博架构发展的历程。新浪微博在短短一年时间内从零发展到五千万用户,咱们的基层架构也发展了3个大的版本。初版就LAMP架构,优势是能够很是快的实现咱们的系统。咱们看一下技术特色,微博这个产品从架构上来分析,它须要解决的是发表和订阅的问题。咱们初版采用的是推消息模式,假如说咱们一个明星用户他有10万个粉丝,那就是说用户发表一条微博的时候,咱们把这个微博消息存成10万份,这样就是很简单了,初版的架构实际上就是这两行字。初版的技术细节,典型的LAMP架构,是使用MyISAM搜索引擎,它的优势就是速度很是快。数据库

 

  另一个是MPSS,就是多个端口能够布置在同一服务器上。为何使用MPSS?假如说咱们作一个互联网应用,这个应用里面有三个单元,咱们能够由2种部署方式。咱们能够把三个单元分别部署在三台服务器上,另一种部署模式就是这三个单元部署在每一个服务器上都有。我推荐第2种方法。这个方法解决了两个问题,一个是负载均衡,由于每个单元都有多个节点处理,另一个是能够防止单点故障。若是咱们按照模式1来作的话,任何一个节点有故障就会影响咱们系统服务,若是模式二的话,任何一个结点发生故障咱们的总体都不会受到影响的。安全

 

  咱们微博初版上线以后,用户很是喜欢这个产品,用户数增加很是迅速。咱们技术上碰到几个问题。第一个问题是发表会出现延迟现象,尤为是明星用户他的粉丝多系统须要处理很长时间。另外系统在处理明星用户发表时系统繁忙可能会影响到其余的用户,由于其余的用户同一时间发表的话,也会受到这个系统的影响。咱们就考虑这个系统怎么改进。首先是推模式,这确定是延迟的首要缘由,咱们要把这个问题解决掉。其次咱们的用户愈来愈多,这个数据库表从一百万到一亿,数据规模不同处理方式是有差异的。咱们初版单库单表的模式,当用户数量增多的时候,它不能知足就须要进行拆分。第二个是锁表的问题,咱们考虑的是更改引擎。另一个是发表过慢,咱们考虑的是异步模式。服务器

 

  第二版咱们进行了模块化,咱们首先作了一个分层,最底层叫基础层,首先对数据作了拆分,图上最右边是发表作了异步模式。第二个服务层,咱们把微博基础的单元设计成服务层一个一个模块,最大改进是对推模式进行了改进。首先看一下投递模式的优化,首先咱们要思考推模式,若是咱们作一下改进把用户分红有效和无效的用户。咱们一个用户好比说有一百个粉丝,我发一条微博的时候不须要推给一百个粉丝,由于可能有50个粉丝不会立刻来看,这样同步推送给他们,至关于作无用功。咱们把用户分红有效和无效以后,咱们把他们作一下区分,好比说当天登录过的人咱们分红有效用户的话,只须要发送给当天登录过的粉丝,这样压力立刻就减轻了,另外投递的延迟也减少了。网络

 

  咱们再看数据的拆分,数据拆分有不少方式,不少互联网产品最经常使用的方法,好比说如能够按照用户的UID来拆分。可是微博用户的一个特色就是说你们访问的都是最近的数据,因此咱们考虑微博的数据咱们按照时间拆分,好比说一个月放一张表,这样就解决了咱们不一样时间的维度能够有不一样的拆分方式。第二个考虑就是要把内容和索引分开存放。假如说一条微博发表的uid,微博id是索引数据,140个字的内容是内容数据。假如咱们分开的话,内容就简单的变成了一种key-value的方式,key-value是最容易扩展的一种数据。索引数据的拆分具备挑战,好比说一个用户发表了一千条微博,这一千条微博咱们接口前端要分页访问,好比说用户须要访问第五页,那咱们须要迅速定位到这个记录。架构

 

  假如说咱们把这个索引拆分红一个月一张表,咱们记录上很难判断第五页在哪张表里,咱们须要加载全部的索引表。若是这个地方不能拆分,那咱们系统上就会有一个很是大的瓶颈。最后咱们想了一个方法,就是索引上作了一个二次索引,把每月记录的偏移记下来,就是一个月这个用户发表了多少条,ID是哪里,就是按照这些数据迅速把记录找出来。并发

 

  异步处理,发表是一个很是繁重的操做,它要入库、统计索引、进入后台,若是咱们要把全部的索引都作完用户须要前端等待很长的时间,若是有一个环节失败的话,用户获得的提示是发表失败,可是入库已经成功,这样会带来数据不一致问题。因此咱们作了一个异步操做,就是发表成功咱们就提示成功,而后在后台慢慢的消息队列慢慢的作完。另外新浪发表了一个很重要的产品叫作MemcacheQ,咱们去年作了一个对大规模部署很是有利的指令,就是statsqueue,适合大规模运维。负载均衡

 

  第二版咱们作了这些改进以后,微博的用户和访问量并无中止,还有不少新的问题出现。好比说系统问题,单点故障致使的雪崩,第二个是访问速度问题由于国内网络环境复杂,会有用户反映说在不一样地区访问图片、js这些速度会有问题。另一个是数据压力以及峰值,MySql复制延迟、慢查询,另外就是热门事件,好比说世界杯,可能会致使用户每秒发表的内容达到几千条。咱们考虑如何改进,首先系统方面容许任意模块失败。另外静态内容,第一步咱们用CDN来加速,另外数据的压力以及峰值,咱们须要将数据、功能、部署尽量的拆分,而后提早进行容量规划。

 

  另外一方面咱们还有平台化的需求,去年11月咱们就说要作开放平台,开放平台的需求是有差别的,Web系统它有用户行为才有请求,可是API系统特别是客户端的应用,只要用户一开机就会有请求,直到他关闭电脑这种请求一直会不间断的过来,另外用户行为很难预测。

 

  系统规模在持续的增大,另外也有平台化的需求,咱们新架构应该怎么作才能知足这些须要?咱们看一下同行,好比说Google怎么样考虑这个问题的?Google首席科学家讲过一句话,就是一个大的复杂的系统,应该要分解成不少小的服务。好比说咱们在Google.com执行一个搜索查询的话,实际上这个操做会调动内部一百多个服务。所以,咱们第三版的考虑就是先有服务才有接口最后才有应用,咱们才能把这个系统作大。

 

  如今咱们看一下第三版,首先咱们把底层的东西分红基础服务,基础服务里面有分布式的存储,咱们作了一些去中心化、自动化的操做。在基础服务之上有平台服务,咱们把微博经常使用的应用作成各类小的服务。而后咱们还有应用服务,这个是专门考虑平台各类应用的需求。最上面咱们有API,API就是新浪微博各类第三方应用都在上面跑。

 

  平台服务和应用服务是分开的,这样实现了模块隔离,即便应用服务访问量过大的话,平台服务不会首先影响。另外咱们把微博的引擎进行了改进,实现了一个分层关系。用户的关注关系,咱们改为一个多唯度的索引结构,性能极大的提升。第四个层面就是计数器的改进,新版咱们改为了基于偏移的思路,就是一个用户他原来读的一个ID好比说是10000,系统最系的ID是10002的话,咱们很清楚他有两条未读。原来的版本是采用绝对计数的,这个用户有几条未读都是用一个存储结构的话,就容易产生一致性的问题,采用这种偏移的技术基本上不会出错。

 

  另外基础服务DB冷热分离多维度拆分,在微博里面咱们是按照时间拆分的,可是一个大型的系统里面有不少业务须要有不一样的考虑。好比说私信这个就不能按照时间来拆分,这个按照UID来拆分可能更简单。而后咱们突出存储还作了一个去中心化,就是用户上传图片的速度会极大的提升,另外察看其余用户的图片速度也会极大的提升。另外是动态内容支持多IDC同时更新,这个是在国内比较新颖的。

 

  下面给你们介绍一下新浪微博怎么样打造一个高性能架构。到目前为止有五千万用户使用新浪微博,最高发表3000条以上每秒,而后一个明星用户发表的话,会被几百万用户同时读到。这些问题的本质是咱们架构须要考虑高访问量、海量数据的状况下三个问题。易于扩展、低延迟、高可用和异地分布。咱们天天有数十亿次外部网页以及API接口的需求,咱们知道微博的特色是用户请求是没法cache的。所以面对这个需求咱们怎么样扩展?几点思路。第一咱们的模块设计上要去状态,咱们任意一个单元能够支持任意节点。另外是去中心化,避免单点及瓶颈。另外是可线性扩展。最后一个是减小模块。

 

  咱们要作一个高性能的系统,要具有一个低延迟、高实时性,微博要作到高实时性这是核心的价值,实时性的核心就是让数据离CPU最近,避免磁盘的

 

  IO。咱们看淘宝核心系统专家余锋说过的一句话“CPU访问L1就像从书桌拿一本书,L2是从书架拿一本书,L3是从客厅桌子上拿一本书,访问主存就像骑车去社区图书馆拿一书”。咱们微博若是要作到很是实时的话,咱们就须要把数据尽可能离CPU节点最近。因此咱们看一下cache设计里面怎么达到这个目标。首先INBOX,这个数据咱们须要放再一个最快的地方,由于用户随时访问。OutBOX里面的最近发表就是L1cache,还有一个是中期的,这个由于访问少一点,它能够被踢。最后一部份内容体有三部分。L0是本地的,咱们须要把一些常常访问的,好比说明星发表微博的内容体本地化,由于它被访问的几率很是大。而后L1里面存放着最近发表的,还有一个是中期的。咱们一般用L2就能够了,L1咱们能够理解成它就是一个RAM存储。

 

  一个好的架构还须要举行高可用性。咱们看一下业界的指标,S3是99.9%,EC2是99.5%,咱们另一个同行Facebook在这方面它是没有承诺的,就是接口可用写。微博平台目前承诺的是99.95%,就是说一天365天故障率应该小于9小时。这个怎么达到?第一咱们要作容量规划,要作好监控以及入口的管理,就是说有些服务若是访问量过了的话,咱们要有一个开关能够拦住他。咱们经过这个图表能够清楚的看到,好比说咱们要作L1的cache,咱们剩余空间有多少,好比说80%,就说明这个数据有可能会丢失,有可能会对咱们的系统形成影响。

 

  另一个层面就是接口监控,咱们目前有Google维度的接口监控,包括访问错误失败率。而后要作架构,给你们一个很重要的经验分享,就是说监控的指标尽可能量化。好比说他延迟30秒是小问题,若是是延迟10分钟咱们就要当即采起措施了,就是全部能够量化的指标都要量化。

 

  而后咱们看监控怎么样更好的作?咱们看亚马逊的VP说过的一句话,就是说监控系统确实特别好,能够当即告诉咱们哪里有故障,可是有20%的几率咱们人是会出错的。因此咱们一个大型系统就应该要为自动化设计,就是说尽量的将一些运做自动化。好比说发布安装、服务、启用、中止。咱们再看另一句,Google的工程师是怎么作的。他是这么作的,好比说第一周是处理线上的业务,这一周他处理了不少事情,处理了不少系统的状况,剩下几周时间没有别的工做,他只要把这一周碰到的状况用程序的方法来解决,下次再碰到这种状况很简单的一个按钮就能够处理了。咱们目前也在向自动化这方面努力,就是咱们的工具在持续增长。

 

  另一个异地分布,在国内网络环境下,好比说IDC灾难,机房检修甚至是机房掉电,咱们也碰到过中国最好的机房也会掉电,因此要每一个服务单元都能支持多机房部署。另外作多机房部署有一个好处,就是用户的访问速度会提升。多IDC分布静态内容就不说了,基本上大的互联网公司都会作,它很是成熟基本上没有什么问题,好比说图片等等的静态内容。动态内容的CDN分布是业内的难点,国内不多有公司可以作到很是成熟的多机房动态内容发布的成熟方案,它的核心就是分布式存储。一款理想的分布式存储产品它有哪些需求呢?首先它要支持海量规模、可扩展、高性能、低延迟、高可用。第二个是须要多机房分布,可以知足国内负责的网络环境,还要具有异地容灾能力。第三个就是要调用简单,具有丰富数据库特性。所以分布式存储须要解决一个多对多的数据复制。

 

  若是要作复制无非是三种策略,第一个是Master/Slave,可是它也两个缺点,第一个是Master是中心化的,若是Master在北京那广州访问就很是慢。第二个缺点是有单点风险的,好比说Master在北京,能当即迁到广州吗?这样有个时间窗口的数据就丢失了,并且须要人工的干预,并且平常广州的用户访问北京的Master是有很大延迟问题的,因此通常来讲要作的很是优秀是不会考虑第一种方案的。第二种就是Multi-Master方案,它须要应用避免冲突,就是咱们不能多处改变。这个对于微博来讲不会特别难,咱们的用户一般只会再一个地方发表微博,用户不会同时在广州又在北京发表或者是修改本身的资料,这样的话咱们应用上就已经避免了这种状况。第三个就是Paxos就是能够达到强一致写,就是一条数据若是成功确定是多个机房都成功了,这个也显而易见就是延迟性很是大。所以总结一下Multi-Master是最成熟的策略,可是它如今没有成熟的产品,由于确实没有。

 

  咱们再来看微博的方案,因此咱们本身实现了一个多机房同步的方案。就是咱们前端应用将数据写到数据库,再经过一个消息代理,至关于经过咱们本身开发的一个技术,将数据广播到多个机房。这个不但能够作到两个机房,并且能够作到三个、四个。具体的方式就是经过消息广播方式将数据多点分布,就是说咱们的数据提交给一个代理,这个代理帮咱们把这些数据同步到多个机房,那咱们应用不须要关心这个数据是怎么样同步过去的。

 

  用这种消息代理方式有什么好处呢?能够看一下Yahoo是怎么来作的?第一个是数据提供以后没有写到db以后是不会消失的,我只要把数据提交成功就能够了,不须要关心数据怎么到达机房。第二个特色YMB是一款消息代理的产品,可是它惟一神奇的地方是为广域网设计的,它能够把多机房应用归到内部,咱们应用不须要关注这个问题。这个原理跟咱们目前本身开发的技术类似。

 

  而后咱们再看一下目前即将推出的微博平台的新架构。咱们知道API大部分的请求都为了获取最新的数据。API请求有一个特色,它大目前调用都是空返回的,好比说一款手机的客户端每隔一分钟它都要调用服务器一下,就是有没有新数据,大目前的调用都是空返回,就是说无论服务器有没有数据都要调用一次。此次询问到下一次询问中间,若是有新的数据来了,你是不会立刻知道的。所以咱们想API能不能改用推的方式,就是客户端不须要持续的调用,若是有新数据就会推过去。技术特色,显而易见低延迟,就是从发表到接受1秒内完成,实际上可能用不了1秒。而后服务端的链接就是高并发长链接服务,就是多点都链接在咱们的服务器上,这个比传统的API要大不少。

 

  咱们看一下推送架构怎么从架构底层作到实时性的。java培训机构从左上角的一条微博在咱们系统发布以后,咱们把它放在一个消息队列里面,而后会有一个消息队列的处理程序把它拿过来,处理之后放到db里面。假如说咱们不作持久化,由于咱们推送数据也不能丢失,咱们就要写一个很复杂的程序,将数据异步去存,这样就会很是复杂,并且系统也会有不稳定的因素。从另一个角度来讲,咱们作持久化也是作过测试的。咱们推送整个流程能够作到100毫秒和200毫秒之间,就是说咱们在这个时间能把数据推送出去。

 

  咱们再看一下内部细节,就是咱们收到数据以后首先要通过最上面RECEIVER。而后推到咱们的引擎里面,这个引擎会作两个事情,首先会把用户的关系拿过来,而后按照用户关系立刻推送给他相应的粉丝。因此咱们调用方已经在那儿等待了,咱们须要有一个唤醒操做,就是说在接口这儿把它唤醒,而后把它发送过去。最后是一个高并发的长连服务器,就是一台服务器支持10万以上的并发链接。最右边中间有一个圆圈叫作Stream Buffer,咱们须要Stream Buffer是要保存用户最近的数据。由于用户可能会有断线的,好比说他发送数据的时候断线半分钟,咱们须要把这半分钟补给他。这就是咱们的推送架构。

 

  下面介绍一下平台安所有分。因为咱们的接口是彻底开放的,因此咱们要防范不少恶意行为,有不少人担忧咱们接口是开放的,是否是有人经过这个接口发垃圾广告,或者是刷粉丝,咱们技术架构怎么来防范这一点呢?这是咱们的安全架构,作了三个层面的事情。最上面是咱们有一个实时处理,好比说根据频度、内容的类似性来进行判断,判断发的是否是广告或者是垃圾内容。中间这个是一个日志处理器,咱们会根据一些行为进行判断,好比说若是咱们只是实时拦截的话,有些行为很难防止,咱们作了个离线纠正的模块,好比说他潜伏的几个月开始发广告了,咱们能够过后把这些人清除掉,以保证咱们平台的健康。最后是经过监控的维度来保证内容的安全。目前内容安全的架构大概是541的体系,就是说咱们的实时拦截能够作到50%的防止,离线分析大概能够作到40%的防止。

 

  微博平台须要为用户提供安全及良好的体验应用,以及为开发者营造一个公平的环境,因此咱们的接口须要清晰安全的规则。从一个APP调用咱们的接口,须要几个阶层,须要划分不一样的业务模块。第二个是安全层。第三个是权限层。这是咱们平台安全的两个维度,一个接口安全,一个是内容安全。

 

  我今天讲的是架构方面的问题,在座大部分是开发者,可能你们都在处理不一样的架构问题,架构不少地方是相通的。咱们须要作一个软件系统须要解决的本质问题是什么?微博初版解决发布规模问题,第二版是解决数据规模的问题,第三版是解决服务化的问题。将复杂的问题简单化以后,咱们才能够设计出一个容易扩展的大规模架构。我今天介绍就这么多,咱们微博其实是很须要各方面的技术人员,你们对咱们的架构若是感兴趣的话、对咱们的系统感兴趣的话,也但愿各方面的技术人员参与咱们微博的团队,随时能够给我微博上发私信。

相关文章
相关标签/搜索