自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

揭密首個(gè)面向IaaS的查詢語言:ZStack Query Language(ZQL)

企業(yè)動(dòng)態(tài) IaaS
為了簡(jiǎn)化UI工作并為運(yùn)維人員提供一種更加靈活的資源查詢方式,ZStack在2.6版本中推出了首個(gè)面向IaaS的查詢語言 —— ZStack Query Language,簡(jiǎn)稱ZQL。

   為了簡(jiǎn)化UI工作并為運(yùn)維人員提供一種更加靈活的資源查詢方式,ZStack在2.6版本中推出了***面向IaaS的查詢語言 —— ZStack Query Language,簡(jiǎn)稱ZQL。

背景

        IaaS管理著海量的數(shù)據(jù)中心資源,如何對(duì)這些資源進(jìn)行靈活快速的查詢是運(yùn)維人員面臨的一個(gè)難題。在以往的IaaS軟件中,往往只對(duì)單個(gè)資源的某些字段提供有限的API查詢支持,例如可以通過虛擬機(jī)的IP字段查詢,這不足夠也不靈活。運(yùn)維人員在做復(fù)雜查詢時(shí)往往得繞開IaaS軟件直接查詢其后端數(shù)據(jù)庫,這既要求運(yùn)維人員要了解IaaS資源的內(nèi)部關(guān)系,又帶來了數(shù)據(jù)庫誤操作的風(fēng)險(xiǎn)。

        從ZStack正式發(fā)布的***個(gè)版本ZStack0.6開始,我們就致力在API層面提供跟數(shù)據(jù)庫級(jí)別的查詢功能,ZStack的每個(gè)資源都包含一個(gè)Query API,能夠通過資源的自身字段以及資源的關(guān)聯(lián)資源字段進(jìn)行查詢。例如

QueryVmInstance name~=web-vm state=Running

這里查詢所有名字包含web-vm字符串,正在運(yùn)行中的VM。又例如

QueryVmInstance vmNics.eip.vip.ip='22.22.22.22'

EIP是虛擬機(jī)的關(guān)聯(lián)資源,這里查詢網(wǎng)卡綁定了EIP為22.22.22.22的虛擬機(jī)。

Query API功能強(qiáng)大:

        用戶可以通過count參數(shù)返回滿足查詢條件資源數(shù)量,類似SQL的count();

        通過fields參數(shù)指定要返回的字段,類似SQL的uuid,name from;

        通過sortBy、sortDirection參數(shù)指定排序的字段和方向,類似SQL的order by;

        通過start、limit參數(shù)實(shí)現(xiàn)分頁查詢,類似SQL的limit和offset。

        Query API除了使用方便外,定義也很簡(jiǎn)單。程序員在ZStack中增加了一種新資源后,只需要在代碼中定義如下class:

@AutoQuery(replyClass = APIQueryVmInstanceReply.class, inventoryClass = VmInstanceInventory.class)

public class APIQueryVmInstanceMsg extends APIQueryMessage {

}

不需要寫任何實(shí)現(xiàn),對(duì)應(yīng)資源就具有了Query API。

ZStack內(nèi)部包含一個(gè)Query Service負(fù)責(zé)處理所有資源的Query API,將他們翻譯成相應(yīng)的SQL語句,在查詢條件中包含關(guān)聯(lián)資源條件時(shí)會(huì)生成對(duì)應(yīng)的Join子句。

基于Query API, ZStack0.6版本就包含了超過400萬個(gè)單項(xiàng)查詢條件,組合查詢條件數(shù)為400萬的階乘。極大的方便了運(yùn)維和復(fù)雜UI的設(shè)計(jì)。但Query API仍然包含一些缺陷:

        查詢條件之間只能是AND邏輯,無法執(zhí)行OR邏輯,條件之間也無法加括號(hào)實(shí)現(xiàn)復(fù)雜邏輯組合

        不支持類似SQL中的sub query子句

        單個(gè)API只能查詢一種資源,查詢多種資源時(shí)需要調(diào)用多個(gè)API

        不支持跟監(jiān)控系統(tǒng)的查詢語言整合

        隨著ZStack UI的場(chǎng)景越來越豐富,Query API的限制使得UI端的工作越來越多,很多場(chǎng)景需要多次調(diào)用Query API進(jìn)行數(shù)據(jù)組合。例如在監(jiān)控Top 5頁面(用于檢測(cè)系統(tǒng)中CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)等資源使用率***5個(gè)資源的頁面),需要先采用Query API將虛擬機(jī)、物理機(jī)等資源信息查詢回來,再調(diào)用監(jiān)控系統(tǒng)ZWatch的API查詢對(duì)應(yīng)的監(jiān)控?cái)?shù)據(jù)。

Query API在未來的ZStack版本中會(huì)一直保留并維護(hù),其后端實(shí)現(xiàn)已經(jīng)從原來的Query Service替換成ZQL。

ZStack Query Language

        使用過著名issue管理系統(tǒng)JIRA的開發(fā)者都知道JIRA在進(jìn)行高級(jí)搜索的時(shí)候提供一種查詢語言JQL (JIRA Query Language),能夠使用一種類似SQL的DSL(Domain Specific Language)對(duì)JIRA中ticket的各個(gè)字段進(jìn)行高效的查詢。ZQL跟JQL類似,也是一種類似SQL的DSL,先來看一個(gè)例子:

query vminstance where name='webvm' or vmnics.ip='192.168.0.10' or (vmnics.eip = '172.20.100.100' (cpuNum >= 8 or clusterUuid in ('fe13b725c80e45709f0414c266a80239','73ca1ca7603d454f8fa7f3bb57097f80')))

在這個(gè)簡(jiǎn)單例子中,可以看到很多熟悉的SQL元素,例如and/or條件、括號(hào)、>=/in操作符等。ZQL可以看作SQL的一個(gè)子集外加ZStack根據(jù)自身需求進(jìn)行的增強(qiáng)的查詢語言。它的基本結(jié)構(gòu)如下:

QUERY queryTarget (WHERE condition+)? restrictBy? returnWith? groupBy? orderBy? limit? offset? filterBy? namedAs?

query關(guān)鍵詞

一條ZQL語句通常以query關(guān)鍵字開頭,queryTarget表示要查詢的資源或資源字段的集合。前面的例子中vminstance代表虛擬機(jī),例如host代表物理機(jī)、zone代表區(qū)域,所有可被查詢的資源都有自己的名稱。如果不希望返回資源的所有字段,只希望獲得資源的一個(gè)或多個(gè)字段,實(shí)現(xiàn)類似SQL的uuid,name from ...的功能,可以在資源名后指定字段名,多個(gè)字段名用逗號(hào)隔離,例如:

query vminstance.uuid,name,cpuNum

該查詢返回所有虛擬機(jī)的UUID、名稱以及CPU數(shù)量。

除了query關(guān)鍵字,查詢也能以count和sum關(guān)鍵字開頭,前者返回滿足查詢條件資源的總數(shù),后者可以對(duì)資源的某個(gè)字段進(jìn)行求和。例如:

vminstance where cpuNum > 8

返回系統(tǒng)中CPU數(shù)量超過8核的虛擬機(jī)的總數(shù)。

sum vminstance.memorySize by name where cpuNum > 8 

用虛擬機(jī)名字對(duì)CPU核數(shù)超過8個(gè)的虛擬機(jī)進(jìn)行分組,對(duì)它們的memorySize字段進(jìn)行求和。如果系統(tǒng)中有兩個(gè)10CPU8G的虛擬機(jī)都名為webvm,則求和后返回webvm虛擬機(jī)總內(nèi)存使用數(shù)為16G。翻譯成SQL則為:

sum(memorySize) from vminstance where cpuNum > 8 group by name

WHERE從句

ZQL的WHERE從句跟SQL的WHERE從句類似,支持and/or邏輯操作符、括號(hào)組合,條件的比較符支持=,!=,>,>=,<, <=, like, not like, is null, is not null, in, not in,查詢條件名為資源的字段名。跟SQL不一樣的地方在于,ZQL的查詢條件可以是關(guān)聯(lián)資源的字段,例如:

query vminstance where 

vmNics.eip.vip.ip='22.22.22.22'

注意where從句前無需寫類似SQL的from xx從句,因?yàn)閝uery vminstance已經(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)聯(lián)資源的查詢,無需調(diào)用多次API在應(yīng)用端組合數(shù)據(jù),也無需像SQL一樣寫復(fù)雜的join從句,只需要像編程一樣通過點(diǎn)號(hào)(.)引用另一個(gè)資源即可, ZQL的翻譯器會(huì)自動(dòng)將跨資源引用翻譯成對(duì)應(yīng)的SQL join從句。

WHERE從句可以包含子查詢,類似于SQL的sub query功能,例如:

query vminstance where vmNics.l3NetworkUuid in (query l3network.uuid 

where ipRanges.networkCidr='10.1.0.0/24')

這里找出所有CIRD為10.1.0.0/24的三層網(wǎng)絡(luò)上運(yùn)行的虛擬機(jī)。

上面這個(gè)例子也可以用更簡(jiǎn)單的方法實(shí)現(xiàn):query vminstance where vmNics.l3network.ipRanges.networkCidr='10.1.0.0/24',這里只是為了演示子查詢功能

GROUP BY、ORDER BY、LIMIT、OFFSET 子句

跟SQL一樣,ZQL支持GROUP BY、ORDER BY、LIMIT、OFFSET關(guān)鍵字,以實(shí)現(xiàn)分組、排序、分頁等功能。

GROUP BY:

通過虛擬機(jī)的區(qū)域UUID和集群UUID分組,統(tǒng)計(jì)各區(qū)域中各集群中虛擬機(jī)的數(shù)量。

vminstance group by zoneUuid,clusterUuid

ORDER BY:

查詢所有虛擬機(jī),使用cpuNum字段降序排序。

1.query vminstance order by cpuNum desc

LIMIT、OFFSET:

使用limit和offset實(shí)現(xiàn)分頁:

query vminstance limit 100 offset 10

多資源查詢

對(duì)于多個(gè)資源的查詢,可以通過多條query查詢語句實(shí)現(xiàn),語句之間使用分號(hào)分隔,例如:

query vminstance where name = 'my-vm';

query host where cpuNum > 10;

query zone;

則一次調(diào)用即可返回三種資源的查詢結(jié)果。由于返回的結(jié)果是一個(gè)map的JSON結(jié)構(gòu),為了方便獲得對(duì)應(yīng)語句的查詢結(jié)果,可以使用named as關(guān)鍵字對(duì)查詢語句命名,例如:

query vminstance where name = 'my-vm' named as 'vm';

query host where cpuNum > 10 named as 'host';

query zone named as 'zone';

則在返回的JSON map中,可以通過vm、host、zone作為key獲得對(duì)應(yīng)語句的查詢結(jié)果。

合并監(jiān)控查詢 (return with從句)

在ZStack中使用了兩種數(shù)據(jù)庫:關(guān)系數(shù)據(jù)庫存放元數(shù)據(jù),時(shí)序數(shù)據(jù)庫存放監(jiān)控?cái)?shù)據(jù)。由于不同數(shù)據(jù)庫查詢方式不一樣,在ZQL之前,用戶要查詢一個(gè)資源的監(jiān)控?cái)?shù)據(jù),需要先通過Query API獲得該資源的元數(shù)據(jù),再通過ZWatch的查詢API獲得其監(jiān)控?cái)?shù)據(jù)。例如要查詢一個(gè)名為webvm虛擬機(jī)的CPU使用率監(jiān)控?cái)?shù)據(jù),要執(zhí)行如下API:

QueryVmInstance fields=uuid name=webvm

GetMetricData namespace=ZStack/VM metricName=CPUUsedUtilization labels=VMUuid=QueryVmInstance返回的UUID offsetAheadOfCurrentTime=60

ZQL通過return with子句解決這個(gè)問題。return with是一種插件機(jī)制,它允許子系統(tǒng) 通過插件將自身的查詢條件注入ZQL中,ZQL會(huì)先執(zhí)行關(guān)系數(shù)據(jù)庫查詢,將滿足條件資源的原數(shù)據(jù)查詢出來后,再將資源的主鍵(primary key)作為輸入條件調(diào)用實(shí)現(xiàn)return with子句的插件,***將插件的查詢結(jié)果一并返回給ZQL的調(diào)用者。

上述查詢虛擬機(jī)監(jiān)控?cái)?shù)據(jù)的需求可以通過一條ZQL語句實(shí)現(xiàn):

query vminstance.hostUuid,uuid where name = 'webvm' return with (zwatch{resultName='webvm-cpu',metricName='CPUAllUsedUtilization',offsetAheadOfCurrentTime=60})

返回:

{

    "results": [

        {

            "inventories": [

                {

                    "hostUuid": "f8271f58468b4281a212a43e530b5535",

                    "uuid": "05781209d24341ac84fc055ae71820ac"

                }

            ],

            "returnWith": {

                "webvm-cpu": [

                    {

                        "labels": {

                            "VMUuid": "05781209d24341ac84fc055ae71820ac"

                        },

                        "time": 1533280402,

                        "value": 0.8

                    },

                    {

                        "labels": {

                            "VMUuid": "05781209d24341ac84fc055ae71820ac"

                        },

                        "time": 1533280462,

                        "value": 0.8

                    }

                ]

            }

        }

    ],

    "success": true

}

        這里我們用一條ZQL語句中即返回了我們感興趣的元數(shù)據(jù)字段:uuid和hostUuid,也返回了該虛擬機(jī)的監(jiān)控?cái)?shù)據(jù)。細(xì)心的讀者已經(jīng)注意到我們?cè)赯Watch查詢字段中指定了參數(shù)resultName='webvm-cpu',并且在返回的JSON map中監(jiān)控?cái)?shù)據(jù)的key也是webvm-cpu。跟named as關(guān)鍵字一樣,這是為了執(zhí)行多條ZWatch查詢子句時(shí)方便檢索返回結(jié)果準(zhǔn)備的。 ZStack UI使用非常復(fù)雜的ZQL查詢語句,例如在TOP 5頁面,一條ZQL查詢包含多達(dá)13個(gè)ZWatch查詢:

ZQLQuery zql="query vmInstance.uuid,name where zoneUuid='89e148fb667c404dbc5309a2e956fa28' hypervisorType='KVM' type='UserVm' state='Running' return with (zwatch{resultName='CPUAllUsedUtilization',metricName='CPUAllUsedUtilization',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='MemoryUsedInPercent',metricName='MemoryUsedInPercent',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='MemoryFreeInPercent',metricName='MemoryFreeInPercent',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='DiskAllReadOps',metricName='DiskAllReadOps',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='DiskAllWriteOps',metricName='DiskAllWriteOps',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='DiskAllReadBytes',metricName='DiskAllReadBytes',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='DiskAllWriteBytes',metricName='DiskAllWriteBytes',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='NetworkOutBytes',metricName='NetworkOutBytes',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")',functions='top(num=5)'},zwatch{resultName='NetworkInBytes',metricName='NetworkInBytes',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")',functions='top(num=5)'},zwatch{resultName='NetworkOutPackets',metricName='NetworkOutPackets',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")',functions='top(num=5)'},zwatch{resultName='NetworkInPackets',metricName='NetworkInPackets',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")',functions='top(num=5)'},zwatch{resultName='NetworkOutErrors',metricName='NetworkOutErrors',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")',functions='top(num=5)'},zwatch{resultName='NetworkInErrors',metricName='NetworkInErrors',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")',functions='top(num=5)'})"

上例是在ZStack CLI中執(zhí)行時(shí)的例子,使用\對(duì)引號(hào)轉(zhuǎn)義

當(dāng)資源特別多時(shí),時(shí)序數(shù)據(jù)庫查詢性能可能成為多條ZWatch查詢的性能瓶頸,故return with會(huì)通過并發(fā)的方式執(zhí)行插件,默認(rèn)并發(fā)度為10。例如上述例子中的13條ZWatch查詢會(huì)在10個(gè)線程中并發(fā)執(zhí)行。用戶可以通過全局配置zql.returnWith.concurrency更改并發(fā)度,例如

UpdateGlobalConfig category=query name=zql.returnWith.concurrency value=15

限制查詢 (restrict by從句)

        ZStack的企業(yè)管理模塊包含一個(gè)功能,可以對(duì)管理綁定某個(gè)區(qū)域,使得該管理員只能管理該區(qū)域內(nèi)的資源,這就要求我們的ZQL對(duì)該管理員的查詢請(qǐng)求只返回與其綁定區(qū)區(qū)中的資源。

        對(duì)于虛擬機(jī)這樣的資源,其元數(shù)據(jù)本身就帶zoneUuid字段用于標(biāo)識(shí)所在區(qū)域。但對(duì)于eip這樣的資源,其元數(shù)據(jù)并無任何字段表示區(qū)域?qū)傩?,區(qū)域?qū)傩允怯善渌诘娜龑泳W(wǎng)絡(luò)或綁定的虛擬機(jī)確定的。例如要查詢某個(gè)區(qū)域內(nèi)的eip,可以使用:

# 通過與虛擬機(jī)的綁定關(guān)系查詢

query eip where vmNic.vmInstance.zoneUuid = '52fdad0a2c0d4131a6c0fc6c1b7141a6'

# 通過所在三層網(wǎng)絡(luò)確定

query eip where vip.l3Network.zoneUuid = '52fdad0a2c0d4131a6c0fc6c1b7141a6'

        無論那種方式,都需要調(diào)用者了解知道eip跟zone之間的關(guān)聯(lián)關(guān)系,這對(duì)API的使用者提出了非??量痰囊蟆QL通過restrict by從句解決這個(gè)問題。跟return with從句類似,restrict by也是個(gè)插件框架,它允許其它服務(wù)通過插件解讀restrict by從句中指定的條件,向生成的SQL中注入額外條件。例如上面的eip例子通過restrict by從句可以寫成:

query eip restrict by (zone.uuid='52fdad0a2c0d4131a6c0fc6c1b7141a6')

        這里調(diào)用者無需知道eip跟zone之間的邏輯關(guān)系,restrict by的路徑插件會(huì)自動(dòng)計(jì)算兩者的邏輯關(guān)系,并生成對(duì)應(yīng)的SQL join從句。這里eip既可以通過所在三層網(wǎng)絡(luò),也可以通過綁定的虛擬機(jī)確定和區(qū)域的關(guān)系,插件會(huì)自動(dòng)計(jì)算路徑權(quán)重,使用權(quán)重***的路徑生成SQL語句。

        對(duì)于eip這個(gè)例子,插件會(huì)選取通過三層網(wǎng)絡(luò)的關(guān)系生成SQL語句。因?yàn)閑ip可能沒有跟虛擬機(jī)綁定,但其一定處于某個(gè)三層網(wǎng)絡(luò),故三層網(wǎng)絡(luò)這條路徑的權(quán)重更高。

        restrict by支持多個(gè)條件,通過逗號(hào)分隔,多個(gè)條件之間是AND關(guān)系。

        除了給ZQL調(diào)用者使用外,restrict by插件在ZStack內(nèi)部也被其它服務(wù)廣泛使用。例如賬號(hào)系統(tǒng)會(huì)通過插件在普通賬戶調(diào)用ZQL的時(shí)候注入跟賬號(hào)關(guān)聯(lián)的SQL語句,使得普通賬號(hào)只能查詢到屬于該賬號(hào)的資源;又例如SNS服務(wù)會(huì)通過插件注入語句讓ZQL只能查詢到非系統(tǒng)類型的接收端。

未來

        ZQL為ZStack提供了一種類似SQL的IaaS查詢語言,并且能夠通過return with插件框架跟其它非關(guān)系數(shù)據(jù)庫系統(tǒng)進(jìn)行查詢整合。在未來的版本中我們還會(huì)繼續(xù)豐富其功能,目前有兩個(gè)方向:

filter by從句

        雖然return with的ZWatch插件能讓我們?cè)诓樵冑Y源元數(shù)據(jù)的同時(shí)查詢其監(jiān)控?cái)?shù)據(jù),但還不能將監(jiān)控?cái)?shù)據(jù)作為元數(shù)據(jù)的查詢條件,例如無法通過一條ZQL實(shí)現(xiàn)查詢某個(gè)集群中所有CPU使用率超過90%的虛擬機(jī)。這在未來版本中會(huì)通過filter by從句實(shí)現(xiàn),例如:

query vminstance where clusterUuid = '33e26bd547d149fbb190436cc9aca824' filter by (zwatch{metricName='CPUAllUsedUtilization', offsetAheadOfCurrentTime=60, threshold>90})

同樣,filter by從句會(huì)實(shí)現(xiàn)成類似return with的插件框架,用于整合非關(guān)系數(shù)據(jù)庫的查詢條件。

智能CLI

        ZQL有大量的從句,每個(gè)ZStack又有大量的可查詢字段,目前ZStack CLI可以對(duì)Query API的可查詢字段進(jìn)行補(bǔ)全,但ZQL還暫時(shí)無法補(bǔ)全。未來版本中,我們會(huì)對(duì)CLI進(jìn)行在增強(qiáng),使其對(duì)所有查詢條件可以進(jìn)行提示和補(bǔ)全。

歡迎大家在ZStack官網(wǎng)下載頁面

http://www.zstack.io/product_downloads/

進(jìn)行免費(fèi)的下載安裝和試用。

責(zé)任編輯:張燕妮 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2018-08-15 09:55:35

IaaS查詢ZStack

2018-08-13 16:15:41

2009-06-18 09:47:50

2015-08-06 11:10:46

開源IaaS軟件ZStack本地存儲(chǔ)

2020-06-02 18:03:25

ZStack超融合一體機(jī)裸金屬

2018-07-02 17:53:16

ZStack

2009-09-14 14:20:36

LINQ ORM

2010-02-23 10:58:43

EucalyptusIaaS云服務(wù)

2010-03-01 17:47:53

Python語言

2017-05-17 10:46:33

華為公有云IaaS

2014-07-29 10:49:23

Swift

2024-04-02 07:32:58

Go語言接口

2019-12-13 10:14:43

開發(fā)技能代碼

2012-06-25 09:20:05

IaaS云計(jì)算

2010-01-22 10:26:40

C++語言

2010-08-24 16:00:43

C語言

2021-02-04 12:40:55

勒索軟件VovalexD語言

2011-06-02 09:47:11

C語言重構(gòu)

2012-03-30 14:15:50

GoogleGo

2015-07-13 10:19:35

運(yùn)維ZStackIaaS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)