ZStack--查询API

 

IaaS软件用户面临的共同挑战是如何快速、准确地找到一个想要的资源;例如,从10,000台虚拟机中发现有EIP(16.16.16.16)的虚拟机。大多数IaaS软件经过API中的特定查询逻辑解决这个问题。ZStack不用特定查询,而是配备了一个框架,这个框架能够自动为每一个资源的每一个字段生成查询,并联合跨越了多个资源的查询,帮助用户管理云端数量庞大的资源。web

 

动机数据库

一个中型的云能够管理几百台物理主机和成千上万台虚拟机,由于IaaS软件不多有所有的查询API,致使寻找想要的资源成为挑战。大多数IaaS软件只容许用户使用少许条件(如name,UUID)查询资源,这些条件硬编码在查询API中。若是用户想要使用硬编码以外的条件作一个查询,例如,经过建立日期查询虚拟机,他们可能不得不最终列出全部虚拟机,而后用for..loop来过滤结果。使用任意字段查询资源至今在大多数IaaS软件都不被彻底支持,更不用说联合查询;例如,若是用户想要找到一个虚拟机,这个虚拟机的网卡应用了特定的安全组规则,他们可能不得不列出全部资源(虚拟机,安全组),而后作两次for..loop安全

另外一方面,相比相似JIRA的软件,大多数IaaS软件的UI是最粗糙简陋的。许多开发人员可能并无意识到糟糕UI的根源不是由于UI开发人员缺少CSS/HTML/JavaScript的技能,而是软件自己并不能提供强大的API来支持复杂的UI;例如,为了实现一个相似JIRA过滤器的功能,即只显示知足指定条件的资源,UI可能须要作不少的须要listing all then filtering by for..loop的后置处理工做,这些后置处理工做将把大量的资源拧在一块儿。网络

IaaS软件所以饱受折磨了一段时间;对此的解药就是要提供一种机制,这种机制能够自动为每一个资源的每一个字段都生成查询,并且能够处理join查询。app

 

问题框架

大多数IaaS软件使用关系型数据库(如MySQL)做为后台数据库,在这种数据库中资源一般被安排在单独的表中,好比虚拟机表,主机表,云盘表。对于每个资源,都有一个API用来获取该资源的单独的一条,它可能被命名为describe APIlist APIquery API;这些API一般有硬编码的参数,用来暴露一部分数据库表的列,容许用户经过少许的查询条件查询资源;这些参数是精心选择的,一般是对API设计者自身很是重要的列,例如,name、UUID。然而,因为并非全部的列都被暴露,用户常常遇到他们想查询的列不存在的状况,这样他们就必须检索全部的资源,而后使用一个或多个for..loop进行后置处理。工具

一个复杂的查询场景,可能须要使用联合查询,这种查询一般跨越多个数据库表;例如,找到一个EIP为16.16.16.16的虚拟机,它可能涉及虚拟表、网卡表和EIP表。一些IaaS软件使用数据库视图解决这个问题,这是另外一种硬编码方式,只能以固定的格式join选中的表,而在现实中表是能以很是复杂的方式被join的。在软件升级过程当中,若是一个视图指向的任一表已经改变了的话,视图也须要进行数据库迁移操做。oop

 

查询APIui

为了不在API中手动编码查询逻辑,并给用户提供能在任何地方查询任何东西的灵活的查询,ZStack建立了一个框架,这个框架能够自动为全部资源生成查询,而且不须要开发者写代码去实现查询逻辑;更进一步,该框架还能够生成各类join查询,只要所需的表已经经过外键链接。编码

在如下篇幅中,咱们将用zone做为一个例子来阐述这个使人惊叹的框架。一个zone在数据库中有下面的这些列:

FIELD

DESCRIPTION

uuid

zone UUID

name

zone name

description

zone description

state

zone state

type

zone type

createDate

the time the zone was created

lastOpDate

the last time the zone was operated

 

用户能够经过任何一个字段或字段组合来查询zone,并采用常规的SQL比较运算符如'=', '!=', '>', '>=', '<', '<=', 'in', 'not in', 'is null', 'is not null', 'like', 'not like'。

 

注意:在命令行工具中,一些运算符有不一样的格式:'in'(?=), 'not in'(!?=), 'is null'(=null), 'is not null'(!=null), 'like'(~=), 'not like'(!~=).

QueryZone name=west-coast-zone

QueryZone name=west-coast-zone state=Enabled

 

由于zone是ZStack中主要资源的祖先,不少资源都或多或少和它有关系;例如,一个运行中的虚拟机老是在一个zone内。像这种关系能够生成联合查询,如:

QueryZone vmInstance.name=web-vm1

 

如上表格所示,一个zone不会暴露任何叫vmInstance的字段,但在上述查询中有一个条件是由'vmInstance'开始的。这种查询在ZStack中称为扩展查询。这里vmInstance表明VM表,VM表有一个字段为zoneUuid(外键)指向zone表,所以查询框架能够理解它们的关系并生成联合查询。上面的例子能够被解释为“寻找运行着名字为web-vm1的虚拟机的zone”。进一步扩展这个例子,由于虚拟机网卡表有外键指向VM表,而且EIP表有外键指向虚拟机网卡表,查询zone也可使用EIP做为条件:

QueryZone vmInstance.vmNics.eip.vipIp=16.16.16.16

 

 

查询被解释为“查找一个区域,它上面的虚拟机的网卡的EIP为 16.16.16.16。如今您知道了查询接口的强大之处了!咱们甚至能够建立一些很是复杂的查询:

QueryVolumeSnapshot volume.vmInstance.vmNics.l3Network.l2Network.attachedClusterUuids=13238c8e0591444e9160df4d3636be82

 

这个复杂的查询目的是找到磁盘快照,目标磁盘快照是由虚拟机磁盘建立的,而该虚拟机有网卡在L3网络上,这个L3网络的父L2网络则是附加在一个集群上的,这个集群的uuid是13238c8e0591444e9160df4d3636be82。不要惊慌,你不多须要这么复杂的查询,但它确实证实了框架的能力。此外,SQL的一些特性例如选择字段、排序、计数和分页也是支持的:

QueryL3Network name=L3-SYSTEM-PUBLIC count=true
QueryL3Network l2NetworkUuid=33107835aee84c449ac04c9622892dec limit=10
QueryL3Network l2NetworkUuid=33107835aee84c449ac04c9622892dec start=10 limit=100
QueryL3Network fields=name,uuid l2NetworkUuid=33107835aee84c449ac04c9622892dec
QueryL3Network l2NetworkUuid=33107835aee84c449ac04c9622892dec sortBy=createDate sortDirection=desc

 

实现

尽管查询API功能是如此强大,实现倒是很是简洁的。当添加一个新的资源时,开发人员不须要写任何关于查询逻辑的代码,除了定义查询API和资源自己。要实现zone的查询API,开发人员须要:

 

  1. 使用查询元数据注解zone的inventory
@Inventory(mappingVOClass=ZoneVO.class)
@PythonClassInventory
@ExpandedQueries({
@ExpandedQuery(expandedField="vmInstance",inventoryClass=VmInstanceInventory.class,       
foreignKey="uuid",expandedInventoryKey="zoneUuid"),               
@ExpandedQuery(expandedField="cluster",inventoryClass=ClusterInventory.class,       
foreignKey="uuid",expandedInventoryKey="zoneUuid"),               
@ExpandedQuery(expandedField="host",inventoryClass=HostInventory.class,       
foreignKey="uuid",expandedInventoryKey="zoneUuid"),               
@ExpandedQuery(expandedField="primaryStorage",inventoryClass=PrimaryStorageInventory.class,       
foreignKey="uuid",expandedInventoryKey="zoneUuid"),               
@ExpandedQuery(expandedField="l2Network",inventoryClass=L2NetworkInventory.class,       
foreignKey="uuid",expandedInventoryKey="zoneUuid"),               
@ExpandedQuery(expandedField="l3Network",inventoryClass=L3NetworkInventory.class,       
foreignKey="uuid",expandedInventoryKey="zoneUuid"),               
@ExpandedQuery(expandedField="backupStorageRef",inventoryClass=BackupStorageZoneRefInventory.class,       
foreignKey="uuid",expandedInventoryKey="zoneUuid",hidden=true),               
})
@ExpandedQueryAliases({
@ExpandedQueryAlias(alias="backupStorage",expandedField="backupStorageRef.backupStorage")       
})
publicclassZoneInventoryimplementsSerializable{
privateStringuuid;   
privateStringname;   
privateStringdescription;   
privateStringstate;   
privateStringtype;   
privateTimestampcreateDate; 
privateTimestamplastOpDate; 
}

上面的注解声明了zone和其余资源之间的关系,这是zone扩展查询的基础。

 

2.定义一个查询API

@AutoQuery(replyClass=APIQueryZoneReply.class,inventoryClass=ZoneInventory.class)
publicclassAPIQueryZoneMsgextendsAPIQueryMessage{
}

 

3.在区域的API配置文件中声明查询API

<?xml version="1.0" encoding="UTF-8"?>
<servicexmlns="http://zstack.org/schema/zstack">
<id></id>   zone
<interceptor></interceptor>   ZoneApiInterceptor
   
<message>    
<name></name>       org.zstack.header.zone.APIQueryZoneMsg
<serviceId></serviceId>       query
</message>   
</service>

API APIQueryZoneMsg经过指定服务ID query被路由到查询服务。就是这样了,查询逻辑不须要一行代码;查询服务会把其他部分自动完成。全部的ZStack查询API都像这样定义,添加新资源的查询API是很是容易的。

 

当前限制

主要的限制是在查询条件中,只有逻辑AND是被支持的,OR是不被支持的。例如:

QueryZone name=west-coast-zone state=Enabled

上述查询语句能够被解释为“寻找区域名字为west-coast且state是Enabled的区域”咱们这么作的缘由是咱们由ZStack源代码中SQL的使用分析得出99%的组合的查询条件都是基于AND逻辑的。另外一方面,若是逻辑OR在没有建立DSL的状况下就被引入,要保持代码简洁是很是困难的。然而,在不少状况下,OR可使用比较操做in(?=)实现:

QueryZone name=west-coast-zone state?=Enabled,Disabled

上述例子表述的是“寻找名字为west-coast的区域,而且它的状态是Enabled或Disabled”,未来,咱们将引入DSL风格的查询语言,例如:

QueryZone name=west-coast-zone AND (state=Enabled OR state=Disabled)

 

总结

这篇文章中,咱们演示了ZStack的查询API。经过使用这个强大的工具,用户能以相似关系型数据库的方式查询任何资源。未来,ZStack将创建一套高级的UI,它可使用查询API建立各类各样的视图(过滤器),例如,展现全部运行在同一L3网络的虚拟机,为IaaS UI的用户体验带来革命性的改变。

相关文章
相关标签/搜索