二 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
我们现在明白了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