Query ZStack 揭密首个面向IaaS的查问言语 Language ZQL

  • 电脑网络维修
  • 2024-11-15

为了简化UI上班并为运维人员提供一种愈加灵敏的资源查问模式,ZStack在2.6版本中推出了***面向IaaS的查问言语 —— ZStack Query Language,简称ZQL。

背景

IaaS治理着海量的数据中心资源,如何对这些资源启动灵敏极速的查问是运维人员面临的一个难题。在以往的IaaS软件中,往往只对单个资源的某些字段提供有限的API查问支持,例如可以经过虚构机的IP字段查问,这无余够也不灵敏。运维人员在做复杂查问时往往得绕开IaaS软件间接查问其后端数据库,这既要求运维人员要了解IaaS资源的外部相关,又带来了数据库误操作的危险。

从ZStack正式颁布的***个版本ZStack0.6开局,咱们就努力在API层面提供跟数据库级别的查问性能,ZStack的每个资源都蕴含一个Query API,能够经过资源的自身字段以及资源的关联资源字段启动查问。例如

QueryVmInstance name~=web-vm state=Running

这里查问一切名字蕴含web-vm字符串,正在运转中的VM。又例如

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

EIP是虚构机的关联资源,这里查问网卡绑定了EIP为22.22.22.22的虚构机。

Query API性能弱小:

用户可以经过count参数前往满足查问条件资源数量,相似SQL的count();

经过fields参数指定要前往的字段,相似SQL的uuid,name from;

经过sortBy、sortDirection参数指定排序的字段和方向,相似SQL的order by;

经过start、limit参数成功分页查问,相似SQL的limit和offset。

Query API除了经常使用繁难外,定义也很繁难。程序员在ZStack中参与了一种新资源后,只有要在代码中定义如下class:

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

public class APIQueryVmInstanceMsg extends APIQueryMessage {

不须要写任何成功,对应资源就具有了Query API。

ZStack外部蕴含一个Query Service担任处置一切资源的Query API,将他们翻译成相应的SQL语句,在查问条件中蕴含关联资源条件时会生成对应的Join子句。

基于Query API, ZStack0.6版本就蕴含了超越万个单项查问条件,组合查问条件数为万的阶乘。极大的繁难了运维和复杂UI的设计。但Query API依然蕴含一些毛病:

查问条件之间只能是AND逻辑,不可口头OR逻辑,条件之间也不可加括号成功复杂逻辑组合

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

单个API只能查问一种资源,查问多种资源时须要调用多个API

不支持跟监控系统的查问言语整合

随着ZStack UI的场景越来越丰盛,Query API的限度使得UI端的上班越来越多,很多场景须要屡次调用Query API启动数据组合。例如在监控Top 5页面(用于检测系统中CPU、内存、磁盘、网络等资源经常使用率***5个资源的页面),须要先驳回Query API将虚构机、物理机等资源信息查问回来,再调用监控系统ZWatch的API查问对应的监控数据。

Query API在未来的ZStack版本中会不时保管并保养,其后端成功曾经从原来的Query Service交流成ZQL。

ZStack Query Language

经常使用过驰名issue治理系统JIRA的开发者都知道JIRA在启动初级搜查的时刻提供一种查问言语JQL (JIRA Query Language),能够经常使用一种相似SQL的DSL(Domain Specific Language)对JIRA中ticket的各个字段启动高效的查问。ZQL跟JQL相似,也是一种相似SQL的DSL,先来看一个例子:

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

在这个繁难例子中,可以看到很多相熟的SQL元素,例如and/or条件、括号、>=/in操作符等。ZQL可以看作SQL的一个子集外加ZStack依据自身需求启动的增强的查问言语。它的基本结构如下:

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

query关键词

一条ZQL语句通常以query关键字扫尾,queryTarget示意要查问的资源或资源字段的汇合。前面的例子中vminstance代表虚构机,例如host代表物理机、zone代表区域,一切可被查问的资源都有自己的称号。假设不宿愿前往资源的一切字段,只宿愿取得资源的一个或多个字段,成功相似SQL的uuid,name from ...的性能,可以在资源名后指定字段名,多个字段名用逗号隔离,例如:

query vminstance.uuid,name,cpuNum

该查问前往一切虚构机的UUID、称号以及CPU数量。

除了query关键字,查问也能以count和sum关键字扫尾,前者前往满足查问条件资源的总数,后者可以对资源的某个字段启动求和。例如:

vminstance where cpuNum > 8

前往系统中CPU数量超越8核的虚构机的总数。

sum vminstance.memorySize by name where cpuNum > 8

用虚构机名字对CPU核数超越8个的虚构机启动分组,对它们的memorySize字段启动求和。假设系统中有两个10CPU8G的虚构机都名为webvm,则求和后前往webvm虚构机总内存经常使用数为16G。翻译成SQL则为:

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

WHERE从句

ZQL的WHERE从句跟SQL的WHERE从句相似,支持and/or逻辑操作符、括号组合,条件的比拟符支持=,!=,>,>=,<, <=, like, not like, is null, is not null, in, not in,查问条件名为资源的字段名。跟SQL不一样的中央在于,ZQL的查问条件可以是关联资源的字段,例如:

query vminstance where

vmNics.eip.vip.ip='22.22.22.22'

留意where从句前无需写相似SQL的from xx从句,由于query vminstance曾经限定了被查问的资源

这里vip跟eip关联,eip跟vmnic关联,vmnic又跟vminstance关联,则咱们可以指定vip的IP作为查问条件。这正是ZQL的弱小之处,关于多个关联资源的查问,无需调用屡次API在运行端组合数据,也无需像SQL一样写复杂的join从句,只有要像编程一样经过点号(.)援用另一个资源即可, ZQL的翻译器会智能将跨资源援用翻译成对应的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的三层网络上运转的虚构机。

上方这个例子也可以用更繁难的方法成功: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关键字,以成功分组、排序、分页等性能。

经过虚构机的区域UUID和集群UUID分组,统计各区域中各集群中虚构机的数量。

vminstance group by zoneUuid,clusterUuid

查问一切虚构机,经常使用cpuNum字段降序排序。

1.query vminstance order by cpuNum desc

LIMIT、OFFSET:

经常使用limit和offset成功分页:

query vminstance limit 100 offset 10

多资源查问

关于多个资源的查问,可以经过多条query查问语句成功,语句之间经常使用分号分隔,例如:

query vminstance where name = 'my-vm';

query host where cpuNum > 10;

query zone;

则一次性调用即可前往三种资源的查问结果。由于前往的结果是一个map的JSON结构,为了繁难取得对应语句的查问结果,可以经常使用named as关键字对查问语句命名,例如:

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取得对应语句的查问结果。

兼并监控查问 (return with从句)

在ZStack中经常使用了两种数据库:相关数据库寄存元数据,时序数据库寄存监控数据。由于不同数据库查问模式不一样,在ZQL之前,用户要查问一个资源的监控数据,须要先经过Query API取得该资源的元数据,再经过ZWatch的查问API取得其监控数据。例如要查问一个名为webvm虚构机的CPU经常使用率监控数据,要口头如下API:

QueryVmInstance fields=uuid name=webvm

GetMetricData namespace=ZStack/VM metricName=CPUUsedUtilization labels=VMUuid=QueryVmInstance前往的UUID offsetAheadOfCurrentTime=60

ZQL经过return with子句处置这个疑问。return with是一种插件机制,它准许子系统 经过插件将自身的查问条件注入ZQL中,ZQL会先口头相关数据库查问,将满足条件资源的原数据查问进去后,再将资源的主键(primary key)作为输入条件调用成功return with子句的插件,***将插件的查问结果一并前往给ZQL的调用者。

上述查问虚构机监控数据的需求可以经过一条ZQL语句成功:

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语句中即前往了咱们感兴味的元数据字段:uuid和hostUuid,也前往了该虚构机的监控数据。认真的读者曾经留意到咱们在ZWatch查问字段中指定了参数resultName='webvm-cpu',并且在前往的JSON map中监控数据的key也是webvm-cpu。跟named as关键字一样,这是为了口头多条ZWatch查问子句时繁难检索前往结果预备的。 ZStack UI经常使用十分复杂的ZQL查问语句,例如在TOP 5页面,一条ZQL查问蕴含多达13个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中口头时的例子,经常使用\对引号转义

当资源特意多时,时序数据库查问性能或者成为多条ZWatch查问的性能瓶颈,故return with会经过并发的模式口头插件,自动并发度为10。例如上述例子中的13条ZWatch查问会在10个线程中并发口头。用户可以经过全局性能zql.returnWith.concurrency更改并发度,例如

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

限度查问 (restrict by从句)

ZStack的企业治理模块蕴含一特性能,可以对治理绑定某个区域,使得该治理员只能治理该区域内的资源,这就要求咱们的ZQL对该治理员的查问恳求只前往与其绑定区区中的资源。

关于虚构机这样的资源,其元数据自身就带zoneUuid字段用于标识所在区域。但关于eip这样的资源,其元数据并无任何字段示意区域属性,区域属性是由其所在的三层网络或绑定的虚构机确定的。例如要查问某个区域内的eip,可以经常使用:

# 经过与虚构机的绑定相关查问

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

# 经过所在三层网络确定

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

无论那种模式,都须要调用者了解知道eip跟zone之间的关联相关,这对API的经常使用者提出了十分厚道的要求。ZQL经过restrict by从句处置这个疑问。跟return with从句相似,restrict by也是个插件框架,它准许其它服务经过插件解读restrict by从句中指定的条件,向生成的SQL中注入额外条件。例如上方的eip例子经过restrict by从句可以写成:

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

这里调用者无需知道eip跟zone之间的逻辑相关,restrict by的门路插件会智能计算两者的逻辑相关,并生成对应的SQL join从句。这里eip既可以经过所在三层网络,也可以经过绑定的虚构机确定和区域的相关,插件会智能计算门路权重,经常使用权重***的门路生成SQL语句。

关于eip这个例子,插件会选取经过三层网络的相关生成SQL语句。由于eip或者没有跟虚构机绑定,但其必定处于某个三层网络,故三层网络这条门路的权重更高。

restrict by支持多个条件,经过逗号分隔,多个条件之间是AND相关。

除了给ZQL调用者经常使用外,restrict by插件在ZStack外部也被其它服务宽泛经常使用。例如账号系统会经过插件在个别账户调用ZQL的时刻注入跟账号关联的SQL语句,使得个别账号只能查问到属于该账号的资源;又例如SNS服务会经过插件注入语句让ZQL只能查问到非系统类型的接纳端。

未来

ZQL为ZStack提供了一种相似SQL的IaaS查问言语,并且能够经过return with插件框架跟其它非相关数据库系统启动查问整合。在未来的版本中咱们还会继续丰盛其性能,目前有两个方向:

filter by从句

只管return with的ZWatch插件能让咱们在查问资源元数据的同时查问其监控数据,但还不能将监控数据作为元数据的查问条件,例如不可经过一条ZQL成功查问某个集群中一切CPU经常使用率超越90%的虚构机。这在未来版本中会经过filter by从句成功,例如:

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

雷同,filter by从句会成功成相似return with的插件框架,用于整合非相关数据库的查问条件。

智能CLI

ZQL有少量的从句,每个ZStack又有少量的可查问字段,目前ZStack CLI可以对Query API的可查问字段启动补全,但ZQL还临时不可补全。未来版本中,咱们会对CLI启动在增强,使其对一切查问条件可以启动揭示和补全。

欢迎大家在ZStack官方下载页面

启动收费的下载装置和试用。

  • 关注微信

本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载联系作者并注明出处:https://duobeib.com/diannaowangluoweixiu/7085.html

猜你喜欢

热门标签

洗手盆如何疏浚梗塞 洗手盆为何梗塞 iPhone提价霸占4G市场等于原价8折 明码箱怎样设置明码锁 苏泊尔电饭锅保修多久 长城画龙G8253YN彩电输入指令画面变暗疑问检修 彩星彩电解除童锁方法大全 三星笔记本培修点上海 液晶显示器花屏培修视频 燃气热水器不热水要素 热水器不上班经常出现3种处置方法 无氟空调跟有氟空调有什么区别 norltz燃气热水器售后电话 大连站和大连北站哪个离周水子机场近 热水器显示屏亮显示温度不加热 铁猫牌保险箱高效开锁技巧 科技助力安保无忧 创维8R80 汽修 a1265和c3182是什么管 为什么电热水器不能即热 标致空调为什么不冷 神舟培修笔记本培修 dell1420内存更新 青岛自来水公司培修热线电话 包头美的洗衣机全国各市售后服务预定热线号码2024年修缮点降级 创维42k08rd更新 空调为什么运转异响 热水器为何会漏水 该如何处置 什么是可以自己处置的 重庆华帝售后电话 波轮洗衣机荡涤价格 鼎新热水器 留意了!不是水平疑问! 马桶产生了这5个现象 方便 极速 邢台空调移机电话上门服务 扬子空调缺点代码e4是什么疑问 宏基4736zG可以装置W11吗 奥克斯空调培修官方 为什么突然空调滴水很多 乐视s40air刷机包 未联络视的提高方向 官网培修 格力空调售后电话 皇明太阳能电话 看尚X55液晶电视进入工厂形式和软件更新方法 燃气热水器缺点代码

热门资讯

关注我们

微信公众号