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的用戶體驗帶來革命性的改變。

相關文章
相關標籤/搜索