基于Azure云计算平台的网格计算,第3部分:运行网格应用程序
在本系列的第1部分,我们介绍了在Azure上进行网格计算开发的设计模式,而在第二部分,我们用C#开发了一个网格应用程序。在这篇文章中,我们将来运行它。

作者 Zhi Gan, Raja Das, Xiao Jun Dai 译者 崔康 发布于 2009年12月3日 下午8时45分
随着多核处理器成为主流,应用开发人员对于如何编写高伸缩性的应用以利用底层硬件的优势这个问题面临巨大的压力。此外,遗留系统不得不移植到新的架构上。 保证应用伸缩性的一种有效方式是使用高伸缩性组件构建应用。举例来说,在各种应用 中,java.util.concurrent.ConcurrentHashMap可以替代同步的HashTable,使应用伸缩性更好。因此,向应用 直接提供一套高伸缩性构造块以引入并行是非常有用的。
Flash Builder 4 Beta和FlexUnit下的测试驱动开发
汇集最新RIA技术相关资源,提供Flash开发平台相关工具高速下载,免费获得Adobe软件的产品序列号。
我们创建了一套高伸缩性并发Java组件作为Amin库项目的一部分。在本文中,我们将介绍一些创建该开源库的想法。
作为软件工程师,我们不得不并行我们的应用使它们在多核机器上很好的伸缩。一种并行方式是把它们分成若干子任务,其中每一个子任务与应用的其他子任务通信和同步。这通常被称为基于任务的并发。我们可以基于子任务的通信模式将应用分类。
经过为伸缩性而优化的组件非常有益于解决这些困难问题。举例来说,如果存在一个高伸缩性队列组件,那么实现生产者/消费者伸缩性相对容易些。本文中,我们提供了若干通用技术提高软件组件的伸缩性。
应用分析是开发过程的重要方面。分析是为了了解应用的运行特征。分析数据经常被用于提高应用的性能和伸缩性。大多数分析器遵从一个简单的执行模式,其中有 一个配置阶段。在该阶段,根据信息获取的类型,会配置不同层次的计算堆栈。硬件计数器可以被用来监控硬件事件。操作系统可以通过配置各种操作系统事件来监 控。如果在计算层次中还有虚拟机,那么需要配置以访问虚拟机的事件。最后,应用需要配置以得到真实应用的事件。优秀的分析器能够在不要求应用重新编译的情 况下完成这些配置。大多数分析器通常都配置虚拟机和应用层。应用在配置之后运行时,会生成跟踪信息,例如函数运行时间、资源使用情况、硬件性能参数、锁使 用、系统时间、用户时间等等。不同的分析器会在把跟踪信息输出到文件系统前做一些计算。最后,分析器会通过显示界面可视化这些数据。
用于并发应用的分析器需要提供有关线程、锁竞争和同步点的详细信息。我们使用了下面一些分析器作为Amino性能分析:
传统的性能调优方法,比如适用于顺序应用的方法也适用于并行应用。在完成传统调优之后,我们需要检查共享数据是如何被多线程访问的。通过使用JLM或者JLA,我们能够发现线程在访问共享资源时是如何竞争的。
举例来说,如果应用有100个线程,并且所有的线程都需要从一个java.util.HashTable提取/存储元素,该应用的性能由于线程竞争会下降。每一个线程需要在访问该HashTable之前等待很长时间。
如果我们使用类似JLM的工具就会发现,该Hash表关联的monitor使用非常频繁。解决这一问题的办法是使用能够替代HashTable的高扩展性 组件。在本例中,我们可以通过java.util.concurrent.ConcurrentHashMap替换该hash表。 ConcurrentHashMap把它的内部数据结构分成若干段。在应用中使用ConcurrentHashMap替换HashMap替换使线程针对多 个子组件竞争而不是单个大组件。使用ConcurrentHashMap的应用产生竞争的几率比之前要小得多。
还有一种办法降低访问共享组件的竞争几率。如果一个组件具有相反语义的操作,如栈的压入和弹出,这两种操作可以无需接触核心数据结构即可完成。这种技术最 早由Danny Hendler、Nir Shavit和Lena Yerushalmi引入,已经在Amino库中实现。这种方法的性能改善见图1。
图1.性能比较:EBStack和TreiberStack

传统上,大家都采用基于锁的方法来确保共享数据的一致性和对关键区域的互斥访问。锁的概念易懂,但基于锁的算法引起了很多挑战。其中一些著名的问题包括死锁、活锁、优先级倒置和锁竞争等。锁竞争会减少组件和算法的可扩展性。
无锁和无等待算法到现在已经存在二十多年了。它们被认为可以能够解决大部分与锁有关的问题。这些算法支持在不使用任何锁算法的情况下更新共享数据结构,不 仅如此,还有助于创建扩展性良好的算法。最初,这些无锁和无等待的算法纯粹是理论兴趣。但是,随着算法社区的发展和新硬件的支持,无锁技术在现实产品中得 到了越来越多的应用,比如操作系统内核、虚拟机、线程库等。
从JDK 1.5以后,JDK包含了这些无锁算法,比如ConcurrentLinkedQueue、AtomicInteger等。它们的伸缩性通常比对应的基于 锁的组件要好。当我们在Amino库实现新组件时,我们会使用目前研究的最新无锁算法。这使得Amino数据结构扩展性和效率非常好。但是有时候,特别是 在低核硬件上,无锁数据结构比基于锁数据结构的吞吐量差,但是一般来说,它们的吞吐量比较好。
从JDK 1.5以后,JDK包含了由Doug Lea开发的位于java.util.concurrent包的无锁的FIFO(先进先出)队列。该队列采用的算法基于单链表的并发操作,最初由 Michael和Scott开发。它的出列操作需要一次比较—交换,而入列操作需要两次比较—交换。这对入列和出列操作来说太容易了。但是分析数据(图 2)显示比较—交换操作占用了大部分执行时间,同时入列操作需要两次交换—比较,这增加了失败的概率。在现代多处理器上,一次成功的比较—交换操作要比一 次加载或者存储的时间长一个数量级,因为它们需要独立占用和冲刷处理器写缓存。
图2. CAS操作的执行时间

从图2可以看出,CAS操作执行时间的百分比为46.08%,几乎占了全部执行时间的一半。分析数据有一个操作的延迟。真正的时间是在"SETE AL"指令之后发生的。
Mozes和Shavit(MoS-queue)在它们的无锁队列算法中,提供了一种新颖的办法来降低入列操作时CAS的数量。其关键点在于替换单链表, 因为其中的指针在插入时需要浪费一次CAS操作,取而代之的是采用一个双链表,其中的指针在更新时只需要一次存储操作,如果事件乱序导致双链表不一致则可 以修复。
我们做了一次基准测试来比较ConcurrentLinkedQueue(JSR166y)和Mos-Queue的性能。结果在图3中显示。对于大量线程来说,Mos-Queue的性能优于JDK ConcurrentLinkedQueue。
图3. 性能比较:ConcurrentLinkedQueue和Mos-Queue

更多有关Mos-Queue的信息参见Mozes和Shavit的论文《An Optimistic Approach to Lock-Free FIFO Queues》。
Java虚拟机拥有一套强大、有效的内存管理体系。垃圾回收器能够压缩现有对象,以确保在垃圾回收之后Java堆里没有空隙。因为空闲空间在垃圾回收之后都是连续的,所以内存分配不多是增加了一个指针而已。
这对多线程应用同样有效,如果内存使用不敏感的话。JVM为每一个线程分配了一个线程范围的缓存。在内存分配时,线程范围的缓存首先被使用。只有在线程范围的缓存被耗尽之后才会使用全局堆。
在线程范围内分配内存对应用性能非常有益,但是如果分配过于频繁,则会不起作用。根据我们的经验,线程范围的缓存在分配频率高的情况下会很快耗尽。
如果在循环中需要暂时性的对象,则线程范围的类会比较有益。如果我们在线程本地对象中存储临时对象,我们可以在每一次循环迭代中重用它。虽然,线程本地类会增加额外的负担,但是大多数时候都比在内存中频繁分配内存要好。
图 4.性能比较:线程本地和分配

在本文中,我们介绍了使用Java创建高扩展性组件的几个重要原则。一般来说,这些原则通常很有帮助,但是它们无法替代谨慎的测试和性能调优。
Zhi Gan是IBM中国开发中心的软件工程师,在上海交通大学获得计算机安全方向的博士学位。Gan博士在SOA(面向服务的架构)、AOP(面向切面编程)和Eclipse领域拥有丰富的经验。他目前主要关注于使用Java/C++进行并行软件开发。
Raja Das是IBM软件集团的软件架构师。目前,他正在开发支持多核/众核系统的库和框架。他之前是WebSphere® Partner Gateway的产品架构师。Das博士感兴趣的领域包括编程语言、并行软件和系统。
Xiao Jun Dai是IBM中国开发中心的软件工程师,在中国科学院软件所获得计算机科学硕士学位。他在敏捷方法和编程语言方面拥有丰富的经验。他目前关注于并发编程和多核系统。
阅读英文原文:Creating Highly-Scalable Components in Java。
感谢曹云飞对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家加入到InfoQ中文站用户讨论组中与我们的编辑和其他读者朋友交流。
在本系列的第1部分,我们介绍了在Azure上进行网格计算开发的设计模式,而在第二部分,我们用C#开发了一个网格应用程序。在这篇文章中,我们将来运行它。
Julian Everett和Chris Matts认为:一个IT业务案例可以作为一种“文化基因(meme)”。它要在市场区隔这样的复杂生态系统中与其他文化基因——也就是其他IT业务案例 ——竞争。他们还揭示了其背后的理念。
本演讲将探讨如何用Microsoft Visual Studio 2010搭配MSF for AgileScrum的流程模版,助力您的团队进行Agile项目的开发工作。本视频为第一部分,演示如何进行项目计划与跟踪。
相比其他行业,IT技术由于信息流动便捷,新技术更新非常频繁。架构师经常面临新技术及传统方案选择的困惑。架构师应如何抓住本质构建新一代的应用?本文从几个方面提出一些思路供架构师参考。
InfoQ中文站最近采访了微软的Ramesh,在采访中,Ramesh从过程控制、架构与设计的控制以及测试组织等方面分享了他所带领Visual Studio软件生命周期管理工具团队使用敏捷方式组织管理大规模软件团队方面的经验。
在去年10月份的Kungfurails大会上,InfoQ中文站有幸采访了从台湾专程赶过来的张文钿,与他探讨了关于台湾Ruby社区的发展、Rails的商业化,Restful Design等话题。
3 条回复
关注此讨论 回复