云计算环境下的JVM虚拟化特性初探

日期: 2011-10-13 作者:李三红 来源:TechTarget中国 英文

  目前对于到底什么是云计算,什么样的平台属于云计算平台,等等围绕云计算相关的问题,不同的软硬件厂商对此都有自己不同的理解,有着自己不同的定义。他们所提供的云计算平台也是千差万别。谈到云计算,大家总会联想到这些方面的东西:比如说高伸缩性(High Scalability)、成本节约(Cost Saving)、按需使用(Use On Demand)等等。我们姑且不论云计算带来的这些纷繁多样的种种概念,如果仅仅从技术角度来讲,云计算本身并不是一个什么新奇的概念,可以理解为一种新型的IT服务交付使用方式,而传统的技术比如虚拟化、集群、网格等等都可以用来作为云计算平台的支撑技术。更详尽的有关云计算概念的介绍,请参考Wikipedia描述。

  云计算平台架构

  一般来讲,云计算平台被解释为如下的架构,图1所示。

图 1. 云计算平台架构

图 1. 云计算平台架构

  最下的一层是IaaS、提供CPU、网络,存储等基础硬件的云服务。在IaaS这一层,著名的云计算产品有Amazon的S3(Simple Storage Service), 提供给用户云存储服务。

  再上一层是PaaS,提供类似于操作系统层次的服务与管理 ,比如Google GAE,你可以把自己写 Java 应用(或者是Python)丢在Google的GAE里运行,GAE就像一个”云”操作系统,对你而言,不用关心你的程序在那台机器上运行。

  最后一层是SaaS,就是我们所熟悉的软件即服务。事实上SaaS的概念的出现要早于云计算,只不过云计算的出现让原来的SaaS找到了自己更加合理的位置。本质上,SaaS的理念是:有别的传统的许可证付费方式(比如购买Windows Office),SaaS强调按需使用付费。SaaS著名的产品很多,比如IBM的LotusLive、Salesforce.com等。

  多租户(Multi-Tenant)

  多租户的概念是伴随云计算而出现的,在这里有必要介绍一下,我们后面的讨论很大量涉及这个概念。

  多租户是一个软件架构方面的概念,指的是一个软件实例(Application Instance)可以供多个组织(Organization或者称为Tenant)使用。这里可以理解为应用程序的虚拟化,也即:多个租户共同使用同一个软件实例,但是每一个租户在数据集,配置等方面有自己的虚拟划分。实际上,在某种程度上,基于B/S架构的应用程序比如J2EE应用本身就是多租户性质的,因为大家都是使用浏览器来访问同一份部署在Application Server上的软件实例。这里之所以说是”某种程度”,是因为对于我们谈到的数据集按租户虚拟划分,现实的 J2EE 应用并没有支持。这个东西本文在后面会详细谈到。

  接下来的章节,将以S3和GAE为例子,围绕本文讨论的主题:多租户和资源管理, 简单介绍一下在这些典型的云计算平台上,多租户是怎么样进行部署的,以及在这些平台上的资源是如何被管理的。

  多租户及资源管理在S3的支持

  Amazon S3向用户提供的在线的(基于Internet)云存储服务。用户可以在S3上存储任何数据,这些数据可以是私有的亦或是可以被公共访问的。Amazon S3 支持 Web 浏览器或者BitTorrent来访问这些数据。一般来讲,用户使用S3:

  作为Backup server:存储你的私有数据到S3上去,这样你就不需要自己购买维护自己的备份磁盘,你只是付费从Amazon租赁磁盘空间。作为Data host: 存储数据到S3上,并且其他人有访问这些数据的权限。这里,你付费的对象不是传统意义上的ISP,而是Amazon。 S3存储涉及两个核心的概念:S3 bucket和S3 object。S3 object是对存在于Amazon S3上内容的抽象,其包括两方面的内容:数据和元数据,数据指的是你存储的真正的内容,比如一份PDF文档,一个HTML文件等。而元数据是对该数据的描述,比如可以用于指定当前存放的内容的Content-Type是text/html。每一个S3 object有一个唯一的Key来标志。S3 bucket是存放S3 object的容器。如果用个类比的话,S3 bucket相当于于磁盘上的文件系统,而S3 Object 则是这个文件系统中的一个文件。

  我们用一个简单的例子来看,在S3上多租户是怎么做出来的?

  假如想利用S3存储example.com web站点,首先需要创建名为”example.com”的bucket,然后在这个bucket里创建诸如:键值为 “”( 空串 ),”catalog”、“catalog/929339”的objects,这些objects对应的URL分别为:“http://example.com/”,“http://example.com/catalog/”,“http://example.com/catalog/929339”,而object的值就是相应的 HTML 页面,元数据Content-Type被设置为 text/html(相应于标准的http定义)。

  如果多租户的角度来看,我们可以把S3看作是在线的存储服务器,各个租户可以把自己的信息存储在S3上,比如 : 甲租户可以把 http://tenantA.com网站放在S3上,乙租户可以存储的是http://tenantB.com网站,各个租户共享S3的使用。

  除了多租户支持,S3还有资源的使用管理,计费等功能,如图2所示:

图 2. S3存储价格表

图 2. S3 存储价格表

  多租户及资源管理在GAE上的支持

  较之于IaaS、Google App Engine提供了更多的系统抽象能力。如果做一个比喻的话,IaaS相当于你有了一台拥有存储、网络、CPU等计算资源的计算机,而PaaS的Google App Engine则是装在这台计算机上的操作系统。设想一下,如果你开发一个传统意义上的J2EE应用,你要关心的事情除了应用程序本身之外,还有:要部署在什么样的应用服务器上,使用什么样的数据库,应用的可伸缩性(Scalability)等等。而有了GAE,这些东西你都不需要关心了,你只需要根据GAE规范开发J2EE应用,然后把它部署在GAE云里,GAE会帮助你管理除了你的应用程序本身的所有事情。

  GAE本身就是多租户的架构,即:来自不同租户的、任何一个符合GAE规范J2EE都可以部署在GAE上。

  而且,部署在GAE上的应用实例,如果你想把它作为一个SaaS应用的话,本身也可以实现多租户,也就是说:当你的一个部署在GAE上的J2EE应用需要被不同的租户使用时,可以使用Google提供的Namespace API将其虚拟化为多个应用实例。比如:该SaaS应用的不同的租户使用了不同的子域名(subdomain),tenantA 的子域名是tenantA.example.com,tenantB的子域名是tenantB.example.com等等,你可以使用下面的代码把不同的租户划归在不同的命名空间里,它们可以在共享同一个Datastore实例的基础上按照不同的租户实现相互的隔离。

  清单 1. GAE App Multitenancy
    

以下是引用片段:
 // Filter to set the namespace by different subdomain. 
 public class NamespaceFilter implements javax.servlet.Filter { 
  @Override 
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
                  throws IOException, ServletException { 
  //Make sure set() is only called if the current namespace is not already set. 
    if (NamespaceManager.get() == null) { 
      NamespaceManager.set(req.getServerName()); 
    } 
    //Chain into the next request. 
 chain.doFilter(req, res); 
 } 
 // … remaining Filter methods init() and destroy() 
 } 

  值得注意的是,GAE Namespace使用了Thread-local storage的技术。也就是说,你在Filter设置的Namespace Manager,其生存期 ( 或者叫做有效范围 ) 是存在于单个HTTP Request生命周期内 ( 即:当前线程服务该请求的期间内 ),而不是租户登录后的整个Session周期。

  类似于Amazon S3,GAE也提供了资源的管理计费功能,如图3所示。

图 3. GAE资源管理

图 3. GAE资源管理

  写到这里,总结一下:我们看到,无论是S3还是GAE,都对多租户以及资源管理做了支持。 事实上,不只是S3和GAE,多租户以及资源管理是任何一个云计算平台都必须具备的一个核心特质。

  如何我们简单的把S3和GAE看作是运行在Java平台的上的应用程序 ( 底层运行的是 JRE ! ),那么我们可以说:S3和GAE都在Java Application这个层次上对这两个需求做了它们自己的实现。进一步设想,如果我们要求底层的 JRE 本身就能对多租户和资源管理提供支持,那么有理由相信,这些部署在JRE上的Java应用,利用底层JRE的这些支持,应该能更高效、简洁、方便地来做这方面的工作。这也是本文接下来要谈的Java平台的两个重要的JSR:JSR284和JSR121的原因。一个是Java平台的资源管理支持,一个是Java平台的多租户支持。

  早在云计算兴起之前,Sun Lab就已经开始关注于Java平台的资源的共享与管理。比如:如果不借助操作系统的本地支持,我们没办法让一个普通的Java应用程序受限于CPU的使用,受限于Disk IO或者网络带宽的使用等等。当我们在同一台机器上运行多个JVM实例时,它们都是独立的用户进程,每个JVM的启动都需要实例化自己一份独立的JDK类库,其结果是:JVM启动时间(Startup)、内容(Memory footprint)等都消耗在重复的JVM初始化上。我们要问的问题是:多个JVM可以最大化地共享JDK运行时吗 ? 在共享的同时它们能够互不影响吗?这就是Sun发起Barcelona研究项目,Multi-Tasking Virtual Machine(即MVM)的主要原因。

  在云计算大行其道的今天,我们回过头再来审视一下Barcelona项目,MVM所有解决的两个目标:资源的共享与管理,在云计算的环境下显得愈加的重要。正如我们前面所讲的那样,作为云计算环境两个必备的两个特性,多租户和资源管理,前者要求最大化的共享软件实例,后者要求我们在共享的基础上如何对资源的使用进行隔离与控制。这也正和MVM的目标不谋而合。由MVM源生出了下面的两个JSR:121和284,这也应该是Java平台走向虚拟化的所必需的步骤。

  JSR284

  JSR284规范Resource Consumption Management API(RCM)定义了Java平台的资源管理框架。

  到目前为止,Java平台本身对于资源的管理与控制是非常有限的,在很多情况下,需要额外借助操作系统的资源管理能力对JVM进程进行管理,这样的管理是非常粗粒度的。尤其是放在云计算的大环境下,这种能力就更显得特别有限。可以设想一下,如果多租户的多个J2EE应用同时运行在同一个JVM上,资源的控制与管理就变得尤为重要。比如:我们需要防止DoS攻击,需要对租户进行QoS控制等等,这些目前Java平台本身是没法解决的,这也是JSR284诞生的重要原因。

  通过JSR284,你可以做什么?

  可以对资源在JVM进程内做更细粒度的,基于线程级别的控制,比如对它们做QoS限制;可以对JVM内资源的使用消费进行细粒度的 , 基于线程级别的隔离,防止DoS攻击等;可以通过JMX接口监视资源 ( 比如CPU使用率 ) 其使用情况。

  JSR284最早在2006年起草,有兴趣的读者,更多的细节可以阅读JSR284规范。

  另外,JSR284的引用实现(RI)已经作为JSR孵化项目在2011年一月份开始,读者可以访问jsr284-ri-tck了解更多的细节。

  JSR121

  在通常的情况下,我们运行的Java程序和Java运行时(即所谓的JRE)是一一对应的,即:我们运行一个Java应用,就会对应起一个Java运行时,这包括JVM,以及Java的类库。如图4所示,每一个Java应用都

  如图4,在OS上,每一个Java应用都作为一个独立的OS进程运行,像一般的OS进程一样,它们拥有自己独立的地址空间,互相之间是相互隔离的,一个Java应用的运行错误不会影响到另一个的运行。而且每个Java应用都可以相互独立的启动与停止。

图 4. 多个Java应用使用不同的JRE

图 4. 多个Java应用使用不同的JRE

  说了这么多的好处,我们再来看看这样传统的Java运行模式的缺点,特别是在云计算的环境下:

  首先是关于效率的问题。如果我们运行N个Java程序,那么同时需要N个JRE,在同一个OS上,这不但涉及的资源的浪费问题,比如多使用了内存,而且就Java程序的启动而言,也是没有效率的。Java程序本身启动就慢,这个过程需要初始化JVM,装载所需要的核心类等等,而这些动作实际上对于其它N-1个Java程序而言都是多余的,如果N个Java程序能共享同一个JRE,那么启动速度也会提升。

  其次是关于多个JVM进程间的通讯问题。一般情况下,如果多个JVM之间如果需要共享数据(比如共享某些类等),相互协作,是比较困难的,JDK本身没有对这种计算模式提供更多的支持。

  一个JRE可以同时运行多个Java程序,这个JSR121提出的初衷,如图5所示:

图 5. 多个Java应用共享同一个JRE.

图 5. 多个Java应用共享同一个JRE.

  在JSR121中,每个运行的Java程序被称作为一个Isolate,所有的Isolates共享同一个JRE。

  Isolate之间是相互隔离的,它们各自都有自己的生命周期。类似于在操作系统上的 进程有自己的独立地址空间,JVM上的Isolate也可以看作有自己独立地址空间,它们彼此不受影响。

  尤其在云计算的环境下,Java Isolate的计算模型更为合适。设想一下,我们可以在同一个应用服务器上部署不同的Isolates,每一个Isolate对应一个租户,这些Isolates共享JRE而又互相隔离。也许读者会奇怪:在目前的情况下,一个应用服务器也是可以部署多个J2EE应用的,这些独立的J2EE应用与我们这里讨论的Isolate有什么不同?

  不同在于:Isolates在物理上共享同一个JRE,但运行时逻辑上是相互隔离,彼此不会影响的。一个Isolate的错误不会影响整个JVM运行。而且,Isolate虽然共享基本的JDK类,但是你不可能直接通过这些基本的系统类在Isolates之间共享数据。这个就非常适合在云的环境下应用。

  很多时候,不同的租户来自不同的组织,不同的租户的的代码运行在同一个JVM进程里,保证它们之间的相互隔离是非常必要的。

  小结
 
  本文首先对云计算以及云计算平台IaaS、PaaS和SaaS做了扼要的介绍,并且以Aamzon S3和Google GAE为例子,重点介绍了这两个平台在多租户以及资源管理方面的做法,基于这些的应用背景,围绕云环境下的资源管理以及多租户支持这两个主题,对Java平台的JSR284和JSR121做了比较详细的阐述,未来的Java平台 (也许是Java8?)将会实现JSR284和JSR121来解决这两方面的需求。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • AWS如何支持存储生命周期管理?

    许多企业的许多数据都是不经验访问的。高存储量、低成本和低性能资源,在这些AWS数据管理解决方案是最佳的选择。

  • 云计算税收问题难倒厂商和用户

    无论是总统、国会还是议会主导的政府,历来都会寻找各种税收收入的新来源。而云计算,看起来是被放在仔细审查收入的最新领域之一。

  • AWS十条军规:云与云之间的差距咋就这么大?

    AWS开始于 2006 年 3 月 14 日 Amazon S3 的发布,距今已有十年时间。回首过去十年,我们在构建和运营 AWS 云计算服务中积累了大量的经验教训——这些服务不仅需要确保安全性、可用性和可扩展性,同时还要以尽可能低廉的成本提供可预测的性能。

  • 看爱奇艺如何玩转大数据

    以“大数据”为首的新兴技术使人类社会的数据种类和规模正以前所未有的速度增长,数据的产生已经完全不受时间、地点的限制,数据开始从简单的处理对象转变为一种基础性资源。