新浪微博技术架构分析和设计
新浪微博技术架构分析和设计
第⼀部分:新浪微博技术架构
新浪微博在2014年3⽉公布的⽉活跃⽤户(MAU)已经达到1.43亿,2014年新年第⼀分钟发送的微博达808298条,如此巨⼤的⽤户规模和业务量,需要⾼可⽤(HA)、⾼并发访问、低延时的强⼤后台系统⽀撑。
微博平台第⼀代架构为LAMP架构,数据库使⽤的MyIsam,后台⽤的php,缓存为Memcache。
随着应⽤规模的增长,衍⽣出的第⼆代架构对业务功能模块化、服务化、组件化,后台系统从php替换为Java,逐渐形成⾯向服务的SOA 架构,在很长⼀段时间⽀撑微博平台业务发展。
在此基础上⼜经过长时间的重构、线上运⾏、思索与沉淀,平台形成了第三代架构体系。
我们先看⼀张微博的核⼼业务图(如下),是不是⾮常复杂,但这已经是⼀个简化的不能再简化的业务图啦,第三代技术体系就是为了保障在微博核⼼业务上快速、⾼效、可靠的发布新产品新功能。
第三代技术体系
微博平台的第三代技术体系,使⽤正交分解法建⽴模型,在⽔平⽅向,采⽤典型的三级分层模型,即接⼝层、服务层与资源层,在垂直⽅向,进⼀步细分为业务架构、技术架构、监控平台与服务治理平台,接着看⼀下平台的整体架构图。
如上图所⽰,正交分解法将整个图分解为3*4=12个区域,每⼀个区域代表⼀个⽔平维度与⼀个垂直维度的交点,相应的定义这个区域的核⼼功能点,⽐如区域5主要完成服务层的技术架构,下⾯详细介绍⽔平⽅向与垂直⽅向的设计原则,尤其重点介绍4、5、6中的技术组件及其在整个架构体系中的作⽤。
⽔平分层
⽔平维度的划分,在⼤中型互联⽹后台业务系统的设计中⾮常基础,在平台的每⼀代技术体系中都有体现,这⾥还是简单介绍⼀下,为后续垂直维度的延伸讲解做铺垫:
1. 接⼝层主要实现与Web页⾯、移动客户端的接⼝交互,定义统⼀的接⼝规范,平台最核⼼的三个接⼝服务分别是内容(Feed)服务、
⽤户关系服务以及通讯服务(单发私信、发、聊)。
2. 服务层主要把核⼼业务模块化、服务化,这⾥⼜分为两类服务,⼀类为原⼦服务,定义是不依赖任何其他服务的服务模块,⽐如常⽤
的短链服务、发号器服务都属于这⼀类,图中使⽤泳道隔离,表⽰它们的独⽴性,另外⼀类为组合服务,通过各种原⼦服务和业务逻辑的组合,完成的Composite服务,⽐如Feed服务、通讯服务除了本⾝的业务逻辑,还依赖于短链、⽤户、以及发号器服务。
3. 资源层主要数据模型的存,包含通⽤的缓存资源Redis和MC,以及持久化数据库存储MySQL、HBase,或者分布式⽂件系统TFS以
及Sina S3服务。
⽔平分层有⼀个特点,依赖关系都是从上往下,上层的服务依赖下层,下层的服务不会依赖上层,构建了⼀种简单直接的依赖关系。
与分层模型对应的,微博系统中的服务器主要包括三种类型:前端机(提供 API 接⼝服务),队列机(处理上⾏业务逻辑,主要是数据写⼊),存储(mc、mysql、mcq、redis 、HBase等)。
垂直延伸技术架构
随着业务架构的发展和优化,平台研发实现了许多卓越的中间件产品,⽤来⽀撑核⼼业务,这些中间件由业务驱动产⽣,随着技术组件越来越丰富,形成完备的平台技术框架,⼤⼤提升了平台的产品研发效率和业务运⾏稳定性。
区别于⽔平⽅向上层依赖下层的关系,垂直⽅向以技术框架为地基⽀撑点,向两侧驱动影响业务架构、监控平台、服务治理平台,下⾯介绍⼀下其中的核⼼组件。
接⼝层Web V4框架
接⼝框架简化和规范了业务接⼝开发⼯作,将通⽤的接⼝层功能打包到框架中,采⽤了Spring的⾯向切⾯(AOP)设计理念。接⼝框架基于jersey 进⾏⼆次开发,基于annotation定义接⼝(url, 参数),内置Auth、频次控制、访问⽇志、降级功能,⽀撑接⼝层监控平台与服务治理,同时还有⾃动化的Bean-json/xml序列化。
服务层框架
服务层主要涉及RPC远程调⽤框架以及消息队列框架,这是微博平台在服务层使⽤最为⼴泛的两个框架。
MCQ消息队列
消息队列提供⼀种先⼊先出的通讯机制,在平台内部,最常见的场景是将数据的落地操作异步写⼊队列,队列处理程序批量读取并写⼊DB,消息队列提供的异步机制加快了前端机的响应时间,其次,批量的DB操作也间接的提⾼了DB操作性能,另外⼀个应⽤场景,平台通过消息队列,向搜索、⼤数据、商业运营部门提供实时数据。
微博平台内部⼤量使⽤的MCQ(SimpleQueue Service Over Memcache)消息队列服务,基于MemCache协议,消息数据持久化写⼊BerkeleyDB,只有get/set两个命令,同时也⾮常容易做监控(stats queue),丰富的client library,线上运⾏多年,性能⽐通⽤的MQ ⾼很多倍。
Motan RPC框架
微博的Motan RPC服务,底层通讯引擎采⽤了Netty⽹络框架,序列化协议⽀持Hessian和Java序列化,通讯协议⽀持Motan、http、tcp、mc等,Motan框架在内部⼤量使⽤,在系统的健壮性和服务治理⽅⾯,有较为成熟的技术解决⽅案,健壮性上,基于Config配置管理服务实现了High Availability与L
oad Balance策略(⽀持灵活的FailOver和FailFast HA策略,以及Round Robin、LRU、Consistent Hash等Load Balance策略),服务治理⽅⾯,⽣成完整的服务调⽤链数据,服务请求性能数据,响应应时间(Response Time)、QPS 以及标准化Error、Exception⽇志信息。
资源层框架
资源层的框架⾮常多,有封装MySQL与HBase的Key-List DAL中间件、有定制化的计数组件,有⽀持分布式MC与Redis的Proxy,在这些⽅⾯业界有较多的经验分享,我在这⾥分享⼀下平台架构的对象库与SSD Cache组件。
对象库
对象库⽀持便捷的序列化与反序列化微博中的对象数据,序列化时,将JVM内存中的对象序列化写⼊在HBase中并⽣成唯⼀的ObjectID,当需要访问该对象时,通过ObjectID读取,对象库⽀持任意类型的对象,⽀持PB、JSON、⼆进制序列化协议,微博中最⼤的应⽤场景将微博中引⽤的视频、图⽚、⽂章统⼀定义为对象,⼀共定义了⼏⼗种对象类型,并抽象出标准的对象元数据Schema,对象的内容上传到对象存储系统(Sina S3)中,对象元数据中保存Sina S3的下载地址。
SSDCache
随着SSD硬盘的普及,其优越的IO性能被越来越多的替换传统的SATA和SAS磁盘,常见的应⽤场景有三种:1)替换MySQL数据库的硬盘,⽬前社区还没有针对SSD优化的MySQL版本,即使这样,直接升级SSD硬盘也能带来8倍左右的IOPS提升;2)替换Redis的硬盘,提升其性能;3)⽤在CDN中,加快静态资源加载速度。
微博平台将SSD应⽤在分布式缓存场景中,将传统的Redis/MC + Mysql⽅式,扩展为 Redis/MC + SSD Cache + Mysql⽅式,SSD Cache作为L2缓存使⽤,第⼀降低了MC/Redis成本过⾼,容量⼩的问题,也解决了穿透DB带来的数据库访问压⼒。
垂直的监控与服务治理
随着服务规模和业务变得越来越复杂,即使业务架构师也很难准确的描述服务之间的依赖关系,服务的管理运维变得越来难,在这个背景下,参考google的dapper和twitter的zipkin,平台实现了⾃⼰的⼤型分布式追踪系统WatchMan。
WatchMan⼤型分布式追踪系统
如其他⼤中型互联⽹应⽤⼀样,微博平台由众多的分布式组件构成,⽤户通过浏览器或移动客户端的每⼀个HTTP请求到达应⽤服务器后,会经过很多个业务系统或系统组件,并留下⾜迹(footprint)。
但是这些分散的数据对于问题排查,或是流程优化都帮助有限。对于这样⼀种典型的跨进程/跨线程的场景,汇总收集并分析这类⽇志就显得尤为重要。另⼀⽅⾯,收集每⼀处⾜迹(footprint)的性能数据,并根据策略对各⼦系统做流控或降级也是确保微博平台⾼可⽤的重要因素。要能做到追踪每个请求的完整调⽤链路;收集调⽤链路上每个服务的性能数据;能追踪系统中所有的Error和Exception;通过计算性能数据和⽐对性能指标(SLA)再回馈到控制流程(control flow)中,基于这些⽬标就诞⽣了微博的Watchman系统。
其系统设计⼀个核⼼原则就是低侵⼊性(non-invasivenss):作为⾮业务组件,应当尽可能少侵⼊或者不侵⼊其他业务系统,保持对使⽤⽅的透明性,可以⼤⼤减少开发⼈员的负担和接⼊门槛。基于此考虑,所有的⽇志采集点都分布在技术框架中间件中,包括接⼝框架、RPC 框架以及其他资源中间件。
WatchMan由技术团队搭建框架,应⽤在所有业务场景中,运维基于此系统完善监控平台,业务和运维共同使⽤此系统,完成分布式服务治理,包括服务扩容与缩容,服务降级,流量切换,服务发布与灰度。
微博发布模式
同步推模式
新浪微博登录不了
早期的架构中,⽤户发表微博后,系统会⽴即将这条微博插⼊到数据库所有分析的订阅列表中。当⽤户量较⼤时,特别是明星⽤户发布微博时,会引起⼤量的数据库写操作,系统性能急剧下降,发布微博延迟加剧。
异步推拉模式
⽤户发表微博后,系统将微博写⼊消息队列后⽴即返回,⽤户响应迅速。消息队列的消费者任务将微博推送给所有当前在线的粉丝的订阅列表中,⾮在线⽤户在登录后再根据关注列表拉去微博订阅列表。
我们再看⼀下⽬前即将推出的微博平台的新架构。我们知道API⼤部分的请求都为了获取最新的数据。API请求有⼀个特点,它⼤⽬前调⽤都是空返回的,⽐如说⼀款⼿机的客户端每隔⼀分钟它都要调⽤服务器⼀下,就是有没有新数据,⼤⽬前的调⽤都是空返回,就是说不管服务器有没有数据都要调⽤⼀次。这次询问到下⼀次询问中间,如果有新的数据来了,你是不会马上知道的。因此我们想API能不能改⽤推的⽅式,就是客户端不需要持续的调⽤,如果有新数据就会推过去。技术特点,显⽽易见低延迟,就是从发表到接受1秒内完成,实际上可能⽤不了1秒。然后服务端的连接就是⾼并发长连接服务,就是多点都连接在我们的服务器上,这个⽐传统的API要⼤。
  我们再看⼀下内部细节,就是我们收到数据之后⾸先要经过最上⾯RECEIVER。然后推到我们的引擎
⾥⾯,这个引擎会做两个事情,⾸先会把⽤户的关系拿过来,然后按照⽤户关系马上推送给他相应的粉丝。所以我们调⽤⽅已经在那⼉等待了,我们需要有⼀个唤醒操作,就是说在接⼝这⼉把它唤醒,然后把它发送过去。最后是⼀个⾼并发的长连服务器,就是⼀台服务器⽀持10万以上的并发连接。最右边中间
有⼀个圆圈叫做Stream Buffer,我们需要Stream Buffer是要保存⽤户最近的数据。因为⽤户可能会有断线的,⽐如说他发送数据的时候断线半分钟,我们需要把这半分钟补给他。这就是我们的推送架构。
第⼆部分:设计原则
⽤户规模影响设计,具体是指⽤户数每上⼀个数量级,许多设计需要重新考虑。
10万⽤户级别
单服务器,前端、后端、cache、db在⼀起。
百万级
db和cache单独部署服务器,db或按业务进⾏拆分(sharding)。
cache或使⽤⼀致性hash扩展。
前端后端还是在⼀起,但是根据业务拆分,每个业务可分配不同数量的服务器
千万级
开始重视架构设计,有专门技术架构师
需跨机房部署,前端在远程增加反向代理加速,数据库在异地机房使⽤slave数据库副本
后端拆分出来,系统内部需要远程调⽤,内部需远程调⽤协议。
亿级
架构更细分,或增加数据架构师,cache架构师,分布式架构师
数据库sharding碰到烦恼,开始考虑分布式数据服务
数据访问需要根据业务特点细分。
开发、运维、测量、调优具备有⾃⼰的专有⼯具。
所有服务需要地理多机房分布,具备IDC容灾设计。
服务可降级
上⾯的数字仅供理解“⽤户规模影响设计”,数字本⾝并⽆具体指导价值。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。