互联网系统架构的演进

上传人:宝路 文档编号:12689645 上传时间:2017-10-20 格式:DOC 页数:9 大小:133.50KB
返回 下载 相关 举报
互联网系统架构的演进_第1页
第1页 / 共9页
互联网系统架构的演进_第2页
第2页 / 共9页
互联网系统架构的演进_第3页
第3页 / 共9页
互联网系统架构的演进_第4页
第4页 / 共9页
互联网系统架构的演进_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《互联网系统架构的演进》由会员分享,可在线阅读,更多相关《互联网系统架构的演进(9页珍藏版)》请在金锄头文库上搜索。

1、互联网系统架构的演进发表于2013-08-29 09:27| 14048次阅读| 来源程序员| 60 条评论| 作者杨光辉程序员杂志 2013年9月刊特别策划互联网系统架构技术架构性能系统摘要:多终端接入、开放平台给互联网带来了前所未有的用户数量和访问规模,信息之多、传播速度之快,是传统网站难以想象的。本文将从发展演进的角度,解读高性能互联网系统架构。多终端接入、开放平台给互联网带来了前所未有的用户量级和访问规模,SNS网站产生了海量的 UGC(用户产生内容) ,而且这些内容依托关 系链扩散速度之快、传播范围之广是传统网站难以想象的,海量数据的计算存储也一直是近年互联网领域的热点。本文将从发展

2、演进的层面探讨互联网的系统架构。天下武功唯快不破网站初期的架构一般采用“短平快”的架构思路,架构以简单清晰、容易开发为第一衡量指标。互联网架构选型首先包括开发语言的选择,目前 PHP、Java 是主力语言。开发语言的选择一般从团队人员的知识储备、社区活跃度、商业应用的成熟度、招聘人才的人力成本等方面考量。选择语言之后,一般会选择该语言的流行框架辅助研发,例如 Java 的SSH、Python 的 Django 等。但这些框架并不是通常意义上的架构,架构一般可 分为物理架构、运行架构、逻辑架构、开发架构、数据架构等多个维度,框架往往只是代码架构的一部分。代码架构是指代码的组织形式、规范、设计模式

3、等,框架 其实是常用设计模式的软件化。例如 Struts 是 MVC 模式的实现,Hibernate、iBATIS 是 ORM 模式的实现。在架构视图中,早期关注的主要是开发视图和数据视图,一般数据存储采用DB,初期数据的关注点主要是安全和备份,MySQL 的 Master-Slave 模式可以满足该需求。鸡蛋不要放在一个篮子里采用“短平快”三板斧将网站开发出来之后,急需解决的是网站的可用性问题。可用性最基本的要求是不能有单点,对程序节点而言,前端可采用LVS、HAProxy、Nginx 等负载均衡/反向代理设备。DB 的可用性就复杂了很多,数据库天然是有状态的,状态就是其中的数据,新增一个数

4、据节点一般伴随着大量的数据复制和迁移。对金融行业而言,昂贵的商用存储是 解决之道, “IBM+Oracle+EMC”是该类系统的标配。互联网企业则一般采用较为廉价的方案,例如开源的 DRDB+Heartbeat 技术组合可 以在MySQL 主库宕机时实现备机接管,接管时间可以控制在30秒内。程序节点其实也可能存在状态,例如 Web 服务中常用的 Session 就是保存在容器中的状态,这种状态保持要求所有相同用户的请求都在同一台机器上处理,无状态的程序节点才能水平扩展。无状态一般有两种设计思路,还以 Session为例,一种思路是把用户的状态保存在客户端 Cookie,每次请求都把客户端的用户

5、信息带到服务器端,淘宝的分布式 Session 就是该思 路的一种实现;另一种思路是状态保留在另外一个服务中,例如有些公司将 Session 放在分布式缓存中。性能是生命线去除单点之后的系统就可以水平扩展,架构如图1所示。但随着网站的推广运营,系统的规模开始扩大,此时可能会出现服务访问缓慢,甚至不可用的状况,如何提升系统性能就成了架构师的当务之急。图1 去除单点之后进行水平扩展存储架构和性能互联网系统所有的性能瓶颈中,数据存储和访问速度往往是最重要也是最难解决的,选择合适的存储是系统的关键。存储的选择一般需要从多个方面考量,如成本、内容、用途和模型。目前主流的存储介质包括硬盘和内存两种。对机械

6、硬盘来说,1秒可以完成150次左右的随机 I/O。而结合设计优良的 Hash算法,内存查找可以每秒执行40万次左右。硬盘的随机读写能力决定了其读 写的最差性能,但操作系统在实现文件系统时会把最近读写过的数据缓存在内存中。由于磁盘访问和内存访问性能量级的差距,从操作系统的 Cache 命中率就可 以简单计算文件存储的性能,如果内存命中率可以达到80%,系统的 I/O 能力相较完全随机 I/O 将有5倍提升。对于数据层服务器,大内存已成为标配(一般为100GB 左右) ,如果 DB 中存储200GB 的数据,根据8/2原则,Cache 命中率应为87.5%,因此对 MySQL 而言,一般读写可以达

7、到每秒1千次以上。对于读写频率都很高、且可容忍数据丢失的场景,可以采用内存作为数据存储的介质。可靠的内存存储需要每次操作都记录 Biglog,即使数据丢失也可以恢复,同时内存中的数据一般定期持久化到硬盘。从功能角度考量,还可以分为持久化存储和 Cache。持久化存储也可称为可靠存储,Cache 是为了提升系统性能,在可靠存储的基础上建立的访问性能更加高效的数据读取节点,通常是内存存储,其架构一般如图2所示。图2 持久化存储和 Cache存储的数据模型一般分为结构化存储和 NoSQL 存储。结构化存储以各种传统 DB为代表,NoSQL 技术的代表系统则有 HBase、Memcached、 Red

8、is 等。各种NoSQL 系统虽然特性各异,但相对传统 DB 而言,由于结构化信息的缺失,往往不能做各种关联查询,适用场景更多是主键查询,而且一般 是写少读多的系统。对于大型互联网公司,为了某些场景下的性能优化,也会定制个性化的文件系统,例如为了适应大文件存储的场景,Google 开发了 GFS;为了更快读取海量商品的描述图片,TFS 在阿里诞生。虽然各类存储快速涌现,但 DB 作为结构化数据的传统存储设备,依然在架构中处于非常重要的地位。由于随机 I/O 的瓶颈,DB 的性能天花板十分明显。在大型系 统中通常需要分库操作,分库一般有两个维度水平切分和垂直切分。水平切分一般根据主键规则或某种规

9、则将同类数据切分到不同的单元表中,原则是数据切分均匀,尤其是热点数据分布均匀。垂直切分是把大表中的字段拆分到多张表。垂直切分一般按照数据访问频率的不同。逻辑关系的差别进行切分,例如将大字段、kv 字段、计数等高频访问字段单独剥离存储都是常见的垂直切分方案。除了切库之外, MySQL 的分表也会有效减少单表大小,使数据变得更简单,甚至可以做到不下线变更,单表索引规模的下降也会带来性能的提升。分库分表作为 DB 架构中重要的一环,使 DB 更加稳健,但它给业务代码带来了额外的复杂性,最好通过中间件来屏蔽 DB 的底层分布,对业务透明。作为高性能网站必不可少的组件,Cache 在各种主流架构中也起着

10、重要的作用。从部署模式上看,它可分为本地 Cache 和分布式 Cache。本地 Cache 是指在应用进程中的 Cache,通常的数据结构是一个 MAP,其优点是结构简 单,效率较分布式 Cache 更高,缺点是一般应用程序服务器的内存有限,导致本地 Cache容量受到局限,而且数据冗余度较高,每个应用服务器都需要一份 数据,更新比较烦琐,一般采用超时删除机制。分布式 Cache 的容量较大,方便扩容和更新,其数据分布可采用一致性 Hash 算法,减少节点变化带来的数据迁移。引入 Cache 不可避免的问题是服务器的宕机处理。Cache 通常是一个集群,数据分布在多个节点,如果挂掉一个节点,

11、只会影响部分数据,而且对于可靠性要求较高的系统,每个节点都可以有备份。作为可靠存储的数据备份,Cache 在架构设计上往往承担大部分读访问需求,其命中率尤为重要。Cache 不命中有两种情况,一是数据在 Cache 中不存 在,二是在持久化存储中也不存在。对于后者的频繁访问会导致请求直接压在 DB 上,在设计时应尽量避免,可以通过维护 Bitmap 对持久化存储中没有的数据 进行拦截,直接返回,也可以简单地将这些数据对应空对象放进 Cache。Cache 的存储一般是将索引和数据分离,对于索引数据可以全量缓存,对于体量较大的数据一般采用部分缓存的方式。Cache 的使用场景有一定的局限,对于较

12、为静态的数据才有意义,这个临界值一般是5分钟。由于当前存储技术的进步,Cache 也可以用其他高性能的存储介质代替,例如 SSD 的引入使得硬盘的随机读写能力提升数十倍,也会使得Cache 的重要性有所下降。程序架构和性能对一般的系统而言,程序逻辑的主要作用是调用各种数据访问接口,该操作通常需要等待,所以除搜索等少数系统外,程序逻辑一般是非 CPU 密集型。该类系统中“线程”是稀缺资源,线程数和接口耗时构成了系统的 QPS 能力。大型互联网系统的 QPS 可能为几万甚至峰值达到几十万,此时增加机器可以解决问题,但这些机器的利用率其实很低,因为大部分时间是在等待,此时引入异步变得非常重要,异步在

13、同样的时间可以处理更多工作,拥有更好的性能。图3 同步调用和异步调用利用 Nio 的多路复用方式可方便地实现异步系统,当然也可用协程令代码更加清晰。业界流行的 SEDA 技术可将一次请求拆分为粒度更细的 Actor,每个 Actor 使用独立队列,前一个的输出是后一个的输入。SEDA 通过该方式将请求中等待和非等待的环节分离,提升了系统的吞吐量,这种方式在小米等互联网 公司有较多应用。除了异步之外,并行对系统也很重要,它可以有效缩短请求的响应时间。批量接口也可以有效减少系统调用次数,使得系统线程消耗更少,从而提升系统吞吐量。对线程而言,还有一个重要的参数是超时时间。响应快的服务,超时时间可以长

14、一些,对于响应慢的服务,超时时间可以短一些,尽快失败是保护自己的有效手段。网络架构和性能大型网站的网络接入一般是“DNS+负载均衡层+CDN”这种模式。对于大型互联网公司,往往有多个 IDC 提供对外服务,中国互联网的南北不互通使得解决不 同地域不同运营商的接入速度问题成了难题,该问题的解决一般需要公司自己开发 DNS 服务器,结合 IP 测速平台,引流用户请求到访问速度最快的节点。大系统小做业务逻辑复杂多变,如何保证程序逻辑的代码稳定是架构师需要解决的问题,良好的模块划分和扩展性强的接口设计都是解决这个问题的利器。模块是和领域模型相关的一个概念,其往往指系统中高内聚的一个数据访问单元。例如对

15、电商系统而言,最大的两个领域模型分别是商品信息和交易信息,每个领域模 型对应一系列数据,商品会有商品的基本信息、类目信息等,交易会包括交易的订单,这些“领域模型+数据+业务方法”就构成了一个个的模块,高度内聚的模块 是数据的访问的入口。例如交易时也需要去获取商品信息,但一般不会被允许直接调用商品模块的数据表,而是通过商品模块提供的接口进行访问,这样做有下面一 些优点。 接口和数据分离,底层数据结构的变化不会影响到外围系统。 数据直接暴露给其他系统,增加了系统的不稳定性。 接口的收敛减少了重复开发,提高了系统可用性。对较小规模的应用,模块可部署在一起,但对大型系统而言,模块一般是单独部署,通过

16、RPC 交互,这样可以减少彼此之间的系统层面影响。例如 Amazon 就倾向将所有服务器程序暴露为接口。分布式系统增加了系统交互的复杂性,也为系统引入了更多潜在的失败环节,但分布式系统可以带来的好处更明显。 有利于系统分级,针对不同服务提供不同的可用性。 大规模开发有了可能,每个模块可以单独开发和部署。 系统可重用性加强,避免重复制造轮子。 服务治理更加简单,一般 RPC 天然提供容灾,可以自动发现新增节点和剔除问题节点。逻辑层的接口设计如何做到稳定呢?首先接口的设计不应该是产品驱动的,而应该由数据驱动,尽量考虑接口以后的发展,接口的参数尽量是对象,参数不要采用 boolean 这种难以扩展的数据类型。逻辑层的接口设计,一般有粗粒度和细粒度两种模式。粗粒度接口的优点是交互少,一次调用基本可以满足需求,缺点是业务逻辑较多,所以不稳定性增加,这里的不稳定性不仅是系统稳定性,还包括业务逻辑的稳定性。细粒度接口交互较多,但更加有利于重用性。细粒度接口多次交互是否会带来明显的性能损耗呢?目前服务器1秒可以执行近

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号