数字图书馆云服务平台的重要组成部分是基础设施云。针对基础设施云的分布式、异构性等特点,提出基于模块化的基础设施云设计与实现方法,分析每个模块的主要功能以及如何将各个模块进行互联等一系列关键问题,为今后基础设施云的搭建和优化提供重要的参考。
The IaaS(Infrastructure as a Service) is an important part of digital library cloud services platform. As the IaaS is distributed and heterogeneous, a method is proposed to design and implement IaaS in modules. And a detail analysis of each modules and the key to interconnect the various modules are given as an important reference for the future infrastructure.
数字图书馆云服务平台的重要组成部分是基础设施云,即基础设施即服务。目前国内外工业界与学术界开发出若干基础设施云,国外如Amazon EC2[ 1]、Microsoft Azure[ 2];国内如移动大云、云快线、万网等。由于工业界并不披露内部系统实现细节,且学术界中每个云都有自己的一套系统架构及定义,造成概念复杂、系统模块不清晰,难以用于学习与研究,至今未有一套标准的基础设施云构建方案。为了使不管是用户在数字图书馆建设或是工业生产中能够高效、便捷地构建适应各自需求的基础设施云,本文提出并实现了基于模块化的基础设施云,通过一些开源框架构建可分布式部署且支持在线扩展的基础设施云。
本文主要以两个典型的开源基础设施云为研究对象,对其功能、体系结构及源代码进行分析:
(1)Eucalyptus[ 3],它是加州大学圣巴巴拉分校[ 4]计算机科学系的一个研究项目,由Rich Wolski(Rich Wolski是VGrADS[ 5]项目的首席研究员,该项目由美国国家科学基金资助)的研究小组最终设计并实现;
(2)OpenStack[ 6, 7, 8],该项目是由RackSpace[ 9]和美国国家航空航天局(NASA)合作研发的云计算平台,其主要用于建立“私有云”。
通过对开源基础设施云的分析发现,学术界中每个云都有自己的一套系统架构及定义,并且适用场景较为专一,若要使用诸如此类基础设施云,可能出现组件复杂、冗余、管理不便等情况,造成概念复杂、系统模块不清晰,未有一套标准的基础设施云构建方案,难以应用管理、学习与研究。因此,本文设计并实现基于模块化的基础设施云,保证基础设施云各子系统之间协调工作,最大限度地提高构建基础设施云的效率、灵活性和使用简洁性,为用户提供一套切实可行的完整基础设施云解决方案。
本文通过将基础设施云抽象成若干个核心模块集成起来的系统,使每一个子系统都有明确的功能,对外提供特定的接口。对于两个实现相同功能的组件,只要其遵循该模块要求的接口规范,则可以互相替换,从而可以方便、自由地选择组件构建基础设施云,解决了基础设施云的概念复杂、难以构建等问题。
基础设施云系统的体系结构如图1所示:
基础设施云系统包括以下子系统:虚拟化运行环境子系统;云存储系统:在线存储子系统与虚拟磁盘子系统;虚拟网络子系统;模块互联子系统;用户管理子系统(由于该子系统并非基础设施云所特有,因此本文不做深入研究)。
虚拟化运行环境子系统利用虚拟化技术,实现对CPU、内存、硬盘等物理资源的逻辑抽象和统一表示,抽象出的虚拟资源组成一个或多个虚拟机,从而实现对物理资源的统一调配和管理。虚拟化运行环境子系统主要提供4个功能,分别是:
(1)资源管理,包括资源虚拟化和资源监控。
(2)节点调度,虚拟化运行环境子系统由集群组成,每个集群中的节点可以运行一个或多个虚拟机。当用户申请虚拟机时,集群控制器要遵循某种调度策略选择节点控制器,从而在资源充足的前提下,保证资源的合理分配和负载均衡。
(3)虚拟机生命周期管理,虚拟机生命周期是指从用户申请虚拟机到用户关闭虚拟机的整个时间段。
(4)虚拟机监控,虚拟化运行环境子系统通过虚拟化技术将物理资源虚拟成虚拟资源,最终呈现给用户的是一个个的虚拟机,因此对虚拟机监控,实时掌握虚拟机的状态,以此判断虚拟机是否正常运行。
通过对现有基础设施云的代码分析发现,它们均使用集群管理物理资源,因此该子系统也以集群的形式管理多个物理服务器,通过设置一个集群控制器对系统中的节点控制器进行管理,每个节点控制器可以运行一个或多个虚拟机。节点控制器上除了运行虚拟化任务外,还需要将所有任务发布成Web Service的形式向集群提供一个服务调用地址。集群控制器通过Web Service客户端定时向所有节点控制器发送心跳测试以判断节点控制器的存活状态,并通过该服务调用地址调用节点控制器上的相应服务,如启动虚拟机等。集群控制器上需要一个配置文件来记录该集群中的所有节点IP地址,并同样以Web Service的形式提供一个注册节点的服务。当需要在线扩展节点时,只需调用该注册节点的服务,集群控制器将会把该IP记录到内存中的节点数组中和上述配置文件中。当集群控制器发送心跳时会循环节点数组,向该数组中的所有IP发送心跳信息。从而实现在线扩展服务器的功能,且保证当服务器重启时能够从配置文件中获取该集群中的所有节点信息,确保集群的可靠。
云存储系统通过两种方式保存用户数据:虚拟磁盘子系统和在线存储子系统。虚拟磁盘子系统主要存储用户对虚拟机的操作,比如安装的软件包。在线存储子系统则可让用户以文件的形式存储数据。
虚拟磁盘子系统主要分为三部分:磁盘控制器、节点控制器和在线存储。磁盘控制器是虚拟磁盘的实际存储位置,它通过存储网络传输协议iSCSI将本地的虚拟磁盘映射为节点控制器中的磁盘设备;节点控制器将通过虚拟化适配层将这些磁盘设备映射为虚拟机中的磁盘;在线存储保存存储控制器中虚拟磁盘的快照。存储控制器和节点控制器之间通过存储网络协议连接,主要用于传输磁盘文件内容,当用户在虚拟机中读磁盘时,磁盘内容通过存储网络协议传输给虚拟机;当用户写磁盘时,磁盘内容通过存储网络协议最终写入存储控制器上的磁盘文件中。存储控制器和在线存储之间通过HTTP协议上传和下载磁盘快照。
在线存储子系统的主要功能是让用户以文件的格式存储数据。它以存储桶(Buckets)和对象(Objects)的结构进行组织,其中Buckets与文件系统中的目录对应,而Objects与文件系统中的文件对应。该子系统为用户永久存储数据,主要功能包括:创建、删除、列举文件夹;上传、下载、删除文件;对文件夹和文件设置权限控制信息;存储虚拟机镜像,允许用户和其他子系统对虚拟机镜像进行上传、下载、删除等操作;提供其他机制方便用户管理存储于系统中的数据,如通过为Bucket设置Versioning属性来管理不同版本的文件,其中Versioning属性有两种取值:Enabled、Disabled。当指定Bucket的Versioning为Enabled状态,则用户可以在该Bucket中保留同一个Object的多个版本,每个Objcet都拥有一个使用Java语言生成的UUID作为唯一标识的versionId,具体为:versionId = UUID.randomUUID().toString().replaceAll("-", "")。用户上传Objcet可以指定相同的名称,系统以versionId区分相同名称的Objcet。如果用户指定Bucket的Versioning为Disabled,则Object的versionId为Null,这种情况下用户上传相同名称的Object,系统只保留最新上传的Object。
现有基础设施云中的虚拟网络子系统比较复杂,使用太多模式进行配置却又难以指明具体使用场景,造成管理不便,本文中的虚拟网络子系统主要解决虚拟机实例的网络通信问题,提供4个功能,即:
(1)通过配置虚拟机实例的内网IP,使得虚拟机实例之间可正常通信;
(2)定义安全组,让运行在同一组内的虚拟机实例具有相同的访问规则(如Ping、SSH);
(3)实现弹性IP功能,使用户能够动态设置虚拟实例的IP;
(4)实现网络隔绝,使处于不同安全组的虚拟机之间的网络流量隔离。该子系统以工具类的形式供其他子系统调用,通过调用一些系统命令实现网络相关功能,如添加一条转发规则可以调用命令:
iptables -t nat -A PREROUTING -d XX.XX.XX.XX -j DNAT --to-destination XX.XX.XX.XX
基础设施云由多个子系统组成,不同子系统间需进行信息交互,因此,模块互联子系统的主要功能有:
(1)互联和集成其他子系统;
(2)系统入口与负载均衡,基础设施云提供两个用户级接入点,即虚拟化运行环境子系统接口和云存储系统接口;
(3)提供信息流和控制流在整个基础设施云系统中的流动渠道。
该子系统的关键功能是启动虚拟机,当物理服务器接收到启动虚拟机请求后,适配器查询资源管理器是否有足够的硬件资源分配给虚拟机。如有则准备镜像资源、虚拟机XML配置文件等,之后调用Libvirt 虚拟化库的API 启动虚拟机,返回调用成功信息。当集群控制器收到启动虚拟机请求后,首先调用虚拟网络子系统请求网络资源(MAC地址、Public IP和Private IP),并调用节点调度策略为虚拟机寻找资源满足申请需求的节点,找到节点后,则利用Axis2/C(Web Service客户端)调用该节点的Web Service启动虚拟机的服务,与此同时,集群控制器还要将该虚拟机信息添加到InstanceCache(该结构保存了集群中的所有虚拟机信息,包括虚拟机ID、虚拟机镜像ID、虚拟机类型、所在节点的URL、挂载的虚拟磁盘信息、网络地址信息等)中,最后将运行虚拟机的节点的可用资源信息减去刚分配给虚拟机的CPU、内存和硬盘资源,其流程如图2所示:
启动虚拟机功能关键代码如下:
for (i=0; i<5 && dom == NULL;i++){//最多尝试启动虚拟机5次,如果5次都失败,则返回
sem_p (hypervisor_sem);//锁定虚拟机相关信号量
//Libvirt的库函数,node_state.conn为虚拟监控程序的连接,在init函数中初始化
dom = virDomainCreateLinux (node_state.conn, xml, 0);
sem_v (hypervisor_sem);//解锁虚拟机相关信号量
}
虚拟磁盘子系统的关键功能是将虚拟磁盘挂载到虚拟机上。当该子系统接收到挂载磁盘命令时,找到要挂载的虚拟机,查看该虚拟机是否活动,是则发送挂载命令是虚拟磁盘挂载到虚拟机上。具体流程如下:
(1)搜索存储控制器上的target:iscsiadm -m discovery -t st -p xx.xx.xx.xx;
(2)将target映射为本地虚拟磁盘:iscsiadm -m node --targetname "unregistered:store3" --portal "xx.xx.xx.xx:3260" -login;
(3)使用Libvirt的 virsh attach-device 命令将虚拟磁盘挂载到虚拟机上,首先完成 virsh attach-device 命令所需要的XML文件(取名为:virtual_volume.xml),内容如下:<disk type='block'> <driver name='phy'/><source dev="/dev/sdb"/><target dev='sdb' bus='usb'/></disk>,其中<source dev="/dev/sdb"/>表示虚拟磁盘在节点控制器上所对应的磁盘设备为:/dev/sdb,<target dev='sdb' bus='usb'/>表示虚拟磁盘映射到虚拟机中所对应的设备是/dev/sdb,并以usb的总线方式挂载到虚拟机上;
(4)挂载虚拟磁盘(假设已开启的虚拟机名称为domain_name,挂载所需的XML文件名称是:virtual_volume.xml),使用命令virsh attach-device domain_name virtual_volume.xml 即可将虚拟磁盘挂载到虚拟机中。
在线存储子系统的关键功能是上传文件。该子系统将用户上传的数据流保存在HttpRequest中,服务器获得上传的数据流后,将上传数据流分块保存在一个数据块队列中。当同时有多个用户或单个用户上传多个文件时,使用多线程机制并保证线程安全使上传数据不互扰。其主要流程如图3所示:
描述如下:
(1)数据库中查找上传文件所在的目录,并检查该Bucket是否具有可写权限(即是否可以保存Object);
(2)判断目录的Versioning属性是否设置为Enabled,如果为Enabled,则产生一个全局唯一随机数赋给文件的versionId,否则其versionId为Null;
(3)获得上传文件的数据块队列;
(4)在目录中写入文件。
该子系统的关键功能为系统入口服务。该子系统使用HTTP协议提供服务,为支持多个客户端的并发请求,使用Netty框架来发布接入点服务。需先进行Netty服务器的配置和启动,可在端口关联的Pipeline上添加如下handler以对请求做异步处理,NioHttpDecoder()将接收到的数据流转化为Java对象;HttpResponseEncoder()为Netty自带类,将HTTP响应Java对象编码为HTTP协议并发送;ChunkedWriteHandler()为Netty自带类;支持异步写入大数据流,管理大数据流如文件传输时的复杂状态;Handler_construct()进行handler的选择添加和功能执行。
模块互联系统入口关键代码如下:
//配置服务器-使用Java线程池作为解释线程
ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
//设置Pipeline工厂
bootstrap.setPipelineFactory(new MessageServerPipelineFactory());
//绑定端口,发布服务
bootstrap.bind(new InetSocketAddress(port));
为了向用户提供透明化服务,该系统设计实现了图形化管理系统对基础设施云中各种资源进行生命周期管理和访问。
管理系统主要功能界面如图4所示:
主界面分为标签栏、功能按钮栏、用户资源栏。标签栏包括:虚拟机运行实例管理、虚拟机镜像管理、虚拟机磁盘管理三项。点击左上角下拉列表可以用列表或图标的形式显示当前列表的内容,点击刷新所有数据,可读取云端数据更新客户端中显示的信息。
登录基础设施云管理系统,进入虚拟机镜像管理界面,选择镜像、虚拟机类型、虚拟机数量、所在区域、安全组,点击“启动”按钮,启动虚拟机实例。以选择建立Windows XP镜像为例,进入虚拟机实例管理界面,选择刚启动的虚拟机实例,点击“连接”按钮,点击“远程桌面”按钮进入Windows XP虚拟桌面,如图5所示:
进入虚拟机后,安装游戏服务端软件,本例服务端软件从网络上下载,运行程序,提供网络游戏服务,等待客户端接入游戏。
至此该服务已经运行于云端服务器上,可在其他PC上安装游戏客户端,连接该服务器进行游戏。
该应用实例展示了基础设施云管理系统提供的服务相比于传统服务方式的优点:
(1)用户可以根据需要获取相应的计算能力;
(2)主要的维护工作都由基础设施云供应商负责,用户不必关心服务器状况;
(3)用户不需要前期的硬件购置成本;
(4)基础设施云主要是提供虚拟机且能支持多种操作系统,可支持广泛的应用;
(5)基础设施云只需几分钟就能为用户提供计算资源,而传统的企业数据中心则往往需要几周时间,同时计算资源可以根据用户需求来调整大小。
本测试对象为基金项目中基于模块化构建的基础设施云——YUN系统(简称系统)。
本部分测试的重点在于评估系统对虚拟机生命周期管理操作、编程接口(Libvirt API)和终端命令(Virsh)三者的时间开销。
(1)测试方法
测试采用的虚拟机管理器为QEMU+KVM(qemu-kvm-0.14.0),虚拟机采用的是Ubuntu10.10操作系统。分别使用系统、Libvirt API、Virsh终端命令三种方式对虚拟机进行包括启动、重启、关闭、迁移的4种操作。每种方式、每种操作执行50次,以求结果尽量真实准确。
(2)测试结果与分析
图6显示了Libvirt、Virsh和系统分别对虚拟机启动、关闭、重启和迁移的对比结果。
其中的每个柱体代表每种方式、每种操作的执行50次操作的平均时间。结果显示,除启动虚拟机外,三种方式对关闭、重启和迁移虚拟机的时间开销相差无几。关闭虚拟机平均花费时间在0.08秒左右,重启虚拟机平均花费时间在1.65秒左右,迁移虚拟机平均花费时间在3.5秒左右。系统启动虚拟机的平均时间接近27秒,是通过Libvirt执行相同操作所需时间的18倍,时间相差大的原因主要是系统在真正执行启动虚拟机的操作前会对系统记录的所有虚拟机状态进行更新,并回收那些已经处于关闭或无法访问状态的虚拟机的资源,更新相应数据结构。由此表明,系统对虚拟机生命周期管理引入的额外代价可以忽略不计。
(1)测试方法
本测试内容为基础设施云中的在线存储系统模块性能测试,在4个云存储服务上分别以1KB和10MB作为操作对象进行了测试,使用Linux下的time系统命令对每一种操作分别测了200组数据,其统计信息如图7所示:
其中C1代表Amazon AWS的S3,C2代表Microsoft Azure的XStore,C3代表YUN系统基于Web的在线存储服务,C4代表Rackspace CloudServers的CloudFiles。
(2)测试结果与分析
分析图7可知,在测试小文件的时候,YUN系统的响应时间与其他云存储的响应时间差距在50ms以内,这种细微的区别并不会影响用户体验,也即性能相当;在测试大文件的时候,YUN系统的传输速率基本等于网络带宽,也就是说系统带来的额外开销也完全可以忽略,只要有足够的物理环境支持,YUN系统即能为用户提供良好的性能。
(1)测试方法
对于块的存储方式,重点在于比较局域网里用于实现网络存储的两种通信协议AOE和iSCSI。基于YUN系统,在已经运行虚拟机上,对于不同的协议,都挂载一个相同的存储卷(大小为5GB),然后利用POSTMARK来测试在使用不同协议的情况下,文件系统的吞吐率,这里主要测的是小文件的存储,文件大小始终保持在1B-10KB之间。
(2)测试结果与分析
对两者的性能做比较,将POSTMARK的事务数保持在50 000,然后变化文件的总数,结果如图8所示。
随着文件数的增加,存储的性能会显著下降,主要是因为文件检索时间在增加。但总体来说,AOE都要优于iSCSI。图9则显示了并发的事务数对不同协议的影响,而文件数固定在50 000个。
同样,随着事务数的增大,iSCSI的吞吐率所受的影响较大,而AOE所受的影响较小。从这两组测试可以看出,在局域网上对于小文件的存储使用AOE比iSCSI能够获得更好的性能。这主要是因为AOE作为基于局域网的网络通信协议比iSCSI更加简单、快捷,更能体现出局域网内高通信速率。
(1)测试方法
可扩展性是云存储的一个重要特性,这里通过在不同虚拟机个数下AOE与iSCSI所表现出来的性能,来比较二者的可扩展性。同样使用POSTMARK, 把文件数与事务数固定设为50 000。对于每一种协议,在一个宿主机上同时启动1-5台虚拟机,然后为每一台虚拟机分配一个独立的存储卷,在每台虚拟器上同时运行POSTMARK,得出一个平均值。
(2)测试结果与分析
最后测出的结果如图10所示:
![]() | 图10 AOE与iSCSI可扩展性比较 |
可以看出AOE不但整体性能优于iSCSI,而且当虚拟机数目增加时,iSCSI所受的影响也明显大于AOE。所以在扩展性上AOE也优于iSCSI。
本文提出并实现了基于模块化的基础设施云,经实际应用测试,功能及性能均运行良好。通过将基础设施云抽象成若干个核心模块集成起来的系统,使每一个模块或子系统都有明确的功能,对外提供特定的接口。对于两个实现相同功能的组件,只要其遵循该模块要求的接口规范,则可以互相替换,从而可以自由地选择组件构建基础设施云,一定程度上解决了基础设施云的概念复杂、难以构建等问题。
云计算是未来技术发展的趋势,数字图书馆的建设最终也将进入云时代,云安全将是研究者及用户最关心的问题,而数字图书馆的建设离不开一个可信的云计算平台,这些问题都有待于在今后的工作中继续研究。
[1] |
|
[2] |
|
[3] |
|
[4] |
|
[5] |
|
[6] |
|
[7] |
|
[8] |
|
[9] |
|