為了簡(jiǎn)化UI工作并為運(yùn)維人員提供更靈活的資源查詢模式,ZStack推出了第一種面向IaaS的查詢語(yǔ)言—— ZStack查詢語(yǔ)言(ZQL)。
背景
IaaS管理大量數(shù)據(jù)中心資源。如何靈活快速地查詢這些資源對(duì)于操作和維護(hù)人員來(lái)說(shuō)是一個(gè)難題。在過(guò)去的IaaS軟件中,僅為單個(gè)資源的某些字段提供有限的API查詢支持,例如,可以通過(guò)虛擬機(jī)的IP字段查詢,這是不夠的或不靈活的。在進(jìn)行復(fù)雜查詢時(shí),運(yùn)維人員通常不得不繞過(guò)IaaS軟件直接查詢其后端數(shù)據(jù)庫(kù)。這要求操作和維護(hù)人員了解IaaS資源的內(nèi)部關(guān)系,并帶來(lái)數(shù)據(jù)庫(kù)誤操作的風(fēng)險(xiǎn)。
從ZStack發(fā)布的第一個(gè)版本的ZStack開(kāi)始,我們致力于在API級(jí)別提供數(shù)據(jù)庫(kù)級(jí)查詢功能。 ZStack的每個(gè)資源都包含一個(gè)查詢API,它可以傳遞資源自己的字段和相關(guān)的資源資源。該字段被查詢。例如
QueryVmInstance名稱?=web-vm state=正在運(yùn)行
此查詢包含web-vm字符串的所有名稱,即正在運(yùn)行的VM。另一個(gè)例子
QueryVmInstance vmNics.eip.vip.ip='22 .22.22.22'
EIP是虛擬機(jī)的關(guān)聯(lián)資源。 NIC綁定到虛擬機(jī),EIP為22.22.22.22。
Query API功能強(qiáng)大:
用戶可以通過(guò)count參數(shù)返回滿足查詢條件的資源數(shù),類似于SQL的count();
指定fields參數(shù)返回的字段,類似于SQL uuid,name from;
通過(guò)sortBy,sortDirection參數(shù)指定排序的字段和方向,類似于SQL order by;
通過(guò)啟動(dòng),限制參數(shù)來(lái)實(shí)現(xiàn)分頁(yè)查詢,類似于SQL限制和偏移。
除了易于使用之外,查詢API也很容易定義。在程序員向ZStack添加新資源之后,他只需要在代碼中定義以下類:
@AutoQuery(replyClass=APIQueryVmInstanceReply.class,inventoryClass=VmInstanceInventory.class)
公共類APIQueryVmInstanceMsg擴(kuò)展了APIQueryMessage {
}
無(wú)需編寫(xiě)任何實(shí)現(xiàn),相應(yīng)的資源具有Query API。
ZStack內(nèi)部包含一個(gè)查詢API,它處理所有資源,將它們轉(zhuǎn)換為相應(yīng)的SQL語(yǔ)句,并在查詢條件中包含相關(guān)資源條件時(shí)生成相應(yīng)的Join子句。
基于查詢API,ZStack 0.6版本包含超過(guò)400萬(wàn)個(gè)單項(xiàng)查詢條件,組合查詢條件數(shù)為400萬(wàn)個(gè)階乘。操作和維護(hù)方便,UI設(shè)計(jì)復(fù)雜。但是查詢API仍然存在一些缺陷:
查詢條件只能是AND邏輯,不能執(zhí)行OR邏輯,也不能用于實(shí)現(xiàn)條件之間復(fù)雜的邏輯組合
不支持類似于SQL的子查詢子句
單個(gè)API只能查詢一個(gè)資源,查詢多個(gè)資源時(shí)需要調(diào)用多個(gè)API。
不支持與監(jiān)控系統(tǒng)集成查詢語(yǔ)言
隨著ZStack UI場(chǎng)景變得越來(lái)越豐富,Query API的局限性使得UI方面的工作越來(lái)越多。許多方案需要多次調(diào)用Query API才能進(jìn)行數(shù)據(jù)組合。例如,在監(jiān)控Top 5頁(yè)面(用于檢測(cè)最大資源資源率為5資源的CPU,內(nèi)存,磁盤(pán),網(wǎng)絡(luò)和其他資源)中,需要使用Query API查詢虛擬機(jī),物理機(jī)和其他資源信息返回,然后調(diào)用監(jiān)控系統(tǒng)ZWatch API查詢相應(yīng)的監(jiān)控?cái)?shù)據(jù)。
查詢API將在未來(lái)的ZStack版本中保留并維護(hù),其后端實(shí)現(xiàn)已被原始查詢服務(wù)中的ZQL替換。
ZStack Query Language
使用著名問(wèn)題管理系統(tǒng)JIRA的開(kāi)發(fā)人員知道JIRA在執(zhí)行高級(jí)搜索時(shí)提供查詢語(yǔ)言JQL(JIRA查詢語(yǔ)言),并且可以為每個(gè)JIRA票證使用類似SQL的DSL(域特定語(yǔ)言)。有效查詢的字段。ZQL類似于JQL,也是類似SQL的DSL。我們來(lái)看一個(gè)例子:
查詢vminstance,其中name='webvm'或vmnics.ip='192.168.0.10'或(vmnics.eip='172.20.100.100'(cpuNum>=8或clusterUuid in('fe13b725c80e45709f0414c266a80239','73ca1ca7603d454f8fa7f3bb57097f80')))/p>
在這個(gè)簡(jiǎn)單的示例中,您可以看到許多熟悉的SQL元素,例如和/或條件,括號(hào),>=/in運(yùn)算符等。ZQL可以看作是SQL的一個(gè)子集,加上ZStack根據(jù)自己的需要執(zhí)行的增強(qiáng)查詢語(yǔ)言。其基本結(jié)構(gòu)如下:
QUERY queryTarget(WHERE條件+)? restrictBy? returnWith?通過(guò)...分組?排序依據(jù)?限制?偏移?過(guò)濾? namedAs?
query關(guān)鍵詞
ZQL語(yǔ)句通常以query關(guān)鍵字開(kāi)頭,該關(guān)鍵字表示要查詢的資源或資源字段的集合。在前面的示例中,vminstance表示虛擬機(jī)。例如,host表示物理機(jī)器,zone表示區(qū)域??梢圆樵兊乃匈Y源都有自己的名稱。如果你不想返回資源的所有字段,你只想獲得資源的一個(gè)或多個(gè)字段,實(shí)現(xiàn)uuid的功能,名稱來(lái)自...類似于SQL,你可以在之后指定字段名稱資源名稱和多個(gè)字段名稱用逗號(hào)分隔,例如:
查詢vminstance.uuid,name,cpuNum
此查詢返回所有虛擬機(jī)的UUID,名稱和CPU數(shù)。
除了查詢關(guān)鍵字之外,查詢還可以從count和sum關(guān)鍵字開(kāi)始。前者返回滿足查詢條件的資源總數(shù),后者可以對(duì)資源的某個(gè)字段求和。例如:
Vminstance cpuNum> 8
返回系統(tǒng)中具有8個(gè)以上內(nèi)核的虛擬機(jī)總數(shù)。
按名稱匯總vminstance.memorySize,其中cpuNum> 8
虛擬機(jī)名稱按虛擬機(jī)名稱分組,CPU核心數(shù)超過(guò)8個(gè),其memorySize字段相加。如果系統(tǒng)中有兩個(gè)名為webvm的10CPU8G虛擬機(jī),則求和后返回的webvm虛擬機(jī)的總內(nèi)存使用量為16G。轉(zhuǎn)換為SQL是:
來(lái)自vminstance的sum(memorySize),其中cpuNum>按名稱分組8
WHERE從句
ZQL的WHERE子句類似于SQL的WHERE子句。它支持和/或邏輯運(yùn)算符和括號(hào)。條件比較支持=,!=,>,>=,<,<=,like,not like,is null,not null,in,not in,查詢名稱是字段的名稱資源。與SQL的區(qū)別在于ZQL的查詢條件可以是關(guān)聯(lián)資源的字段,例如:
查詢vminstance在哪里
vmNics.eip.vip.ip='22 .22.22.22’
請(qǐng)注意,在where子句之前不需要從xx子句編寫(xiě)類似SQL的,因?yàn)椴樵僾minstance已經(jīng)定義了要查詢的資源
這里vip與eip相關(guān)聯(lián),eip與vmnic相關(guān)聯(lián),vmnic與vminstance相關(guān)聯(lián),然后我們可以指定vip的IP作為查詢條件。這是ZQL的強(qiáng)大功能。對(duì)于多個(gè)相關(guān)的資源查詢,不需要調(diào)用多個(gè)API來(lái)組合應(yīng)用程序端的數(shù)據(jù),也不需要像SQL那樣編寫(xiě)復(fù)雜的連接子句,只需要像編程一樣傳遞點(diǎn)(。)。通過(guò)引用另一個(gè)資源,ZQL的轉(zhuǎn)換器將自動(dòng)將跨資源引用轉(zhuǎn)換為相應(yīng)的SQL連接子句。
WHERE子句可以包含類似于SQL的子查詢函數(shù)的子查詢,例如:
在vmNics.l3NetworkUuid中查詢vminstance(查詢l3network.uuid
其中ipRanges.networkCidr='10 .1.0.0/24')
找出運(yùn)行在第3層網(wǎng)絡(luò)上的所有虛擬機(jī),CIRD為10.1.0.0/24。
上面的例子也可以用更簡(jiǎn)單的方式實(shí)現(xiàn):query vminstance其中vmNics.l3network.ipRanges.networkCidr='10 .1.0.0/24',只是為了演示子查詢函數(shù)
GROUP BY、ORDER BY、LIMIT、OFFSET 子句
與SQL一樣,ZQL支持GROUP BY,ORDER BY,LIMIT和OFFSET關(guān)鍵字進(jìn)行分組,排序和分頁(yè)。
GROUP BY:
通過(guò)對(duì)虛擬機(jī)的區(qū)域UUID和群集UUID進(jìn)行分組來(lái)計(jì)算每個(gè)區(qū)域中每個(gè)群集中的虛擬機(jī)數(shù)量。
VYNstance group by zoneUuid,clusterUuid
ORDER BY:
查詢所有虛擬機(jī),并使用cpuNum字段按降序?qū)λ鼈冞M(jìn)行排序。
1. ceryNum desc的查詢vminstance順序
LIMIT、OFFSET:
使用limit和offset來(lái)實(shí)現(xiàn)分頁(yè):
查詢vminstance限制100偏移10
多資源查詢
對(duì)于多個(gè)資源查詢,您可以使用以分號(hào)分隔的多個(gè)查詢查詢,例如:
查詢vminstance,其中name='my-vm';
查詢主機(jī)cpuNum> 10;
查詢區(qū)域;
可以在一次調(diào)用中返回三個(gè)資源的查詢結(jié)果。由于返回的結(jié)果是地圖的JSON結(jié)構(gòu),為了獲得相應(yīng)語(yǔ)句的查詢結(jié)果,可以使用命名為關(guān)鍵字來(lái)命名查詢,例如:
查詢vminstance,其中name='my-vm',命名為'vm';
查詢主機(jī)cpuNum> 10名為“主持人”;
查詢區(qū)域名為“zone”;
在返回的JSON映射中,可以使用vm,host和zone作為鍵來(lái)獲取相應(yīng)語(yǔ)句的查詢結(jié)果。
合并監(jiān)控查詢 (return with從句)
ZStack使用兩種數(shù)據(jù)庫(kù):關(guān)系數(shù)據(jù)庫(kù)存儲(chǔ)元數(shù)據(jù),時(shí)間序列數(shù)據(jù)庫(kù)存儲(chǔ)監(jiān)控?cái)?shù)據(jù)。由于不同的數(shù)據(jù)庫(kù)查詢方法不同,在ZQL之前,用戶需要查詢資源的監(jiān)控?cái)?shù)據(jù),首先需要通過(guò)查詢API獲取資源的元數(shù)據(jù),然后通過(guò)ZWatch查詢API獲取監(jiān)控?cái)?shù)據(jù)。例如,要查詢名為webvm虛擬機(jī)的CPU使用情況監(jiān)視數(shù)據(jù),需要執(zhí)行以下API:
QueryVmInstance fields=uuid name=webvm
GetMetricData namespace=ZStack/VM metricName=CPUUsedUtilization labels=VMUuid=QueryVmInstance返回的UUID offsetAheadOfCurrentTime=60
ZQL通過(guò)返回子句解決了這個(gè)問(wèn)題。Return with是一種插件機(jī)制,允許子系統(tǒng)通過(guò)插件將自己的查詢條件注入ZQL。 ZQL將首先執(zhí)行關(guān)系數(shù)據(jù)庫(kù)查詢,查詢滿足條件資源的原始數(shù)據(jù),然后查詢資源的主鍵(主鍵)作為輸入條件,調(diào)用實(shí)現(xiàn)return with子句的插件,最后調(diào)用插件的查詢結(jié)果返回給ZQL的調(diào)用者。
查詢虛擬機(jī)監(jiān)控?cái)?shù)據(jù)的上述要求可以通過(guò)ZQL語(yǔ)句實(shí)現(xiàn):
查詢vminstance.hostUuid,其中name='webvm'返回的uuid(zwatch {resultName='webvm-cpu',metricName='CPUAllUsedUtilization',offsetAheadOfCurrentTime=60})
回:
{
'結(jié)果': [
{
'庫(kù)存': [
{
'hostUuid':'f8271f58468b4281a212a43e530b5535',
'uuid':'05781209d24341ac84fc055ae71820ac'
}
],
'returnWith': {
'webvm-cpu': [
{
'labels': {
'VMUuid':'05781209d24341ac84fc055ae71820ac'
},
'時(shí)間': 1533280402,
'價(jià)值': 0.8
},
{
'labels': {
'VMUuid':'05781209d24341ac84fc055ae71820ac'
},
'時(shí)間': 1533280462,
'價(jià)值': 0.8
}
]
}
}
],
'成功':是真的
}
在這里,我們使用ZQL語(yǔ)句返回我們感興趣的元數(shù)據(jù)字段:uuid和hostUuid,并返回虛擬機(jī)的監(jiān)視數(shù)據(jù)。細(xì)心的讀者注意到我們?cè)赯Watch查詢字段中指定了參數(shù)resultName='webvm-cpu',并且在返回的JSON映射中監(jiān)視數(shù)據(jù)的鍵也是webvm-cpu。與命名為as關(guān)鍵字一樣,這是為了便于在執(zhí)行多個(gè)ZWatch查詢子句時(shí)檢索返回的結(jié)果。ZStack UI使用非常復(fù)雜的ZQL查詢。例如,在TOP 5頁(yè)面上,ZQL查詢最多包含13個(gè)ZWatch查詢:
上面的示例是在ZStack CLI中使用引號(hào)轉(zhuǎn)義
的執(zhí)行示例當(dāng)資源特別大時(shí),時(shí)序數(shù)據(jù)庫(kù)查詢性能可能成為多個(gè)ZWatch查詢的性能瓶頸,因此返回將以并發(fā)方式執(zhí)行插件,默認(rèn)并發(fā)性為10。例如,上面示例中的13個(gè)ZWatch查詢將在10個(gè)線程中同時(shí)執(zhí)行。用戶可以通過(guò)全局配置zql.returnWith.concurrency來(lái)更改并發(fā)性,例如
UpdateGlobalConfig category=query name=zql.returnWith.concurrency value=15
限制查詢 (restrict by從句)
ZStack的企業(yè)管理模塊包括一個(gè)可以將區(qū)域綁定到管理的功能,以便管理員只能管理該區(qū)域中的資源。這要求我們的ZQL僅向管理員返回查詢請(qǐng)求到綁定區(qū)域。資源。
對(duì)于諸如虛擬機(jī)之類的資源,其元數(shù)據(jù)本身具有標(biāo)識(shí)該區(qū)域的zoneUuid字段。然而,對(duì)于諸如eip的資源,元數(shù)據(jù)不具有指示區(qū)域?qū)傩缘娜魏巫侄?,并且區(qū)域?qū)傩杂傻?層網(wǎng)絡(luò)或綁定的虛擬機(jī)確定。例如,要查詢區(qū)域中的eip,可以使用:
查詢與虛擬機(jī)的綁定關(guān)系
查詢eip,其中vmNic.vmInstance.zoneUuid='52fdad0a2c0d4131a6c0fc6c1b7141a6'
或
由三層網(wǎng)絡(luò)決定
查詢eip,其中vip.l3Network.zoneUuid='52fdad0a2c0d4131a6c0fc6c1b7141a6'
無(wú)論哪種方式,調(diào)用者都需要知道eip和區(qū)域之間的關(guān)系,這對(duì)API的用戶提出了非常苛刻的要求。ZQL使用restrict by子句解決了這個(gè)問(wèn)題。與return with子句類似,restrict by也是一個(gè)插件框架,允許其他服務(wù)通過(guò)插件解釋restrict by子句中指定的條件,并在生成的SQL中注入其他條件。例如,上面的eip示例可以寫(xiě)成strict by子句:
查詢eip限制(zone.uuid='52fdad0a2c0d4131a6c0fc6c1b7141a6')
這里調(diào)用者不需要知道eip和zone之間的邏輯關(guān)系。 limit by插件的路徑將自動(dòng)計(jì)算兩者之間的邏輯關(guān)系并生成相應(yīng)的SQL join子句。在這里,eip可以通過(guò)三層網(wǎng)絡(luò)或通過(guò)綁定虛擬機(jī)確定與區(qū)域的關(guān)系。插件將自動(dòng)計(jì)算路徑權(quán)重并使用權(quán)重最高的路徑生成SQL語(yǔ)句。
對(duì)于eip示例,插件將選擇通過(guò)網(wǎng)絡(luò)的三個(gè)層的關(guān)系生成SQL語(yǔ)句。由于eip可能不會(huì)綁定到虛擬機(jī),但它必須位于三層網(wǎng)絡(luò)中,因此三層網(wǎng)絡(luò)的路徑具有更高的權(quán)重。
限制支持多個(gè)條件,以逗號(hào)分隔,并且多個(gè)條件之間存在AND關(guān)系。
除了被ZQL調(diào)用者使用之外,限制依賴插件也被ZStack中的其他服務(wù)廣泛使用。例如,當(dāng)普通帳戶通過(guò)插件調(diào)用ZQL時(shí),帳戶系統(tǒng)將注入與帳戶關(guān)聯(lián)的SQL語(yǔ)句,以便普通帳戶只能查詢屬于該帳戶的資源;例如,SNS服務(wù)只能通過(guò)插件注入語(yǔ)句查詢ZQL。系統(tǒng)類型的接收端。
未來(lái)
ZQL為ZStack提供了類似SQL的IaaS查詢語(yǔ)言,并且可以通過(guò)返回插件框架與其他非關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)集成。我們將在未來(lái)版本中繼續(xù)豐富其功能,目前有兩個(gè)方向:
filter by從句
雖然使用ZWatch插件返回允許我們?cè)诓樵冑Y源的元數(shù)據(jù)時(shí)查詢監(jiān)控?cái)?shù)據(jù),但我們不能將監(jiān)控?cái)?shù)據(jù)用作元數(shù)據(jù)的查詢條件。例如,無(wú)法通過(guò)ZQL實(shí)現(xiàn)查詢集群中的所有CPU使用情況。 90%的虛擬機(jī)。這將通過(guò)filter by子句在將來(lái)的版本中實(shí)現(xiàn),例如:
查詢vminstance,其中clusterUuid='33e26bd547d149fbb190436cc9aca824'過(guò)濾(zwatch {metricName''CPUAllUsedUtilization',offsetAheadOfCurrentTime=60,threshold> 90})
類似地,filter by子句將實(shí)現(xiàn)為類似于return with的插件框架,用于集成非關(guān)系數(shù)據(jù)庫(kù)的查詢條件。
智能CLI
ZQL有很多子句。每個(gè)ZStack都有大量可查詢字段。目前,ZStack CLI可以完成查詢API的可查詢字段,但ZQL無(wú)法暫時(shí)完成。在將來(lái)的版本中,我們將增強(qiáng)CLI,以便它可以提示并完成所有查詢條件。
歡迎大家下載ZStack官方網(wǎng)站上的頁(yè)面
http://www.zstack.io/product_downloads/
免費(fèi)下載安裝和試用版。