本文转自:https://www.infoq.cn/article/weibo-platform-archieture
编者按】《博文共赏》是 InfoQ 中文站新推出的一个专栏,精选来自国内外技术社区和我的博客上的技术文章,让更多的读者朋友受益,本栏目转载的内容都通过原做者受权。文章推荐能够发送邮件到editors@cn.infoq.com。php
新浪微博在 2014 年 3 月公布的月活跃用户(MAU)已经达到 1.43 亿,2014 年新年第一分钟发送的微博达 808298 条,如此巨大的用户规模和业务量,须要高可用(HA)、高并发访问、低延时的强大后台系统支撑。前端
微博平台第一代架构为 LAMP 架构,数据库使用的是 MyIsam,后台用的是 php,缓存为 Memcache。mysql
随着应用规模的增加,衍生出的第二代架构对业务功能进行了模块化、服务化和组件化,后台系统从 php 替换为 Java,逐渐造成 SOA 架构,在很长一段时间支撑了微博平台的业务发展。redis
在此基础上又通过长时间的重构、线上运行、思索与沉淀,平台造成了第三代架构体系。sql
咱们先看一张微博的核心业务图(以下),是否是很是复杂?但这已是一个简化的不能再简化的业务图了,第三代技术体系就是为了保障在微博核心业务上快速、高效、可靠地发布新产品新功能。数据库
微博平台的第三代技术体系,使用正交分解法创建模型:在水平方向,采用典型的三级分层模型,即接口层、服务层与资源层;在垂直方向,进一步细分为业务架构、技术架构、监控平台与服务治理平台。下面是平台的总体架构图:json
如上图所示,正交分解法将整个图分解为 3*4=12 个区域,每一个区域表明一个水平维度与一个垂直维度的交点,相应的定义这个区域的核心功能点,好比区域 5 主要完成服务层的技术架构。数组
下面详细介绍水平方向与垂直方向的设计原则,尤为会重点介绍 四、五、6 中的技术组件及其在整个架构体系中的做用。浏览器
水平维度的划分,在大中型互联网后台业务系统的设计中很是基础,在平台的每一代技术体系中都有体现。这里仍是简单介绍一下,为后续垂直维度的延伸讲解作铺垫:缓存
水平分层有一个特色,依赖关系都是从上往下,上层的服务依赖下层,下层的服务不会依赖上层,构建了一种简单直接的依赖关系。
与分层模型相对应,微博系统中的服务器主要包括三种类型:前端机(提供 API 接口服务)、队列机(处理上行业务逻辑,主要是数据写入)和存储(mc、mysql、mcq、redis 、HBase 等)。
随着业务架构的发展和优化,平台研发实现了许多卓越的中间件产品,用来支撑核心业务,这些中间件由业务驱动产生,随着技术组件愈来愈丰富,造成完备的平台技术框架,大大提高了平台的产品研发效率和业务运行稳定性。
区别于水平方向上层依赖下层的关系,垂直方向以技术框架为地基支撑点,向两侧驱动影响业务架构、监控平台、服务治理平台,下面介绍一下其中的核心组件。
接口框架简化和规范了业务接口开发工做,将通用的接口层功能打包到框架中,采用了 Spring 的面向切面(AOP)设计理念。接口框架基于 Jersey 进行二次开发,基于 annotation 定义接口 (url, 参数),内置 Auth、频次控制、访问日志、降级功能,支撑接口层监控平台与服务治理,同时还有自动化的 Bean-json/xml 序列化。
服务层主要涉及 RPC 远程调用框架以及消息队列框架,这是微博平台在服务层使用最为普遍的两个框架。
消息队列提供一种先入先出的通信机制,在平台内部,最多见的场景是将数据的落地操做异步写入队列,队列处理程序批量读取并写入 DB,消息队列提供的异步机制加快了前端机的响应时间,其次,批量的 DB 操做也间接提升了 DB 操做性能,另一个应用场景,平台经过消息队列,向搜索、大数据、商业运营部门提供实时数据。
微博平台内部大量使用的 MCQ(SimpleQueue Service Over Memcache) 消息队列服务,基于 MemCache 协议,消息数据持久化写入 BerkeleyDB,只有 get/set 两个命令,同时也很是容易作监控(stats queue),有丰富的 client library,线上运行多年,性能比通用的 MQ 高不少倍。
微博的 Motan RPC 服务,底层通信引擎采用了 Netty 网络框架,序列化协议支持 Hessian 和 Java 序列化,通信协议支持 Motan、http、tcp、mc 等,Motan 框架在内部大量使用,在系统的健壮性和服务治理方面,有较为成熟的技术解决方案,健壮性上,基于 Config 配置管理服务实现了 High Availability 与 Load 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 的下载地址。
随着 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。
如其余大中型互联网应用同样,微博平台由众多的分布式组件构成,用户经过浏览器或移动客户端的每个 HTTP 请求到达应用服务器后,会通过不少个业务系统或系统组件,并留下足迹(footprint)。可是这些分散的数据对于问题排查,或是流程优化都帮助有限。对于这样一种典型的跨进程 / 跨线程的场景,汇总收集并分析这类日志就显得尤其重要。另外一方面,收集每一处足迹的性能数据,并根据策略对各子系统作流控或降级,也是确保微博平台高可用的重要因素。要能作到追踪每一个请求的完整调用链路;收集调用链路上每一个服务的性能数据;能追踪系统中全部的 Error 和 Exception;经过计算性能数据和比对性能指标(SLA)再回馈到控制流程(control flow)中,基于这些目标就诞生了微博的 Watchman 系统。
该系统设计的一个核心原则就是低侵入性(non-invasivenss):做为非业务组件,应当尽量少侵入或者不侵入其余业务系统,保持对使用方的透明性,能够大大减小开发人员的负担和接入门槛。基于此考虑,全部的日志采集点都分布在技术框架中间件中,包括接口框架、RPC 框架以及其余资源中间件。
WatchMan 由技术团队搭建框架,应用在全部业务场景中,运维基于此系统完善监控平台,业务和运维共同使用此系统,完成分布式服务治理,包括服务扩容与缩容、服务降级、流量切换、服务发布与灰度。
如今,技术框架在平台发挥着愈来愈重要的做用,驱动着平台的技术升级、业务开发、系统运维服务,本文限于篇幅限制,没有展开介绍,后续会不断地介绍核心中间件的设计原则和系统架构。