`

Ebay架构特点(HPTS 2009)

阅读更多

 这篇文档转载jdon上的。

在HPTS 2009上,ebay 架构师Randy Shoup又列出了五个lessions.它们分别是:
1 Expect (R)evolution
2 Dependencies Matter
3 Be Authoritative
4 Never Enough Data
5 Custom Infrastructure

我结合ebay以前的5个lessions,总结一下可伸缩性和高性能的系统架构的一些最佳的实践:

一 Partition Everything
在一个大型的系统架构和设计当中,我们会面临各种各样的挑战,而为了能使得系统具有良好的可伸缩性,我们就需要“切分系统的每个部分”,而这里的切分又设计到一些方向性或者是策略性的问题,也就是如何切分,从什么方向入手去切分,我结合Ebay架构师的经验以及自己的想法,总结如下。
1 垂直切分
说到垂直切分,我们能第一时间想到的就应该是系统的分层架构,一个系统可以分为好几个层次,比如在目前J2EE系统的开发当中,我们一般都会分为表现层,应用层(负责业务逻辑的封装),领域模型层(负责业务逻辑的实现),和持久层(负责对底层数据源的访问),按照分层的思想切分以后,系统的每一个层都是高内聚的,同时层与层之间也是低耦合的,这就符合了高内聚和低耦合的原则,这样以来系统的各个层次可以独立的进行维护,扩展和伸缩。分层的好处还可以参见我的一篇文章:系统为什么要分层?

2 水平切分
当系统按照分层原则分为几个层次以后,虽然层与层之间实现了好的解耦,从而容易维护和伸缩,但是随着负载的增大,单个层的伸缩也会遇到瓶颈,而这个时候就需要水平的切分各个层次,这里又可以按照逻辑功能的水平切分和存储或者数据的水平切分。
2.1 应用水平切分
在一个大型的系统中往往会涉及到很多的错综复杂的逻辑,这个时候架构师就需要根据不同的功能对系统进行水平的分割,比如按照用户,商品,交易,搜索等功能进行水平的分割。而在具体架构和设计的过程中,我们一般通过不同的jar,bundle等来进行分割。
在按照功能进行切分以后,我们还需要注意一点就是尽量采用无状态的架构,因为系统的伸缩性很大部分上取决于你的应用的状态如何保存,因此无状态的架构对于水平的切分很重要,只有尽量的采用了无状态的架构以后,我们的系统才可以能更好的进行水平的伸缩。
2.2 存储水平切分
一个大型的系统往往会有非常巨大的数据量,这个时候就需要对数据也进行切分,比如将数据分为用户数据库,交易数据库,商品数据库等。在对数据按照功能进行切分以后,我们还可以对其进行进一步的切分,此时一般采用“Shard”技术,比如将前100W条记录保存一台主机上,然后依次类推。

二 Abstract and Virtualize at all Levels
在第一条"Partition Everything"中,我们将切分融入了系统的血液当中,这样也就使得系统具有了良好可伸缩性的血液,但是在切分以后,也给系统带来了其它的问题,比如在存储层面上,因为我们将数据按照功能进行了水平的切分,这样以来就使得数据的访问复杂了起来,这个时候就需要对数据访问层进行合理化得抽象和虚拟化,使得物理上分割的数据库对外界来说是一个统一的整体,而此时一般我们可以采用DAL技术。
在Ebay的系统中,搜索是系统很重要的构成部分,一般用户的一次搜索都需要通过一个聚合器对搜索结果的进行整合,对于外界来说通过聚合器封装和抽象了搜索系统。
因此抽象和虚拟化使得系统的伸缩性的实现更加容易和方便,它使得伸缩性的系统更加方便管理和维护。

三 Asynchrony Everywhere
目前J2EE其实都是同步的API(JMS除外),同步必然带来组件与组件之间的紧耦合,而组件之间的耦合度越高,也就不能独立对其进行伸缩,从而影响到伸缩性。假如系统中A组件调用了B组件,从基本的数理逻辑来看,如果A可以用,那么B可以用,反过来,如果B不可以用,那么A也不可以用,这就是同步调用给系统可用性带来的损失。因此只有通过一种松耦合的方式对组件进行解耦,这样才能使得系统具有好的可用性和伸缩性,而通过异步的方式是一种比较好的解耦的方式。关于异步大家可以参考一下这篇文章:Java EE meets Web 2.0

Ebay将异步这条原则贯彻的非常彻底。在组件内部使用SEDA来实现异步性,组件和组件之间的交互也尽量的采用异步,将业务程分为很多个阶段,各个阶段通过异步的方式连接起来。在Ebay中,异步主要用了Event Queue和消息多播等技术。
说到这里,我也想说说目前比较流行的DDD如何引入异步,在传统的J2EE开发当中,业务逻辑实现都是在action或者service,业务逻辑的实现是通过action和service这些技术的组件来驱动的,而采用领域驱动设计以后,业务逻辑的操作是由Model驱动的,Model触发Domain Event,然后异步的驱动技术性的组件来完成对Domain Event的响应,这样以来整个系统的核心就是Domain Model,而各种的技术性的组件仅仅是一种为Domain Model服务的tools。Domain Model和Domain Event的结合可以参见下图:





四 Avoid Distributed Transactions
事务和性能,伸缩性是相互矛盾的,系统中事务用的越多,那么性能和伸缩性就会变得越差,因此必须合理化得利用事务。尤其是传统的分布式事务,采用2PC来提交,这样就要求所有事务性的资源必须都准备好,只要一个有问题,那么整个事务都会受到限制,更严重的是2PC是非常影响性能和伸缩性的。从Ebay的架构中也可以看的出来,Ebay坚决的杜绝分布式事务。如果不采用传统那种分布式事务,那么采用什么样的事务策略呢?答案就是BASE策略。
在说BASE策略之前,我们有必要来了解一下Eric Brewer大叔的CAP理论,CAP是Consistency,Availability,Partition_tolerance的缩写,Consistency表示系统的状态对所有的Client都是即时一致的。Availability表示系统的可用性,它主要是指任何一个业务操作都能在预定的时间内完成。最后一项Partition_tolerance表示分区容错性,它主要是指业务操作不能受单个系统组件的影响,即使某一些组件不能使用,业务操作也必须完成。理解了CAP理论的这三个方面以后,我们来看看CAP理论到底告诉了我们什么,CAP告诉我们,任何一个分布式系统不可能同时满足这三个条件,最多只能同时满足两个(是不是有点失望*^__^*).

我们现在明白了CAP,那么BASE是什么?它和传统的ACID又有什么区别和联系呢?接着往下看,你就会明白啦呵呵。BASE是basically available,soft state,eventually consistent的缩写,BASE表示基本可用,事务软状态和最终一致性。BASE采用一种乐观策略,它不要求事务状态的即时一致性,而是要求一种最终一致性,也就是说事务状态在某一个用户可以接受的范围内是不一致的,但是最终会变的一致,而传统的ACID事务策略采用一种悲观的方式,它要求事务状态在业务操作结束以后必须是即时一致的,是一种Hard state,一种面向连接的状态,炫绷得越紧越容易断,事务也是一样的,ACID这跟炫也非常容易断,但是无论是BASE还是ACID都无法摆脱CAP的限制,BASE通过一种事务的软状态和弱一致性换来了可用性,同时也满足分区容错性,而ACID采用了强的一致性,而牺牲了可用性。因此BASE适合于对可用性最求大于一致性需求的场合,而ACID适合于对一致性要求很严格的场合,比如一些股票软件系统就适合ACID。最后,如果大家对BASE和ACID还是不理解的话,推荐大家看看Dan Pritchett大哥的这篇文章:BASE: An Acid Alternative

五 Cache
缓存存在的地方很多,系统中用缓存的方式也有很多方式,我这里仅仅说说我自己的理解,这些也是我目前公司的项目中所运用的方式。
我这里主要说一下缓存如何和领域模型进行结合使用。在传统的软件开发中,我们一般采用action -->service-->Dao中,系统的业务逻辑充斥在action或者Service里面,最终的结果就是action和service非常庞大,非常的难于理解,尤其是在设计到事务的时候,到项目后期,你会发现事务配置在action和service都不合适,这都是传统的SSH传统的开发带来的负面影响。那么采用DDD以后,业务逻辑的实现是通过Domain model驱动技术组件去完成功能,所有的业务逻辑都被封装在了Domain Model里面,但是这样也带来一个问题,Domain model一般聚合了很多的东西,如果我们用完了就是把它扔掉,那么每次从持久层构建它是非常耗费性能的,因此这就需要将其放在某一个地方,这个地方就是缓存。当然了随着目前KEY-VALUE存储系统的不断发展,以后我们可以直接用KEY-VALUE存储系统来讲Domain Model保存起来。如果大家对于Domain model为什么要聚合很多东西,为什么也不能聚合不该聚合的东西,请大家参考另外一篇文章:Improving performance and scalability with DDD

六 Not Only SQL

对象和关系数据库很矛盾,这个经常来本站的人应该都清楚。我就不多说了,目前随着KEY-VALUE存储系统的逐渐成熟和普及,我想一种:面向业务的分析和设计(DDD)+面向业务的存储(KEY-VALUE)的新的架构方式也将会诞生。

七 Embrace Inconsistency

这一点其实也还可以算是一致性和性能,伸缩性,高可用性之间的博弈
八 Automate Everything
九 Remember Everything Fails
十 Expect (R)evolution
十一 Dependencies Matter
十二 Be Authoritative
十三 Never Enough Data
十四 Custom Infrastructure

分享到:
评论

相关推荐

    Node.js-hpts(http-proxy-to-socks)一个nodejs客户端将socks代理转换为http代理

    hpts(http-proxy-to-socks) 一个nodejs客户端将socks代理转换为http代理

    马里巴马科G点大学医院中心肾脏和血液透析科的慢性血液透析甲状旁腺切除术

    它的特点是甲状旁腺分泌副甲状腺激素过多,以维持对低钙血症的磷酸钙稳态,降低1.25二羟基维生素D3和高磷血症。 目的:分析继发性甲状旁腺功能亢进症(HPTS)的甲状旁腺切除术(PTX)的结果,报告术后病程以及早期...

    multitor:使用负载平衡创建多个 TOR 实例

    支持HAProxy 、 socks协议和http-proxy服务器: polipo 、 privoxy和hpts 。 此外,您可以查看以前运行的TOR进程并为所有或选定的进程创建新身份。 multitor已在以下基础上完全重写: 由Jan Seidl编写的Multi-TOR...

    源代码-ajax即时聊天程序(新手学习推荐).zip

    源代码-ajax即时聊天程序(新手学习推荐).zip

    python读取excel数据.doc

    以下是一个简单的Python代码,用于在控制台上打印一个看起来像爱心的形状。这个代码使用了ASCII字符来创建形状。 python print('\n'.join([''.join([('Love'[(x-y)%4] if ((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3 <= 0 else ' ') for x in range(-30, 30)]) for y in range(15, -15, -1)])) 这个代码使用了数学公式来生成心形。但是,由于ASCII字符的限制,这个心形可能看起来不是很完美。 如果你想要一个更详细和定制化的心形,你可能需要使用图形库,如PIL(Python Imaging Library)或matplotlib。但是,这些库通常用于创建图像文件或在图形用户界面上绘制,而不是在控制台上打印。 另外,这里有一个使用turtle模块在图形窗口中绘制爱心的简单示例: python import turtle # 创建一个新的turtle对象 heart = turtle.Turtl

    【图像评价】图像去雾质量评价【含Matlab源码 066期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    30客户满意度调查表.DOC

    30客户满意度调查表.DOC

    labelme, 一个用于图像标记的工具

    使用python3以上版本

    cn-msdn-library-for-visual-studio-2008-service-pack-1-x86-dvd-x1

    cn_msdn_library_for_visual_studio_2008_service_pack_1_x86_dvd_x1.iso 分卷3

    变更申请单.xls

    变更申请单.xls

    【路缝识别】 GUI形态学路缝识别(带面板)【含Matlab源码 1649期】.zip

    【路缝识别】 GUI形态学路缝识别(带面板)【含Matlab源码 1649期】

    判断回文素数的C语言程序

    附件是判断回文素数的C语言程序,文件绿色安全,请大家放心下载,仅供交流学习使用,无任何商业目的! 程序首先定义了两个函数:isPrime 用于判断一个数是否为素数,isPalindrome 用于判断一个数是否为回文。然后在 main 函数中,通过一个循环来检查从2到999(这里假设我们只需要检查小于1000的数)的所有数,如果一个数既是素数又是回文数,就将其打印出来。

    Modbus Poll version 10.9.0 Build 2194

    Modbus Poll version 10.9.0 Build 2194,modbus 主机,包含 32位与64位,非常好用的 modbus 协议主机调试工具

    【表盘识别】 GUI二值化指针式表盘识别【含Matlab源码 275期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    读书屋测试项目,里面涵盖有自动化测试用例以及手工测试用例 此项目主要针对自动化项目用例

    此文档是读书屋的自动化测试用例,

    17产品标识和可追溯性控制程序.doc

    17产品标识和可追溯性控制程序.doc

    【图像融合】形态学分析和稀疏表征CSMCA图像融合【含Matlab源码 4130期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    源代码-ApiAdmin后台管理系统 基于ThinkPHP.zip

    源代码-ApiAdmin后台管理系统 基于ThinkPHP.zip

    【图像隐写】 DCT数字水印嵌入+攻击+提取【含Matlab源码 1758期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

Global site tag (gtag.js) - Google Analytics