可伸缩 Web 架构与分布式系统

开源软件近年来已变为构建一些大型网站的基础组件。并且伴随着网站的成长,围绕着它们架构的最佳实践和指导准则已经显露。这篇文章旨在涉及一些在设计大型网站时需要考虑的关键问题和一些为达到这些目标所使用的组件。本文主要关注于Web系统,然而其中的一些内容同样适用于其他分布式系统。

一、Web分布式系统设计准则

构建和运行一个可伸缩的网站或应用来说究竟意味着什么?从一个基本的层面来看,就是将用户和远程资源通过互联网连接起来——将其变得可伸缩的部分,是指这些资源或者访问这些资源是分布式的、贯穿于多个服务器。像很多生活中的事情一样,在构建一个web服务时花费时间提前做好计划将会帮助服务能够长久运行;理解一些大型网站背后的考量和权衡会在创建小型网站时帮助做出更明智的决定。下面是一些会影响到设计大型可伸缩性Web系统的关键准则:

可用性

一个网站的正常运行时间,对于很多公司的信誉和功能来说都是至关重要的。对于一些大型在线零售网站,甚至是几分钟的不可用都会导致数以千万计美元的收入损失,所以将他们的系统设计成不间断可用和能够弹性恢复既是一项基础业务也是一个技术需求。分布式系统的高可用性需要仔细考虑关键组件冗余,快速恢复部分有问题的系统,并且当出现问题时能够做到优雅降级。

性能

性能已成为大多数网站一个很重要的考量指标。一个网站的速度会影响到使用和用户满意度,同样也会影响到搜索引擎排名,将直接关系到网站收入和用户保持力(黏性)。因此,关键之处就在于创建一个为快速响应、低延迟的系统。

可靠性

一个系统需要做到可靠,这样才能使得对于(固定)数据的请求始终会返回同样的数据。如果数据发生变化或者更新,那相同的请求应该返回新的数据。用户需要知道,一旦一些数据被写入、存储到系统中,那么系统就会持久化(这些数据)并且能够让人信赖随时能够检索。

可伸缩性

对于任何大型分布式系统,系统规模只是可伸缩性需要考虑的一个方面。同样重要的是,增加容量能够处理更大量的负载所需的工作,通常在系统可伸缩性方面被提及到。可伸缩性会涉及到系统的很多不同的因素:系统额外还能够处理多少流量,是否能够轻易增加存储容量,还能多处理多少事务。

可管理性

设计一个易于运维的系统是另一个重要考量点。系统的可管理型等同于操作的可伸缩性:维护和变更。可管理性需要考虑的有:当问题发生时能够便于诊断和理解,便于进行变更和修改,并且系统易于操作。(比如系统是否能够进行例行操作而不带来失败或者异常?)

成本

成本是一个重要因素。这明显会包括硬件和软件成本,但同样还要考虑到一些其他方面来部署、运维系统,比如构建系统所需的开发时间,运行系统所需的运维工作量,甚至所需的培训都要被考虑在内。成本是指拥有系统的总成本(原句是Cost is the total cost of ownership.)。

这些准则中的每一条都提供了在设计一个分布式web系统架构时作决定的基本原则。但是,他们也可能互相矛盾,比如达到某一目标是以牺牲另一个为代价的。一个典型的例子:专注于系统容量时,选择通过简单增加更多机器(可伸缩性)的代价是(增加了)可管理性(你需要运维更多的服务器)和成本(更多服务器价格)。当设计任何web应用时,这些关键准则都是需要考量的,即使不得不承认,一个设计可能会牺牲它们中的一个或更多。

 

二、基本原理

对于系统架构来说,有一些事情需要考虑:什么是正确的组件,这些组件如何协作,需要做哪些正确的权衡。在真正需要可伸缩性之前的投资通常并不是一个明智的商业提议,然而,一些设计中的远见卓识将会在未来节省真正的时间和资源。

本节着眼于一些对于几乎所有大型Web应用都非常核心的因素:服务,冗余,分期和失败处理。每个因素均包含有选择和妥协,特别是在上一节提到的准则上下文中。为了详细解释这些,最好的方式就是从一个例子开始。

举例:图片托管应用

你很可能已经在网上上传过一张图片。对于托管和传送大量图片的大型网站来说,将会在架构建设上遇到很多挑战,比如成本效益、高可用性和低延迟性(能够快速检索)。

设想一个这样的系统:用户可以将他们的图片上传到一个中央服务器,并且图片可以通过一个web链接或者API(应用程序接口)进行请求,就像Flickr或者Picasa一样。为了简单起见,我们假定这个应用有两个关键部分:能够上传(写入)一张图片到服务器,能够查询一张图片。虽然我们希望上传能够更快速,但我们最关心的是系统能够快速分发用户请求的图片(比如图片可以被请求用于一张网页或是其他应用)。这些跟一个web服务器或者CDN(内容分发网络) edge serverCDN所使用的服务器,用于在很多位置存放内容,这样内容在地理/物理上更接近用户,起到更高性能的作用)所提供的功能非常类似。

系统其他重要的方面

  • 对于存储的图片数量没有设限,所以就图片数量而言,需要考虑存储的可伸缩性。
  • 对于图片的下载/请求需要做到低延迟。
  • 如果一个用户上传了一张图片,那该图片应该总是存在的。(图片的数据可靠性)
  • 系统需要易于管理(可管理型)。
  • 由于图片托管不会带来很高的利润,所以系统需要做到有成本效益的。

图片1.1:图片托管应用的简化架构图

 

在这个图片托管例子中,系统必须做到(让用户)可感知到快速,存储数据的可靠性和那些所有高可伸缩的特征。构建一个小型的托管于单台服务器上的应用过于简单,也没有意义,对于本章来说也没有乐趣所在。来假设下,我们想要构建出可以成长为像Flickr一样的庞然大物。

服务

当考虑可伸缩系统的设计时,(服务)有助于各功能去耦并且通过一个清晰定义的接口思考系统的每个部分。在实践中,这种方式的系统设计表明其拥有一个面向服务的架构(SOA)。对于这些类型的系统,每个服务都有它们各自确切的功能上下文,并且和该上下文以外的任何交互均是与一个抽象的接口进行的,特别是另一个服务的公有接口。

将一个系统拆解为一个互补的服务集合解耦了那些相互间的操作。这种抽象有助于建立服务间明确的关系、潜在的(运行)环境、服务的消费者。通过这些清晰的描绘有助于隔离问题,并且允许每个部分能够相互独立地进行扩展。这种面向服务的系统设计有点类似与面向对象编程。

在我们的例子中,所有上传和获取图片的请求都是在同一服务器上处理,但是,如果系统想要达到可伸缩,那么将这两个功能拆分成各自的服务是非常明智的。

快进下,假设这些服务被大量使用;这样的场景将非常易于看到更久(原文此处是how longer writes will impact the time it takes to read the images)的写操作会如何影响(系统)读取图片的时间(因为这两个功能会竞争共享资源)。在这样的架构下,这种影响是真实存在的。即使上传和下载速度是一样的(对于大多数IP网络来说不一定是,因为大多数都是设计成下载速度与上传速度3:1的比例),文件通常直接从缓存中读取,而写入则最终必须到达磁盘(在最终一致的场景中可能会被写入多次)。即使所有东西都是从内存或者磁盘(比如SSD固态硬盘)读取,数据库的写入操作总还是比读取要慢(Pole Position, 一个开源的数据库评测工具)。

另一个潜在的设计问题是,一个像Apache或者lighttpdweb服务器,通常有一个它可以维持并发连接数的上线(默认大约在500左右,但可以调得更高),并且在高流量下,写操作将很快消耗完所有(连接资源)。由于读操作可以异步进行,或者利用其它性能调优如gzip压缩或者chunked transfer encodingweb服务器可以转换为更快服务读操作、更快切换客户端,从而比最大连接数每秒服务更多的请求(Apache最大连接数设置为500,但一般都能每秒服务数千个请求)。写操作,在另一方面,倾向于在上传过程中维护一个打开状态的连接,所有上传一个1M大小的文件在大多数家庭网络上将花费超过1秒的视角,所以web服务器只能同时处理500个写操作。

 

 

 

本教程由尚硅谷教育大数据研究院出品,如需转载请注明来源。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值