TSQL: make monitoring easier and more efficient analysis

1 Introduction

Ali timing spatio-temporal database TSDB latest TSQL, supports standard SQL syntax and functions. Users are familiar with SQL, query not only easier to use, users can also take advantage of the powerful SQL to achieve a more sophisticated computational analysis.

2. Why do you need to do with the timing of the query SQL?

2.1 SQL has an extensive user base

SQL as a born in the 1970s programming language has existed for decades. This is a relatively more "old" programming language, but a language has a broad user base.
In tracking the major programming languages prevalence TIOBE index [1] in, SQL in April 2019 ranked eighth. If the rankings in between two SQL 11-20 "Brothers" PL / SQL, Transact-SQL also incorporates come in, SQL popularity should be higher.

image

According to the survey stackoverflow website [2], SQL in most popular programming language standings ranked No. 4.

image

Whether or stackoverflow TIOBE index of list of programming languages, SQL reflect a broad user base from one side. As a query language, SQL is (directly or indirectly) the main way users interact with the system and database. Has supported a wide range of user-based query language, database system for the promotion, it is very important.

2.2 user learning costs

最近几年出现的几个主要面向时序场景的数据库,除了TimescaleDB是在Postgres基础上所以支持PG生态包括SQL语言支持,其他几个比如InfluxDB, OpenTSDB, Prometheus都有各自不同的查询语言和接口:InfluxDB有InfluxQL,OpenTSDB有自己的Restful API, 而Prometheus有PromQL。每一个系统都可以声称自己的语言是独一无二的,更适合时序查询这样的场景;但不可否认的事实是用户需要去花时间去学习一种新的语言,并且如果这个语言为了功能完善,还在不断演进中,这样的学习成本对用户来说,尤其显得高了。
举个例子,InfluxDB的InfluxQL并不支持Join,Subqueries, 以及SQL中很常见的UDF等功能,这意味着用户并不能在不同数据之间进行关联分析计算,也不能在系统函数基础上进行扩展开发。InfluxDB设计者在听到社区的意见后,做了一个很有“创意”的事情:在新版本里支持Join,UDF等功能,但并不是让InfluxQL变得更加接近于SQL,而是在一个全新的Flux(一个新的functional scripting language)里支持 [3]。用户想要做InfluxQL不能做的事情,那就再来学习一个新语言吧。
一个很有意思的事情,10多年前开始出现的NoSQL系统,比如MapReduce/Hadoop, BigTable,Casandra,HBase等,一开始也是以各自不同的查询语言出现的。在经历了多年用户推广之后,NoSQL开始拥抱SQL,变成了NotOnlySQL或者NewSQL。时序数据库这样一个新兴的数据库领域,也有可能重复这样的历史。原因很简单,用户学习一个新语言的成本越高,越会阻碍一个系统被推广到大众接受的程度。

2.3 BI工具生态支持

时序数据库提供SQL的查询支持,一个很重要的原因是将时序数据库的应用场景扩展到商业分析(BI/Business Analysis),商业决策这样高附加值领域。
当前几个主要的时序数据库,包括InfluxDB, OpenTSDB和Prometheus,主要侧重于基础性能监控这样的场景,利用Grafana这样的可视化工具,实现监控报警这一类基本功能。另一方面,监控报警还没有充分利用挖掘时序数据的商业价值。进一步的功能,需要充分利用现有SQL生态系统中的商业分析工具,比如Tableau, Qlik,Oracle BI, IBM Cognos等。这些BI工具,往往是以SQL的方式同后端数据库交互。从这个角度来说,时序数据库的SQL支持对于对接BI生态系统中的各种工具,尤为重要。

2.4 TSQL面向的用户群

在阿里时序数据库TSDB支持的兼容OpenTSDB查询协议之上推出的TSQL查询引擎,主要是面向以下两类用户:

  • 时序数据库TSDB的新应用开发者 :这类用户往往以前使用关系数据库,因为关系数据库本身处理时序数据的性能和可扩展性的局限,而转而使用TSDB。这些新应用开发者,希望TSDB在提供比关系数据库更好的时序性能和扩展性的同时,能够用他们以前熟悉的查询语言进行应用开发,而不是去学习一个新的查询语言。
  • 数据分析师:这类用户并不开发应用,他们的工作是利用已有的商业分析工具,对时序数据进行进一步的查询分析。他们本身并不直接使用SQL, 但所使用的工具以SQL作为和时序数据库TSDB交互的查询语言。

3. 现有时序数据库系统SQL查询能力比较

这里简单对比时序数据库系统中提供SQL查询,或SQL-like查询能力的InfluxDB, TimescaleDB, 阿里云TSDB。

image

4. TSQL系统架构

image

上图是TSQL的总体架构以及和TSDB引擎和存储之间的协调工作关系。简单来讲,TSQL是一个典型的MPP的SQL分析引擎,通过Connector同TSDB引擎和存储进行数据交换。Connector支持MetaAPI和DataAPI。

TSQL是在两个Apache开源项目基础上演进开发的:

  • Apache Calcite作为SQL的解析器和计划生成和优化器。
  • Apache Drill提供分布式的SQL执行层。

Apache Calcite作为一个扩展性好,支持标准SQL语法和语义的SQL计划生成器,已经被很多数据处理相关的开源项目使用[6],包括大数据ETL的Apache Hive, HBase上的SQL解决方案Apache Phoenix, 也有流数据处理框架Apache Fink (阿里的Blink)和Apache Beam等。 TSQL使用Calcite作为SQL计划生成器,可以在兼容标准SQL方面,充分利用开源社区已有的成果。

4.1 时序数据Schema管理

InfluxDB, OpenTSDB和Prometheus都采用的是一种Schema-on-write的方式,也就是用户并不需要明确定义metric的schema, 而是将schema的信息隐藏在数据中,在数据写入的时候,同时管理着schema。这样做的好处是更高的灵活性:

  • 在写入数据的时候,用户不需要事先必须用Create Table DDL来创建table;
  • 在时序数据tag set出现变化的时候,用户不需要事先用Alter Table来修改table的schema。
    TimeScaleDB从PG上扩展而来,所以是采用的是严格的Schema的管理方式。在使用灵活性方面,不如上面其他3个时序数据库。

Calcite作为一个SQL计划生成器,很适合时序数据库这样的比较松散的Schema管理方式。 Calcite的Schema Adapter,可以支持

  1. 动态的Schema 发现,
  2. 任意一个数据集,只要实现Schema管理中的接口API, 就可以在计划解析生成阶段被当成一个Table来处理。

TSQL在Calcite的Schema Adapter基础上,利用TSDB引擎中新增加的MetaAPI,来完成SQL计划解析和生成。这免去了用户必须事先在一个集中式的catalog中预先定义Table DDL等繁琐工作,给用户带来了很多的灵活性。

4.2 时序数据查询执行

TSQL的执行层,利用了Apache Drill的runtime execution。Drill的runtime execution,具备以下特点

  • 利用off-heap内存作为计算内存,减少Java heap内存GC所带来的延迟问题
  • 基于Columnar格式的ValueVector (Apache Arrow的前身),提升查询执行效率
  • 动态代码生成和编译
    UDF支持

5. TSQL时序查询功能

我们以一个基础性能监控场景来举例说明TSQL能完成的时序查询功能。利用一个时序数据库业界公开的时序性能Benchmark[5] 生成的模拟数据,按照DevOps这样的场景,产生了cpu相关的10不同的metric。每个metric对应了机房(datecenter),主机(hostname),rack等标签下所采集的服务器cpu相关的指标数据。

5.1 元数据查询

可以用下面的方式查询TSDB中所有的metric/table

SHOW TABLES FROM tsdb

如果我们希望列出所有以cpu为前缀的metric/table,可以在上面的查询基础之上添加附带过滤条件.

show TABLES from tsdb where TABLE_NAME like 'cpu%'

下图给出了命令的部分输出:
image

在获得metric/table 名字后,我们可以进一步用SQL中的'DESCRIBE'命令来查询这个metric/table的schema信息

describe tsdb.`cpu.usage_user`

下图显示了上面的'describe'命令的部分结果:

image

5.2 时序数据简单查询

用下面的SQL查询可以获得指定时间段内的'cpu.usage_user'的指标值,时间戳,以及对应的标签值。

select * 
from tsdb.`cpu.usage_user`
where `timestamp`  between '2019-05-01 16:00:00' and '2019-05-01 18:00:00' 

这里, 将被转换成 metric/table下所有的列,包括指标值,时间戳,所有的标签列。可以以具体的列名的一个列表来代替
作为对比,如果把上面的查询转化成OpenTSDB协议来查询,相对应的查询如下:

{
  "start": "1556726400000",
  "end": "1556733600000",
  "queries": [
    {
      "aggregator": "none",
      "metric": "cpu.usage_user",
      "rate": null,
      "downsample": null,
      "filters": []
    }
  ]
}

可以在时间戳的过滤条件基础上,增加指标列上的条件。下面的查询,列出指定时间段内,3台主机上的指标值,并且使用limit, 把查询结果限制在100行。

select * 
from tsdb.`cpu.usage_user`
where `timestamp`  between '2019-05-01 16:00:00' and '2019-05-01 18:00:00'   and 
        hostname in ('host_1', 'host_5', 'host_10')
limit 100

可以在查询中使用标准SQL中丰富的数值计算函数,字符串函数或时间戳函数。下面的SQL,我们分别使用了数值运算函数sqrt, 时间戳函数extract 和字符串lower。

5.3 时序降精度,聚合运算

如果我们要计算两小时之内,每台主机上每5分钟的指标cpu.usage_user的最大值,最小值,以及数据采样点的个数。这样的查询,代表了在时间维度上的降精度,并且在标签hostname上进行的聚合运算。用TSQL来表示这样的查询:

select
  hostname,
  tumble(`timestamp`, interval '5' minute) ts,
  max(`value`) maxV,
  min(`value`) minV,
  count(`value`) cnt
 from tsdb.`cpu.usage_user`
 where `timestamp` between 1556726400000 and 1556733600000   and 
      hostname in ('host_8','host_5','host_6')
group by hostname, ts

如果用OpenTSDB的协议来查询:

{
  "start": "1556726400000",
  "end": "1556733600000",
  "queries": [
    {
      "aggregator": "max",
      "metric": "cpu.usage_user",
      "downsample": "5m-max",
      "tags":{
        "hostname":"host_8|host_5|host_6"
      }
    },
    {
      "aggregator": "min",
      "metric": "cpu.usage_user",
      "downsample": "5m-min",
      "tags":{
        "hostname":"host_8|host_5|host_6"
      }
    },
    {
      "aggregator": "sum",
      "metric": "cpu.usage_user",
      "rate": null,
      "downsample": "5m-count",
      "tags":{
        "hostname":"host_8|host_5|host_6"
      }
    }
  ]
}

可以看到,相比较原来Restful API的查询,TSQL能够用更简洁的方式来表示相同的查询语义;并且,如果用户本来就熟悉SQL的使用方法,节省用户去学习Restfule API里JSON各个字段的含义。从降低用户学习成本,增加易用性这个角度,TSQL带来了较明显的价值。
TSQL不仅仅带来查询简洁,用户易用的优点,并且,更重要的是,用TSQL能够表达Restful API里不能直接表达的查询语义。在TSDB引入TSQL之前,如果用户需要进行这样的查询计算,则用户必须通过自己的应用程序,在Restful API获得数据后,再进行后计算,来满足业务需要。在自己的应用程序中进行后计算,往往需要付出很大的应用开发代价。

5.4 聚合后计算,过滤,排序

下面的例子,计算2个小时内,3台机器上每5分钟内,cpu.usage_user指标值的最大值和最小值的差异超过10.0的时段和hostname, 并按照差异值从大到小排序:
在上面的例子中个,在获得最大值和最小值后,进一步计算两者的差异值,并根据差异值进行过滤和排序。这样的聚合后计算处理,无法用OpenTSDB的查询协议表示;用户如果要表达这样的语义,就必须在应用程序中计算。

select
  hostname,
  tumble(`timestamp`, interval '5' minute) ts,
  max(`value`) - min(`value`) as diffV
 from tsdb.`cpu.usage_user`
 where `timestamp`  between '2019-05-01 16:00:00' and '2019-05-01 18:00:00'   and 
        hostname in ('host_1', 'host_5', 'host_10')
group by hostname, ts
HAVING  diffV > 10.0
order by diffV DESC

5.5 任意复杂的条件表达式

TSDB的Restful API对于只提供有限的几种filter, 而并不支持任意filter通过AND/OR的组合。比如下面的例子,是一个TSQL业务中使用的查询。其中WHERE条件部分是并不能用Restful API来表示的,因为Restful下的filters是只有AND, 而OR只有在相同tag上通过'value1|value2|vale3'这样的形式来表达。

where
    (
      (obj_id='ems30_NA62_183249003' and obj_type='ems30_NA62_20204' and room='ems30_NA62_C-T01.NA62' and building='ems30_NA62_C') or
      (obj_id='ems30_NA62_183249746' and obj_type='ems30_NA62_20204' and room='ems30_NA62_C-T01.NA62' and building='ems30_NA62_C') or
      (obj_id='ems30_NA62_183246962' and obj_type='ems30_NA62_20204' and room='ems30_NA62_C-T01.NA62' and building='ems30_NA62_C') or
      (obj_id='ems30_NA62_183248143' and obj_type='ems30_NA62_20204' and room='ems30_NA62_C-T01.NA62' and building='ems30_NA62_C') or
      (obj_id='ems30_NA62_183249191' and obj_type='ems30_NA62_20204' and room='ems30_NA62_C-T01.NA62' and building='ems30_NA62_C') or
      (obj_id='ems30_NA62_183249964' and obj_type='ems30_NA62_20204' and room='ems30_NA62_C-T01.NA62' and building='ems30_NA62_C') or
      (obj_id='ems30_NA62_183247148' and obj_type='ems30_NA62_20204' and room='ems30_NA62_C-T01.NA62' and building='ems30_NA62_C')
    ) and `timestamp` between '2019-04-25 18:20:21' and '2019-04-25 18:20:31'
    ...
    

支持任意组合的AND/OR的条件表达式,对于应用开发是很有意义的。在集团基础监控业务(raptor-pro)中,一个突出的亮点是“定制化监控报警”:允许业务方的用户来定制查询条件,并且查询条件可以是任意的AND/OR组合。TSQL为"定制化监控报警"的功能实现,提供了有力的技术保障。

5.6 多个metric之间join

这个查询,把cpu.usage_system和cpu.usage_idle在hostname和timestamp上做等值join, 然后计算每5分钟两个度量值之和的sum。

select 
     t1.hostname, 
     tumble(t1.`timestamp`,  interval '5' minute ) ts, 
     sum(t1.`value` + t2.`value`) as sumV
from tsdb.`cpu.usage_system` t1, tsdb.`cpu.usage_idle` t2
where t1.`timestamp` >='2019-05-01' and t1.`timestamp` <= '2019-05-01 01:00:00' 
 and t1.hostname = t2.hostname
 and t1.`timestamp`= t2.`timestamp`
group by t1.hostname, ts

上面的查询,如果我们采用TSDB的多值模型,把cpu.usage_system和cpu.usage_idle处理成一个metric的不同的field, 则不需要join就可以完成。但如果我们需要在分组聚合后的结果上再做join, 多值模型也无法解决问题。

5.7 分组聚合后join计算

The following query, respectively cpu.usage_system cpu.usage_idel calculated as 5 minutes and aggregation function SUM (), and then through the join, alignment, calculates the ratio of the corresponding. And, Where each sub-query conditions, including conditions in addition to the tag and timestamp, further comprising a filter condition value.
Queries like this, is not directly in the TSDB of RestAPI achieved; users can only be achieved in your own applications, increasing the cost of application development.

select f0.hostname, f0.ts, f0.sumV / f1.sumV as resultValue
from (
  select hostname,
  tumble(`timestamp`,  interval '5' minute) ts, 
     sum(`value`) as sumV
  from tsdb.`cpu.usage_system`
  where
    hostname in ('host_0', 'host_5', 'host_10') and
    `timestamp` between '2019-05-01 00:00:00' and '2019-05-01 01:00:00' and `value`<=50
  group by hostname, ts
  ) as f1
join (
  select hostname,
  tumble(`timestamp`,  interval '5' minute ) ts, 
     sum(`value`) as sumV
  from tsdb.`cpu.usage_idle`
  where
    hostname in ('host_0', 'host_5', 'host_10') and
    `timestamp` between '2019-05-01 00:00:00' and '2019-05-01 01:00:00' and `value`<=30
  group by hostname, ts
  ) as f0
on f1.hostname = f0.hostname and f1.ts = f0.ts

5.8 UDF extension

UDF is used to extend the functionality, timing database for database-specific focus such areas, it is very necessary because often SQL functions defined in the standard, and can not fully meet the needs. TSQL have a perfect UDF system, in accordance with the agreement as long as the user interface, Java semantics can be achieved with the expansion. For example, we introduce a function of the time stamp into the window do not overlap in TSQL tumble, its implementation is not completed by the following 15 lines of code.
Users can use Java to achieve different scalar UDF or aggregate UDF, and the jar compiled TSQL added to the system library directory, you can expand on their own TSQL query the computing power.

@FunctionTemplate(name = "tumble", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
    public static class Tumble implements DrillSimpleFunc {
        @Param TimeStampHolder timeStamp;
        @Param IntervalDayHolder interval;
        @Output TimeStampHolder out;

        @Override
        public void setup() {
        }

        @Override
        public void eval() {
            long intervalMs = interval.days * org.apache.drill.exec.vector.DateUtilities.daysToStandardMillis + interval.milliseconds;
            out.value = timeStamp.value - timeStamp.value % intervalMs;
        }
    }

6 TSQL visual query

Aliyun TSDB has provided visual interactive development TSQL function, can easily be TSQL test and development through a web page, as shown in FIG Demo,. Click here to see Ali timing cloud database

image

Guess you like

Origin yq.aliyun.com/articles/711655