如何架构和开发高性能,高伸缩性web 应用系统

51
© 2010 IBM 如如如如如如如如如如如如如如 WEB 如如如如如如如如 如如如

Upload: melity78

Post on 20-Mar-2017

2.354 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM

如何架构和开发高性能,高伸缩性 WEB 应用系统软件架构师 童景文

Page 2: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM2

Agenda

BASE 理论简介 :ACID 理论的另外选择

可伸缩性最佳实践准则几点架构建议

经典架构前言

Page 3: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM3

前言 在我们给客户构建相应的 WEB 应用系统中,会使用 J2EE 架构 /.NET 架构 /LAMP 架构之一或者其中的混合。在很多场合下我们是不需要考虑整个系统的可伸缩性以具备更好的性能(例如高吞吐量和低响应时间);因为我们有足够强的硬件资源和用户的压力并不大或者受到项目资源的问题(例如项目的预算,人力资源,技术风险等)。 但是对于有些场合下,例如用户的并发用户数很高并且有足够的项目预算或者项目预算也比较充分并且我们需要让我们的软件价值更好地体现(例如我们不需要使用昂贵的硬件资源,仅仅可以利用低成本的硬件就可以让整个系统具有很好的性能和可靠性)。我们就非常地需要考虑整个应用系统的高可伸缩性的设计。 当然如果不考虑场合,我们对所有的应用系统的设计都需要考虑高可伸缩性的设计那我们的应用系统将非常地具有竞争力。并且对我们的技术人员(架构师 / 开发人员 / 测试人员)来说提升相应的技术能力对自己本身和对公司来说都是百益而无一害。

Page 4: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM4

前言误区:很多技术人员 ( 架构师,开发人员等 ) 受到各种外部因素和自我因素的影响都会觉得借助各种系统软件 ( 操作系统,数据库系统,中间件等 ) 的强大功能和强大的硬件资源能够为我们解决应用系统高可伸缩性的问题以达到很高的性能和可靠性;例如买更好的硬件资源(更强劲的服务器,存储),实施数据库集群(例如 ORACLE RAC), 实施中间件集群和均衡负载(例如 WAS 集群和 F5 硬件均衡负载器),调优(例如数据库调优,硬件调整,操作系统调优,中间件调优) . 但是这种方式只能解决一定层次上的问题,并不能解决根本问题;往往带来的结果是花了更多的钱而办不好事情。当然这种方式是需要做的特别是调优但是我们不能过度(例如没有必要买更多的更好的机器,没有必要做 ORACLE RAC 等)。

Page 5: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM5

前言挑战:可伸缩性是我们每天奋力抵抗的一大架构压力。我们所做的每一项架构及设计决策,身前身后都能看到它的踪影。对于大并发量的用户核心业务应用系统,可伸缩性是生死交关的问题。在一个可伸缩的架构中,资源的消耗应该随负载线性(或更佳)上升,负载可由用户流量、数据量等测量。如果说性能衡量的是每一工作单元所需的资源消 耗,可伸缩性则是衡量当工作单元的数量或尺寸增加时,资源消耗的变化情况。换句话说,可伸缩性是整个价格 - 性能曲线的形状,而不是曲线上某一点的取值。并且我们需要达到以下几点:1. 资源利用率能够随着负载的增长能够线性增长。形象点就是说,如果负载不断地增加,我们能够通过不断的添加机器(通过负载均衡机制)来处理;并且系统的响应时间不会产生剧烈的波动

2. 系统的架构设计应该能够面对系统数据、用户数增长 10倍以上的情况。形象点说:如果现在的系统能够承受 10000 个用户的使用,那系统现在的这个设计能够承受 10万个用户的使用。 3. 由于整个系统将是由多台机器之间协同工作,单台机器的失效、以及性能严重退化不会影响到整个系统的对外提供的较好地服务质量。 4. 系统能够提供一个稳定的响应时间,不能出现剧烈的波动。 5. 系统监控、管理起来方面简单,并且通过相应的诊断日志和工具能够很方便的定位出错误的原因和性能的瓶颈所在。

Page 6: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM6

Agenda

BASE 理论简介 :ACID 理论的另外选择

可伸缩性最佳实践准则几点架构建议

经典架构前言

Page 7: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM7

经典架构下图所示的是一个我们最喜欢用的经典的应用分层架构设计图。

J2EE 架构经典实现:一般来说我们会使用 Structs/WebWork+Spring+Hibernate/iBitas 来进行实现, .NET 架构基本也是如此;并且会引入相应的 Ajax框架(例如 YUI,DOJO,EXTJS,GWT,PROTYPE etc). 一种改良实现: UI( 用户界面逻辑)采用 php/asp.net/flex/html5进行开发,业务逻辑层和数据访问层采用 JAVA进行开发。 UI( 用户界面逻辑)层与业务逻辑层采用 REST WebService进行集成。

Page 8: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM8

经典架构下图所示的是我们最经典的部署架构之一(包括应用服务器集群和数据库服务器 HA) 。

Page 9: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM9

经典架构下图所示的是我们最经典的部署架构之一(包括应用服务器集群和数据库服务集群 ) 。

Page 10: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM10

经典架构部署 TIPS: 1.除了运行数据库的机器建议运行在小型机上特别是 IBM P小型机上;其它都建议运行在 PC 服务器或者刀片服务器上 。因为数据库系统稳定第一,并且伸缩性扩展能力交较差;而应用服务器的可伸缩性能力 / 集群能力非常好 ( 只要应用设计上没有太大的问题 ). 并且在部署的时候都要对相应的操作系统进行打补丁和进行相应的内核参数调优,网络参数调优等;数据库系统也要进行补丁和调优;应用服务器也要进行补丁和调优。

Page 11: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM11

经典架构部署 TIPS: 2. 有时候在实施一个比较大的应用服务器集群的时候,例如 HTTP SERVER 需要做 HA ,需要建立更多应用服务器实例(为了充分利用 CPU )。而客户仅仅是提供了少量几台高性能的服务器,要实现上面所述的部署架构会发现机器是不够的。所以我们需要利用虚拟化技术(例如 VMWARE,XEN,POWERVM) 。下图是一个例子,在 2台好的 PC服务器或者刀片服务器上利用虚拟化技术的部署架构。

Page 12: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM12

经典架构部署 TIPS: 3. 对于我们 WEB 应用的部署包,例如 J2EE 应用的 WAR包,请把相应的静态内容(例如 JS,HTML,CSS,图片等 )拆分出来放到 HTTP SERVER 上,而只把相应的动态内容(例如 JSP,CLASSES 等)打包到 WAR包中部署在应用服务器上。

Page 13: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM13

Agenda

BASE 理论简介 :ACID 理论的另外选择

可伸缩性最佳实践准则几点架构建议

经典架构前言

Page 14: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM14

一个高伸缩性的 WEB 应用系统架构示例图

应用服务器集群(应用服务器运行于虚拟机中)

App App AppTomc

atTomc

atTomc

at

应用服务器集群(应用服务器运行于虚拟机中)

App App App

Resin Resin Resin

应用服务器集群(应用服务器运行于虚拟机中)

App App App

WAS WAS WAS

F5负载均衡器

数据高速缓存集群(数据高速缓存运行于虚拟机中):DataGrid

DataGrid:WXS

DataGrid:WXS

DataGrid:WXS

数据库服务器

Oracle DB for OLTP

Oracle DB for OLTP

MySQL DB for OLTP

DB2 DB for OLAP

DB2 DB for OLAP

HTTP Server集群(HTTP Server运行于虚拟机中)

Nginx/IHS Nginx/IHS

WVE集群(WVE运行于虚拟机中)

WVE:ODR WVE:ODR

整体IT系统监控应用

获取到的监控信息

获取到的监控信息

获取到的监控信息

获取到的监控信息

获取到的监控信息

应用服务器层

数据库服务器层

WEB服务器层

整体IT系统监控层

Page 15: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM15

数据库层面问题起源:在理想情况下,我们希望有一台性能超级强大的机器上安装一个性能强大的数据库系统(例如 DB2/ORACLE ),但是我们都知道随着用户数的增长和应用数目或者应用的功能模块数目的增长,一台数据库服务器不管它的硬件条件是如何的强劲,是不可能承受很大的处理压力的( oracle RAC/DB2 PureScale 也解决不了这个问题,因为数据库的瓶颈关键在存储 IO而 RAC/ PureScale是 Share IO 的)。所以说硬件的投入和数据库 系统软件的投入是基本上解决不了这个问题的,我们需要找到一个性价比合适的解决方案。架构师和程序员的价值开始体现了……………………

Page 16: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM16

数据库层面解决方式一:在很多场合下我们可能会形成一个主 - 备方式的数据库架构方案来分解压力如下图所示,这种方式能够缓解相应的性能压力(当然需要建立在 SQL语句良好的情况下),但是我们都知道存在相应的数据热点问题,即某些数据存在高强度的删除,修改,查询等操作;一台服务器还是不能够满足相应的需求。

主数据库 备数据库

App

OLTP请求(以增加,修改,删除为主)

查询统计请求(不存在增加,修改,删除操作)

数据实时复制同步

Page 17: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM17

数据库层面解决方式二:在按照功能域进行分解,即利用多台服务器,安装相应的数据库系统;并且按照相应的功能域把数据分解到不同机器上的数据库系统中。相应的逻辑图如下所示,例如把关于交易的数据放在一台数据库服务器上,产品的数据放在一台数据库服务器上。这样的话就把数据给分离到不同的物理机的数据库服务器上。这样的话可以大大地提高整体大规模系统的性能。但是还是会存在一个比较严重的数据热点问题,例如关于交易的数据的请求强度太高这台服务器还是不能购满足。这样的话我们就提出了下面所示的第三种解决方案。

Page 18: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM18

数据库层面解决方式三:进行数据的水平切分(即Sharding ),即根据相应的数据关键字进行 hash (例如一致性HASH 算法)把数据分布到不同机器上去。相应的架构如下图所示,通过下图我们可以看到数据的分布存取和数据的聚合需要在应用服务器上增加相应的数据访问层代码来解决。通过这种方式可以大大降低数据热点问题。如果对某些数据还存在热点问题的话我们就需要在应用服务器层这一端的应用代码进行优化增加 memcache 功能

Page 19: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM19

数据库层面TIPS :1.少用存储过程和触发器,除非在没有办法的情况下。

2.SQL 语句不要太过复杂,一般来说 2 个表联合查询就差不多了不要出现许多表联合查询。 3. 要知道关系型数据库是很难伸缩扩展的要珍惜数据库服务器资源,编写良好的 SQL语句。 4. 要与存储工程师紧密配合设计好关系型数据库的物理模型。 5. 要相信 JAVA,C# 等这些现代语言的能力是非常强劲的,只要设计的好的话;应用服务器可以无限的线性扩展。

Page 20: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM20

应用服务器层面问题起源 (1) :应用服务器运行着我们编写的业务逻辑和数据访问层等代码,进行相应的业务逻辑计算和数据库访问操作以完成相应的业务功能(例如数据的查询,录入,报表展现,数据或者服务的交互等)。在这一层中存在大量的数据库操作代码频繁的访问数据库,并且随着我们应用的完善我们会发现很多数据是可以缓存的不需要到数据库重新访问的,所以我们可以增加一层即高速数据缓存这一层以大幅提高应用系统的性能并降低对数据库服务器的要求。架构师和程序员的价值又开始体现了……………………

Page 21: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM21

应用服务器层面解决方式 (1) :增加高速数据缓存这一层后的业务逻辑会变更成如下简要的流程: 1 ) 先到高速数据缓存服务器上去查询所需要的数据是否存在。 2 ) 如果数据不存在,则操作数据库获取数据并把数据序列化并存储到高速数据缓存服务器上。 3 ) 如果数据存在,则直接从高速数据缓存服务器上获取并反序列化成相应的 java 对象。并且数据缓存服务器还需要提供数据过期功能(即数据在数据缓存服务器存在的时间超过 1 个小时后则过期将被从数据缓存服务器中删除掉。并且数据缓存服务器是可以利用多台机器形成一个大的内存缓存池,数据存在于那个数据缓存服务器上是根据相应的 key 值进行 hash 后得到相应的具体某台数据缓存服务器并存储和获取。相应的根据 key 值进行 hash 后的的内存高速数据缓冲服务器的架构图如下所示 (即根据 Consistent Hashing 算法算出具体的数据分布 ):

Page 22: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM22

应用服务器层面 ( 仅适合 WAS 应用服务器 )—动态缓存 动态缓存是目前大型复杂应用特别是互联网应用中提升性能和并发能力的关键技术之一。因为在很多场合有些动态页面经过一次执行后所反映的内容,在一定时间内基本上是不会经过任何变化的所以就可以在后续的访问后不用再执行而直接访问这将大大提升应用系统的的响应能力和吞吐能力,在同等的硬件条件下提供更强大的处理能力,满足企业日益增长的业务需要。高速动态缓存做为 WAS 的一个扩展服务从 5.0.2 开始就被包含在从 WAS Express 开始的各个版本。该服务可以缓存 WebSphere Command 对象、 Servlet 和 JavaServer Pages( JSP )的输出,从而明显提升应用程序性能。动态高速缓存服务位于应用程序服务器 Java 虚拟机( JVM )内部,通过拦截对可高速缓存对象的调用隐式的实现了对缓存的调用,程序员甚至意识不到它的存在。下图展示了缓存命中和不命中的两种情况下系统的流程,如果缓存命中将避免执行后面复杂的商业逻辑,业务逻辑的执行时间大大缩短了。

Page 23: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM23

应用服务器层面 ( 仅适合 WAS 应用服务器 )—动态缓存

Web Output – HTML, servlet/JSP, JSF, AJAX, Web Services

Business Logic – Command beans

Data – Java objects, Persistence L2 cache

NO CODIN

G

NO CODING

Page 24: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM24

应用服务器层面TIPS :在我们很多的应用场合中,为了提高系统的性能;我们都会对应用服务器进行相应的集群然后又相应的均衡负载器进行均衡负载。然而我们在应用设计和开发的时候都会在 session 中放入相应的数据以维护我们应用的执行,如果在 session 中放入大量的数据将会引起应用服务器集群各个实例之间的数据同步会带来很大的压力从而降低了集群的效果,为了提高集群的效率以实现线性的扩展我们建议把相应的放入 session 中的数据放入到高速内存数据缓冲中。并且建议应用最好实现成无状态 .

Page 25: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM25

HTTP Server 层面 HTTP SERVER 软件(例如 Nginx/IBM HTTP Server ),完成 HTTP SERVER 所具有的一些功能例如反向代理、均衡负载等。 但是我们都知道我们的应用系统有大量的模块,并且不同模块的优先程度是不一样的,有些优先程度是很高,有些优先程度是中等,有些优先程度是较低的。在我们传统的方式中我们会遇到这样的一个情况就是当大量的用户请求上来,并且是请求的是不同的重要优先程度的功能模块;然后由均衡负载器转接到相应的应用服务器执行;我们会发现一个现象就是所有请求都在执行导致所有的请求执行效率都很低很慢甚至大家都锁死在那,并且有些机器却很空闲。所以我们需要引入WVE:ODR(按需路由 ) 这一层所提供的功能,此层接受到大量请求后,根据预先设置好的分类对请求进行分类排队,高优先级的请求将优先得到执行并能够占用更多的资源并且也可以根据需要把空闲机器上的停止的应用启动起来进行请求的执行从而可以更好的利用硬件资源。这个思路就是动态集群和应用虚拟化,相应的架构图如下所示:

Page 26: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM26

HTTP 层面TIPS :1. Make Fewer HTTP Requests.

2. Add an Expires Header 3. Put Stylesheets at the Top 4. Put Scripts at the Bottom 5 …… 等更多,请参考参考资料\High Performance Web Sites.pdf

或者 google 或者到http://nate.koechley.com/talks/2007/atmedia-london/high-performance-web-sites.pdf 下载

Page 27: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM27

代码安全TIPS :很多安全都是代码编写的问题导致很多系统很不安全,例如 SQL注入、跨域脚本。

请参考参考资料\What Every Web Programmer Needs To Know About Security 或者访问 http://code.google.com/intl/zh-CN/edu/submissions/daswani/index.htmlhttp://code.google.com/intl/zh-CN/edu/submissions/web_security/listing.html 下载相应的资料

Page 28: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM28

Agenda

BASE 理论简介 :ACID 理论的另外选择

可伸缩性最佳实践准则几点架构建议

经典架构前言

Page 29: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM29

可伸缩性最佳实践准则按功能分割:相关的功能部分应该合在一起,不相关的功能部分应该分割开来——不管你把它叫做 SOA 、功能分解还是工程秘诀。而且,不相关的功能之间耦合程度越松散,就越能灵活地独立伸缩其中的一部分。

在编码层次,我们无时不刻都在运用这条原则。 JAR 文件、包、 Bundle 等等,都是用来隔离和抽象功能的机制。 在应用层次,将不同的功能划分成几个应用程序池。销售功能由一组应用服务器运行,投标功能由另一组负责,搜索又是另外一组服务器。这样就可以根据某项功能的资源消耗,单独地伸缩其中一个池。我们也因此得以进一步隔离及合理化资源依赖关系 ——比如销售池只需要访问后台资源的一个相对较小的子集。 在数据库层次,我们也采取同样的做法。没有无所不包的单一数据库,相反我们有一组数据库主机存放用户数据、一组存放商品数据、一组存放购买数据……。同样,这种做法让我们得以单独为某一类数据伸缩其数据库设施。

Page 30: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM30

可伸缩性最佳实践准则水平切分:按功能分割对我们的帮助很大,但单凭它还不足以得到完全可伸缩的架构。即使将功能一一解耦,单项功能的资源需求随着时间增长,仍然有可能超出单一系 统的能力。我们需要常常提醒自己,“没有分割就没有伸缩”。在单项功能内部,我们需要能把工作负载分解成许多我们有能力驾驭的小单元,让每个单元都能维持良好 的性能价格比。这就是水平分割出场的时候了。

在应用层次,将各种交互都设计成无状态的,所以水平分割是轻而易举之事。用标准的负载均衡服务器来路由进入的流量。所有应用服务器都是 均等的,而且任何服务器都不会维持事务性的状态,因此负载均衡可以任意选择应用服务器。如果需要更多处理能力,只需要简单 地增加新的应用服务器。 数据库层次的问题比较有挑战性,原因是数据天生就是有状态的。我们会按照主要的访问路径对数据作水平分割(或称为“ sharding” )。例如用户 数据被分割到 20台主机上,每台主机存放 1/20 的用户。随着用户数量的增长,以及每个用户的数据量增长,我们会增加更多的主机,将用户分散到更多的 机器上去。用例不同,我们分割数据的方案也需要不同:有些是对主键简单取模( ID尾数为 1 的放到第一 台主机,尾数为二的放到下一台,以此类推),有些是按照 ID 的区间分割( 1-1M、 1-2M 等等),或者一致性 HASH 算法。不过具体 的分割方案如何,总的思想是支持数据分割及重分割的基础设施在可伸缩性上远比不支持的优越。

Page 31: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM31

可伸缩性最佳实践准则避免分布式事务:看到这里,你可能在疑惑按功能划分数据和水平划分数据的实践如何满足事务要求。毕竟,几乎任何有意义的操作都要更新一个以上的实体——立即就可以举 出用户和商品的例子。正统的广为人知的答案是:建立跨资源的分布式事务,用两段式提交来保证要么所有资源全都更新,要么全都不更新。很不幸,这种悲观方案 的成本很可观。伸缩、性能和响应延迟都受到协调成本的反面影响,随着依赖的资源数量和客户数量的上升,这些指标都会以几何级数恶化。可用性亦受到限制,因 为所有依赖的资源都必须就位。实用主义的答案

是,对于不相关的系统,放宽对它们的跨系统事务的保证。 左右逢源是办不到的。保证跨多个系统或分区之间的即时的一致性,通常既无必要,也不现实。 Inktomi的 Eric Brewer十年前提出的 CAP 公理是这样说的:分布式系统的三项重要指标——一致性( Consistency )、可用性( Availability )和 分区耐受性( Partition-tolerance )—— 在任意时刻,只有两项能同时成立。对于高负载量的应用例如互联网应用来说,我们必须选择分区耐受性,因为它是实 现可伸缩的根本。对于 24x7运行的应用,选择可用性也是理所当然的。于是只好放弃即时一致性( immediate consistency )。

Page 32: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM32

可伸缩性最佳实践准则避免分布式事务:对于高负载量和高可用性的应用,我们应该绝对不允许任何形式的客户端或者分布式事务——因此绝不需要两段式提交。在某些经过仔细定义的情形下,我们会将作用于同一个数据库 的若干语句捆绑成单个事务性的操作。而对于绝大部分操作,单条语句是自动提交的。虽然我们故意放宽正统的 ACID属性,以致不能在所有地方保证即时一致 性,但现实的结果是大部分系统在绝大部分时间都是可用的。当然我们需要采用了一些技术来帮助系统达到最终的一致性( eventual consistency ):周密调整数据库操作的次序、异步恢复事件,以及数据核对( reconciliation )或者集中决算( settlement batches )。具体选择哪种技术要根据特定用例对一致性的需求来决定。 对于架构师和系统的设计者来说,关键是要明白一致性并非“有”和“没有”的单选题。现实中大多数的用例都不要求即时一致性。正如我们经常根据成本和其他压力因素来权衡可用性的高低,一致性也同样可以量体裁衣,根据特定操作的需要而保证适当程度的一致性

。 。

Page 33: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM33

可伸缩性最佳实践准则用异步策略解耦程序:提高可伸缩性的另一项关键措施是积极地采取异步策略。如果组件 A同步调用组件 B ,那么 A和 B 就是紧密耦合的,而紧耦合的系统其可伸缩性特征是各部分 必须共同进退——要伸缩 A 必须同时伸缩 B 。同步调用的组件在可用性方面也面临着同样的问题。我们回到最基本的逻辑:如果 A推出 B ,那么非 B推出非 A 。也就 是说,若 B不可用,则 A 也不可用。如果反过来 A和 B 的联系是异步的,不管是通过队列、多播消息、批处理还是什么其他手段,它们就可以分别地伸缩。而且,此 时 A和 B 的可用性特征是相互独立的——即使 B 受困或者死掉, A仍然能够继续前进。 整个基础设施从上到下都应该贯彻这项原则。即使在单个组件内部也可通过 SEDA (分阶段的事件驱动架构, Staged Event-Driven Architecture )等技术实现异步性,同时保持一个易于理解的编程模型。组件之间也遵守同样的原则——尽可能避免同步带来的耦合。在多数情况下, 两个组件在任何事件中都不会有直接的业务联系。在所有的层次,把过程分解为阶段( stages or phases ),然后将它们异步地连接起来,这是伸缩的关键。

Page 34: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM34

可伸缩性最佳实践准则将过程转变为异步的流:用异步的原则解耦程序,尽可能将过程变为异步的。对于要求快速响应的系统,这样做可以从根本上减少请求者所经历的响应延迟。对于网站或者交易系统, 牺牲数据或执行的延迟时间(完成全部工作的实践)来换取用户的延迟时间(用户得到响应的时间)是值得的。活动跟踪、单据开付、决算和报表等处理过程显然都 应该属于后台活动。主要用例过程中常常有很多步骤可以进一部分解成异步运行。任何可以晚点再做的事情都应该晚点再做。 还有一个同等重要的方面认识到的人不多:异步性可以从根本上降低基础设施的成本。同步地执行操作迫使你必须按照负载的峰值来配备基础设施——即使在 任务最重的那一天里任务最重的那一秒,设施也必须有能力立即完成处理。而将昂贵的处理过程转变为异步的流,基础设施就不需要按照峰值来配备,只需要满足平 均负载。而且也不需要立即处理所有的请求,异步队列可以将处理任务分摊到较长的时间里,因而起到削峰的作用。系统的负载变化越大,曲线越多尖峰,就越能从 异步处理中得益。

Page 35: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM35

可伸缩性最佳实践准则虚拟化所有层次:虚拟化和抽象化无所不在,计算机科学里有一句老话:所有问题都可以通过增加一个间接层次来解决。操作系统是对硬件的抽象,而许多现代语言所用的虚拟 机又是对操作系统的抽象。对象 - 关系映射层抽象了数据库。负载均衡器和虚拟 IP抽象了网络终端。当我们通过分割数据和程序来提高基础设施的可伸缩性,为各 种分割增加额外的虚拟层次就成为重中之重。

我们建议虚拟化数据库。应用与逻辑数据库交互,逻辑数据库再按照配置映射到某个特定的物理机器和数据库实例。应用也抽象于执行数据分割的 路由逻辑,路由逻辑会把特定的记录(如用户 XYZ )分配到指定的分区。这两类抽象需要有我们自己开发相应的 DAL 层实现的。

Page 36: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM36

可伸缩性最佳实践准则适当地使用缓存:最后要适当地使用缓存。这里给出的建议不一定普遍适用,因为缓存是否高效极大地依赖于用例的细节。说到底,要在存储约束、对可用性的需求、对陈旧数 据的容忍程度等条件下最大化缓存的命中率,这才是一个高效的缓存系统的最终目标。经验证明,要平衡众多因素是极其困难的,即使暂时达到目标,情况也极可能 随着时间而改变。

最适合缓存的是很少改变、以读为主的数据——比如元数据、配置信息和静态数据。我们建议积极地缓存这种类型的数据,并且结合使用“推”和“ 拉”两种方法保持系统在一定程度上的更新同步。减少对相同数据的重复请求能达到非常显著的效果。频繁变更、读写兼有的数据很难有效地缓存。我们建议不要对请求间短暂存在的会话数据作任何缓存。 做得好,缓存系统能让可伸缩性的曲线向下弯曲,也就是比线性增长还要好——后续请求从缓存中取数据比从主存储取数据成本低廉。反过来,缓存做得不好 会引入相当多额外的经常耗费,也会妨碍到可用性。我们还没见过哪个系统没机会让缓存大展拳脚的,关键是要根据具体情况找到适当缓存策略。

Page 37: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM37

Agenda

BASE 理论简介 :ACID 理论的另外选择

可伸缩性最佳实践准则几点架构建议

经典架构前言

Page 38: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM38

BASE 理论简介 :ACID 理论的另外选择现有的困境:在过去的十几年中 Web 应用变得越来越流行。我们都希望我们的 Web 应用系统能够应对不断增长的用户量和数据量,以及适应用户和其它开发人员对我们的 WEB 应用系统的高吞吐量和低响应时间的要求。但是如果我们的 WEB 应用系统依赖现今的数据库系统时,我们会发现数据存储将成为我们最大的瓶颈。

Page 39: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM39

BASE 理论简介 :ACID 理论的另外选择解决思路 1 :如何伸缩我们的应用以应付此局面,我们一般来说有两种策略;第一种也是最简单的即是垂直扩展伸缩,即把我们的应用(特别是数据库系统)运行在性能更加强劲的服务器上,但是此种策略最大的限制是性能越好的服务器越昂贵以及还有相应的锁限制并且还需要进行复杂的应用迁移;其实更让我们沮丧的是当我们的数据量和访问负载量以及实现的复杂程度到达一定程度的时候,这个世界上压根就不存在这种服务器。

Page 40: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM40

BASE 理论简介 :ACID 理论的另外选择解决思路 2 :第二种也是最简单的即是水平扩展伸缩,此种伸缩是相当的复杂但是提供了更好的伸缩性。水平数据分区伸缩可以从两个方向来进行。先按照功能域的划分把处于不同功能域的数据放在不同的数据库上相同功能域的数据放在同一个数据库上。然后对于同一个功能域的某些数据按照相应的算法(例如一致性 HASH 算法)把数据进行切分水平 (即 sharding)分布到不同的数据库上 . 相应的图例如下所示:

Page 41: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM41

BASE 理论简介 :ACID 理论的另外选择ACID 理论简介:指数据库事务正确执行的四个基本要素的缩写 .包含 :原子性(Atomicity )、一致性( Consistency )、隔离性( Isolation )、持久性( Durability )。一个支持事务( Transaction )的数据库系统,必需要具有这四种特性,否则在事务过程( Transaction processing )当中无法保证数据的正确性 , 交易过程极可能达不到交易方的要求 .   原子性   整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚( Rollback )到事务开始前的状态,就像这个事务从来没有执行过一样。   一致性   在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。   隔离性   两个事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。   持久性   在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

数据库厂商在很早就认识的到,如果数据进行水平切分分布到不同的数据库系统上的话 (即数据库分区: partitioning databases) 为了保证 ACID 特性,提出了两阶段事务递交技术 (2PC) 并实现,此技术的特点就是第一阶段:事务协调器要去所有参与全局事务的数据库准备递交事务,如果所有的数据库都同意并准备好则转入第二阶段;第二阶段:事务协调器要求所有的参与全局事务的数据库递交数据,要么全部成功要么全部失败。

Page 42: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM42

BASE 理论简介 :ACID 理论的另外选择ACID 理论的缺陷:如果数据进行水平切分分布到不同的数据库系统上的话 (即数据库分区: partitioning databases) 为了保证 ACID 特性,我们必须运用两阶段事务递交技术(2PC) 。但是此技术有以下几大缺陷:

1. 当一个 2PC 事务包含两个数据库的话,如果我们估计每个数据库的有效性为 99.9%, 则整体的有效性变成 99.8%. 2. 由于 2PC 事务是采用悲观锁机制,当业务逻辑复杂程度提高以及负载量增大的情况下效率将很低下,对于一个高性能,高伸缩性的应用系统是不可能接受的。 为了解决这个问题,我们需要引入相应的理论和经验来支撑我们以解决此问题。

Page 43: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM43

BASE 理论简介 :ACID 理论的另外选择CAP 理论介绍:此理论由 Eric Brewer( 加州大学伯克利教授 ) 提出,他认为在任何的数据共享系统中最多只能同时满足以下三个属性之中的两个,如下图所示:

C: Consistency 一致性 A: Availability 可用性P: Tolerance of network Partition 分区容忍性

Page 44: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM44

BASE 理论简介 :ACID 理论的另外选择CAP 理论介绍:对于我们的数据库系统来说满足以下两个特性,如下图所示:

但是对于一个高伸缩性的应用系统,必然会选择水平扩展策略也就是进行数据的水平切分分布到不同的数据库系统上 ;所以为了高性能我们必须放宽一致性(即允许瞬时不一致而最终会达到一致性),会尽量朝着 A、 P 的方向设计,然后通过其它手段保证对于一致性的商务需求

Page 45: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM45

BASE 理论简介 :ACID 理论的另外选择BASE 理论介绍:如果 BASE 是一种为了高性能我们必须放宽一致性(即允许瞬时不一致而最终会达到一致性)的一种设计策略,它按照CAP理论尽量朝着 A、 P 的方向设计,然后通过其它手段保证对于一致性的商务需求。它是一个缩写词,相应的缩写词如下定义:Basically Availble --基本可用 Soft-state -- 软状态 /柔性事务 ( 也可理解成无连接 )Eventual Consistency --最终一致性。

所符合的 CAP理论的图例如下所示:

Page 46: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM46

BASE 理论简介 :ACID 理论的另外选择一个示例:由于采用这个理论后,很多的逻辑将从数据库层转移到应用层进行处理,架构师和程序员的价值又开始体现。

我们先设计一个非常简单的两张表,这两张表的数据分布在不同机器上的数据库上;通过这两张表完成以下的的业务逻辑,用户表存储用户信息并且包含用户所购买和卖出的总的金额,交易表存储相关的交易信息例如交易双方是谁,交易金额等。相应的表关系图如下所示:

Page 47: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM47

BASE 理论简介 :ACID 理论的另外选择使用 ACID 理论的伪代码:由于数据分布在不同机器上不同数据库,为了保证数据的一致性我们必然会使用 2PC ,相应的伪代码如下图所示,当然此代码是及其简单的。

Page 48: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM48

BASE 理论简介 :ACID 理论的另外选择使用 BASE 理论的伪代码:为了达到高性能和高伸缩性,我们根据CAP理论按照往 A,P 方向进行设计,牺牲瞬时一致性但是达到最终的一致性;从而可以实现一个高伸缩性的可扩展系统。对此我们引入了持久化消息队列机制,当然这里的伪代码的一个前提是此持久化消息队列与数据库系统融合在一起(即持久化消息队列的后台存储资源与数据库系统是相同的),当然对于如果不在一起的话,相应的细节请参考此文档: BASE:An Acid Alternative

Page 49: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM49

参考文档

Page 50: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM50

参考文档 1. High Performance Web Sites 2. memcached全面剖析 3. BASE: An Acid Alternative 4. SEDA 架构理论 5. WAS 动态缓存介绍 6. What Every Web Programmer Needs To Know About Security 7. DB2 V9.5 力助 SASS 应用 8. CAP理论介绍 9. Problem Solving on Large Scale Clusters

注:这些资料都可以通过 GOOGLE 搜索得到。

Page 51: 如何架构和开发高性能,高伸缩性Web 应用系统

© 2010 IBM51

Questions ?