From 7e5fa0ddeb70827c6450e8bfdfa4dc913a54a660 Mon Sep 17 00:00:00 2001 From: jiajingbin Date: Sun, 7 Aug 2022 23:45:23 +0800 Subject: [PATCH 01/14] doc: add 06-stream.md --- docs/zh/07-develop/06-stream.md | 263 ++++++++++++++++++++++---------- 1 file changed, 179 insertions(+), 84 deletions(-) diff --git a/docs/zh/07-develop/06-stream.md b/docs/zh/07-develop/06-stream.md index b2223d15e3..ca92b9098e 100644 --- a/docs/zh/07-develop/06-stream.md +++ b/docs/zh/07-develop/06-stream.md @@ -1,84 +1,179 @@ ---- -sidebar_label: 连续查询 -description: "连续查询是一个按照预设频率自动执行的查询功能,提供按照时间窗口的聚合查询能力,是一种简化的时间驱动流式计算。" -title: "连续查询(Continuous Query)" ---- - -连续查询是 TDengine 定期自动执行的查询,采用滑动窗口的方式进行计算,是一种简化的时间驱动的流式计算。针对库中的表或超级表,TDengine 可提供定期自动执行的连续查询,用户可让 TDengine 推送查询的结果,也可以将结果再写回到 TDengine 中。每次执行的查询是一个时间窗口,时间窗口随着时间流动向前滑动。在定义连续查询的时候需要指定时间窗口(time window, 参数 interval)大小和每次前向增量时间(forward sliding times, 参数 sliding)。 - -TDengine 的连续查询采用时间驱动模式,可以直接使用 TAOS SQL 进行定义,不需要额外的操作。使用连续查询,可以方便快捷地按照时间窗口生成结果,从而对原始采集数据进行降采样(down sampling)。用户通过 TAOS SQL 定义连续查询以后,TDengine 自动在最后的一个完整的时间周期末端拉起查询,并将计算获得的结果推送给用户或者写回 TDengine。 - -TDengine 提供的连续查询与普通流计算中的时间窗口计算具有以下区别: - -- 不同于流计算的实时反馈计算结果,连续查询只在时间窗口关闭以后才开始计算。例如时间周期是 1 天,那么当天的结果只会在 23:59:59 以后才会生成。 -- 如果有历史记录写入到已经计算完成的时间区间,连续查询并不会重新进行计算,也不会重新将结果推送给用户。对于写回 TDengine 的模式,也不会更新已经存在的计算结果。 -- 使用连续查询推送结果的模式,服务端并不缓存客户端计算状态,也不提供 Exactly-Once 的语义保证。如果用户的应用端崩溃,再次拉起的连续查询将只会从再次拉起的时间开始重新计算最近的一个完整的时间窗口。如果使用写回模式,TDengine 可确保数据写回的有效性和连续性。 - -## 连续查询语法 - -```sql -[CREATE TABLE AS] SELECT select_expr [, select_expr ...] - FROM {tb_name_list} - [WHERE where_condition] - [INTERVAL(interval_val [, interval_offset]) [SLIDING sliding_val]] - -``` - -INTERVAL: 连续查询作用的时间窗口 - -SLIDING: 连续查询的时间窗口向前滑动的时间间隔 - -## 使用连续查询 - -下面以智能电表场景为例介绍连续查询的具体使用方法。假设我们通过下列 SQL 语句创建了超级表和子表: - -```sql -create table meters (ts timestamp, current float, voltage int, phase float) tags (location binary(64), groupId int); -create table D1001 using meters tags ("California.SanFrancisco", 2); -create table D1002 using meters tags ("California.LosAngeles", 2); -... -``` - -可以通过下面这条 SQL 语句以一分钟为时间窗口、30 秒为前向增量统计这些电表的平均电压。 - -```sql -select avg(voltage) from meters interval(1m) sliding(30s); -``` - -每次执行这条语句,都会重新计算所有数据。 如果需要每隔 30 秒执行一次来增量计算最近一分钟的数据,可以把上面的语句改进成下面的样子,每次使用不同的 `startTime` 并定期执行: - -```sql -select avg(voltage) from meters where ts > {startTime} interval(1m) sliding(30s); -``` - -这样做没有问题,但 TDengine 提供了更简单的方法,只要在最初的查询语句前面加上 `create table {tableName} as` 就可以了,例如: - -```sql -create table avg_vol as select avg(voltage) from meters interval(1m) sliding(30s); -``` - -会自动创建一个名为 `avg_vol` 的新表,然后每隔 30 秒,TDengine 会增量执行 `as` 后面的 SQL 语句,并将查询结果写入这个表中,用户程序后续只要从 `avg_vol` 中查询数据即可。例如: - -```sql -taos> select * from avg_vol; - ts | avg_voltage_ | -=================================================== - 2020-07-29 13:37:30.000 | 222.0000000 | - 2020-07-29 13:38:00.000 | 221.3500000 | - 2020-07-29 13:38:30.000 | 220.1700000 | - 2020-07-29 13:39:00.000 | 223.0800000 | -``` - -需要注意,查询时间窗口的最小值是 10 毫秒,没有时间窗口范围的上限。 - -此外,TDengine 还支持用户指定连续查询的起止时间。如果不输入开始时间,连续查询将从第一条原始数据所在的时间窗口开始;如果没有输入结束时间,连续查询将永久运行;如果用户指定了结束时间,连续查询在系统时间达到指定的时间以后停止运行。比如使用下面的 SQL 创建的连续查询将运行一小时,之后会自动停止。 - -```sql -create table avg_vol as select avg(voltage) from meters where ts > now and ts <= now + 1h interval(1m) sliding(30s); -``` - -需要说明的是,上面例子中的 `now` 是指创建连续查询的时间,而不是查询执行的时间,否则,查询就无法自动停止了。另外,为了尽量避免原始数据延迟写入导致的问题,TDengine 中连续查询的计算有一定的延迟。也就是说,一个时间窗口过去后,TDengine 并不会立即计算这个窗口的数据,所以要稍等一会(一般不会超过 1 分钟)才能查到计算结果。 - -## 管理连续查询 - -用户可在控制台中通过 `show streams` 命令来查看系统中全部运行的连续查询,并可以通过 `kill stream` 命令杀掉对应的连续查询。后续版本会提供更细粒度和便捷的连续查询管理命令。 +--- +sidebar_label: 流式计算 +description: "TDengine 流式计算将数据的写入、预处理、复杂分析、实时计算、报警触发等功能融为一体,是一个能够降低用户部署成本、存储成本和运维成本的计算引擎。" +title: 流式计算 +--- +在时序数据的处理中,经常要对原始数据进行清洗、预处理,再使用时序数据库进行长久的储存。用户通常需要在时序数据库之外再搭建 Kafka、Flink、Spark 等流计算处理引擎,增加了用户的开发成本和维护成本。 +使用 TDengine 3.0 的流式计算引擎能够最大限度的减少对这些额外中间件的依赖,真正将数据的写入、预处理、长期存储、复杂分析、实时计算、实时报警触发等功能融为一体,并且,所有这些任务只需要使用 SQL 完成,极大降低了用户的学习成本、使用成本。 + +## 创建流 + +```sql +CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name AS subquery +stream_options: { + TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time] + WATERMARK time +} + +其中 subquery 是 select 普通查询语法的子集: + +subquery: SELECT [DISTINCT] select_list + from_clause + [WHERE condition] + [PARTITION BY tag_list] + [window_clause] + [group_by_clause] + +不支持 order_by,limit,slimit,fill 语句 +``` +### 触发模式 + +在创建流时,可以通过 TRIGGER 指令指定流式计算的触发模式。 + +对于非窗口计算,流式计算的触发是实时的; + +对于窗口计算,目前提供3种触发模式: + +1. AT_ONCE:写入立即触发 + +2. WINDOW_CLOSE:窗口关闭时触发(窗口关闭由事件时间决定,可配合 WATERMARK 使用,详见《流式计算的乱序数据容忍策略》) + +3. MAX_DELAY time:若窗口关闭,则触发计算。若窗口未关闭,且未关闭时长超过 MAX_DELAY 指定的时间,则触发计算。 + +由于窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,则事件时间无法更新,可能导致无法得到最新的计算结果。 + +因此,流式计算提供了以事件时间结合处理时间计算的 MAX_DELAY 触发模式。 + +MAX_DELAY 模式在窗口关闭时会立即触发计算。此外,当数据写入后,计算触发的时间超过 MAX_DELAY 指定的时间,则立即触发计算。 + +### 乱序数据容忍策略 + +在创建流时,可以在 stream_option 中指定 WATERMARK + +流式计算通过 WATERMARK 来度量对乱序数据的容忍程度,WATERMARK 默认为 0。 + + T = 最新事件时间 - WATERMARK + +每批到来的数据都会以上述公式更新窗口关闭时间,并将窗口结束时间 < T 的所有打开的窗口关闭,若触发模式为 WINDOW_CLOSE 或 MAX_DELAY,则推送窗口聚合结果。 + +### 流式计算的过期数据处理策略 + +对于已关闭的窗口,再次落入该窗口中的数据被标记为过期数据,对于过期数据,流式计算提供两种处理方式: + +1. 直接丢弃:这是常见流式计算引擎提供的默认(甚至是唯一)计算模式 + +2. 重新计算:从 TSDB 中重新查找对应窗口的所有数据并重新计算得到最新结果 + +无论在哪种模式下,watermark 都应该被妥善设置,来得到正确结果(直接丢弃模式)或避免频繁触发重算带来的性能开销(重新计算模式)。 + +### 流式计算与窗口切分查询 + +窗口子句语法如下: + +```sql +window_clause: { + SESSION(ts_col, tol_val) + | STATE_WINDOW(col) + | INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] +} +``` + +其中,SESSION 是会话窗口,tol_val 是时间间隔的最大范围。在 tol_val 时间间隔范围内的数据都属于同一个窗口,如果连续的两条数据的时间超过 tol_val,则自动开启下一个窗口。 + + +## 流式计算的展示 + +```sql +SHOW STREAMS; +``` + +## 流式计算的删除 + +```sql +DROP STREAM [IF NOT EXISTS] stream_name; +``` + +## 使用案例 + +通过以下案例,进一步了解 TDengine 流计算的使用 + +### 创建 DB 和原始数据表 + +首先准备数据,完成建库、建一张超级表和多张子表操作: + +```sql +drop database if exists stream_db; +create database stream_db; + +create table stream_db.stb (ts timestamp, c1 int, c2 float, c3 varchar(16)) tags(t1 int, t3 varchar(16)); +create table stream_db.ctb0 using stream_db.stb tags(0, "subtable0"); +create table stream_db.ctb1 using stream_db.stb tags(1, "subtable1"); +create table stream_db.ctb2 using stream_db.stb tags(2, "subtable2"); +create table stream_db.ctb3 using stream_db.stb tags(3, "subtable3"); +``` + +### 创建流 +case1. 创建流实现数据过滤 + +```sql +create stream stream1 into stream_db.stream1_output_stb as select * from stream_db.stb where c1 > 0 and c2 != 10 and c3 is not Null; +``` + +case2. 创建流实现标量函数的数据转换 + +```sql +create stream stream2 into stream_db.stream2_output_stb as select ts, abs(c2), char_length(c3), cast(c1 as binary(16)),timezone() from stream_db.stb partition by tbname; +``` + +case3. 创建流实现数据降采样 + +```sql +create stream stream3 into stream_db.stream3_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); +``` + +case4. 通过 trigger window_close 控制流的触发频率 + +```sql +create stream stream4 trigger window_close into stream_db.stream4_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); +``` + +case4. 通过 trigger max_delay 控制流的触发频率 + +```sql +create stream stream5 trigger max_delay 3s into stream_db.stream5_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); +``` + +case6. 通过 watermark 实现乱序数据容忍 + +```sql +create stream stream6 trigger window_close watermark 15s into stream_db.stream6_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); +``` + +case7. 通过 ignore expired 实现乱序数据丢弃 + +```sql +create stream stream7 trigger at_once ignore expired into stream_db.stream7_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); +``` + +### 写入数据 +```sql +insert into stream_db.ctb0 values("2022-08-13 00:00:00", 0, 0, 'a0'); +insert into stream_db.ctb0 values("2022-08-13 00:00:01", 1, 1, 'a1'); +insert into stream_db.ctb0 values("2022-08-13 00:00:07", 7, 7, 'a7'); +insert into stream_db.ctb0 values("2022-08-13 00:00:10", 10, 10, 'a10'); +insert into stream_db.ctb0 values("2022-08-13 00:00:13", 13, 13, 'a13'); +insert into stream_db.ctb0 values("2022-08-13 00:00:20", 20, 20, 'a20'); +insert into stream_db.ctb0 values("2022-08-13 00:00:21", 21, 21, 'a21'); +insert into stream_db.ctb0 values("2022-08-13 00:00:25", 25, 25, 'a25'); +insert into stream_db.ctb0 values("2022-08-13 00:00:26", 26, 26, 'a26'); +``` +### 查询以观查结果 +```sql +select * from stream_db.stream1_output_stb; +select * from stream_db.stream2_output_stb; +select * from stream_db.stream3_output_stb; +select * from stream_db.stream4_output_stb; +select * from stream_db.stream5_output_stb; +select * from stream_db.stream6_output_stb; +select * from stream_db.stream7_output_stb; +``` \ No newline at end of file From 922593bc8f2813425727f78da5201e0c1133a04e Mon Sep 17 00:00:00 2001 From: jiajingbin Date: Mon, 8 Aug 2022 16:12:33 +0800 Subject: [PATCH 02/14] docs: Add 06-stream.md for stream-computing --- docs/zh/07-develop/06-stream.md | 120 ++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 53 deletions(-) diff --git a/docs/zh/07-develop/06-stream.md b/docs/zh/07-develop/06-stream.md index ca92b9098e..194ed4646c 100644 --- a/docs/zh/07-develop/06-stream.md +++ b/docs/zh/07-develop/06-stream.md @@ -1,8 +1,9 @@ --- sidebar_label: 流式计算 description: "TDengine 流式计算将数据的写入、预处理、复杂分析、实时计算、报警触发等功能融为一体,是一个能够降低用户部署成本、存储成本和运维成本的计算引擎。" -title: 流式计算 +title: 流式计算 --- + 在时序数据的处理中,经常要对原始数据进行清洗、预处理,再使用时序数据库进行长久的储存。用户通常需要在时序数据库之外再搭建 Kafka、Flink、Spark 等流计算处理引擎,增加了用户的开发成本和维护成本。 使用 TDengine 3.0 的流式计算引擎能够最大限度的减少对这些额外中间件的依赖,真正将数据的写入、预处理、长期存储、复杂分析、实时计算、实时报警触发等功能融为一体,并且,所有这些任务只需要使用 SQL 完成,极大降低了用户的学习成本、使用成本。 @@ -13,58 +14,20 @@ CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name AS subq stream_options: { TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time] WATERMARK time + IGNORE EXPIRED } - + 其中 subquery 是 select 普通查询语法的子集: - + subquery: SELECT [DISTINCT] select_list from_clause [WHERE condition] [PARTITION BY tag_list] [window_clause] [group_by_clause] - + 不支持 order_by,limit,slimit,fill 语句 ``` -### 触发模式 - -在创建流时,可以通过 TRIGGER 指令指定流式计算的触发模式。 - -对于非窗口计算,流式计算的触发是实时的; - -对于窗口计算,目前提供3种触发模式: - -1. AT_ONCE:写入立即触发 - -2. WINDOW_CLOSE:窗口关闭时触发(窗口关闭由事件时间决定,可配合 WATERMARK 使用,详见《流式计算的乱序数据容忍策略》) - -3. MAX_DELAY time:若窗口关闭,则触发计算。若窗口未关闭,且未关闭时长超过 MAX_DELAY 指定的时间,则触发计算。 - -由于窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,则事件时间无法更新,可能导致无法得到最新的计算结果。 - -因此,流式计算提供了以事件时间结合处理时间计算的 MAX_DELAY 触发模式。 - -MAX_DELAY 模式在窗口关闭时会立即触发计算。此外,当数据写入后,计算触发的时间超过 MAX_DELAY 指定的时间,则立即触发计算。 - -### 乱序数据容忍策略 - -在创建流时,可以在 stream_option 中指定 WATERMARK - -流式计算通过 WATERMARK 来度量对乱序数据的容忍程度,WATERMARK 默认为 0。 - - T = 最新事件时间 - WATERMARK - -每批到来的数据都会以上述公式更新窗口关闭时间,并将窗口结束时间 < T 的所有打开的窗口关闭,若触发模式为 WINDOW_CLOSE 或 MAX_DELAY,则推送窗口聚合结果。 - -### 流式计算的过期数据处理策略 - -对于已关闭的窗口,再次落入该窗口中的数据被标记为过期数据,对于过期数据,流式计算提供两种处理方式: - -1. 直接丢弃:这是常见流式计算引擎提供的默认(甚至是唯一)计算模式 - -2. 重新计算:从 TSDB 中重新查找对应窗口的所有数据并重新计算得到最新结果 - -无论在哪种模式下,watermark 都应该被妥善设置,来得到正确结果(直接丢弃模式)或避免频繁触发重算带来的性能开销(重新计算模式)。 ### 流式计算与窗口切分查询 @@ -78,8 +41,55 @@ window_clause: { } ``` -其中,SESSION 是会话窗口,tol_val 是时间间隔的最大范围。在 tol_val 时间间隔范围内的数据都属于同一个窗口,如果连续的两条数据的时间超过 tol_val,则自动开启下一个窗口。 +其中,SESSION 是会话窗口,tol_val 是时间间隔的最大范围。在 tol_val 时间间隔范围内的数据都属于同一个窗口,如果连续的两条数据的时间超过 tol_val,则自动开启下一个窗口; +STATE_WINDOW 是状态窗口,产生的连续记录如果具有相同的状态量数值则归属于同一个状态窗口,数值改变后该窗口关闭; +INTERVAL 是时间窗口,用于产生相等时间周期的窗口,查询过滤、聚合等操作按照每个时间窗口为独立的单位执行; +为了便于理解,下面以 interval(10s) 为例,假设事件时间为 "2022-08-06 00:00:01",对应的窗口为 "2022-08-06 00:00:00" ~ "2022-08-06 00:00:10"(窗口 A),那么下一个窗口为 "2022-08-06 00:00:10" ~ "2022-08-06 00:00:20"(窗口 B)。 + +### 流式计算的触发模式 + +在创建流时,可以通过 TRIGGER 指令指定流式计算的触发模式。 + +对于非窗口计算,流式计算的触发是实时的; + +对于窗口计算,目前提供 3 种触发模式: + +1. AT_ONCE:写入立即触发,窗口 A 和窗口 B 的数据写入后均可以立即触发计算; + +2. WINDOW_CLOSE:窗口关闭时触发(可配合 WATERMARK 使用,详见[流式计算的乱序数据容忍策略](#流式计算的乱序数据容忍策略),当窗口 B 的数据到达时,窗口 A 才会关闭并触发 WINDOW_CLOSE; + +3. MAX_DELAY time:若窗口 A 关闭,则触发计算。若窗口 B 未关闭,且未关闭时长超过 MAX_DELAY 指定的时间,则触发计算。 + +由于窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,则事件时间无法更新,可能导致无法得到最新的计算结果; + +因此,流式计算提供了以事件时间结合处理时间计算的 MAX_DELAY 触发模式; + +MAX_DELAY 模式在窗口关闭时或者数据写入后计算触发的时间超过 MAX_DELAY 指定的时间,会立即触发计算。 + +### 流式计算的乱序数据容忍策略 + +在创建流时,可以在 stream_options 中指定 WATERMARK; + +流式计算通过 WATERMARK 来度量对乱序数据的容忍程度,WATERMARK 默认为 0。 + + T = 最新事件时间 - WATERMARK + +每批到来的数据都会以上述公式更新窗口关闭时间,并将窗口结束时间 < T 的所有打开的窗口关闭,若触发模式为 WINDOW_CLOSE 或 MAX_DELAY,则推送窗口聚合结果。 + +以上面的 WINDOW_CLOSE 为例,如果设置了 WATERMARK 15s,那么窗口 A 和 B 均会延迟推送计算结果,当最新事件时间为 "2022-08-06 00:00:25" 时会推送窗口 A 的结果,当最新事件时间为 "2022-08-06 00:00:35" 时会推送窗口 B 的结果。 + +### 流式计算的过期数据处理策略 + +对于已关闭的窗口,再次落入该窗口中的数据被标记为过期数据,对于过期数据,流式计算提供两种处理方式: + +1. 直接丢弃:这是常见流式计算引擎提供的默认(甚至是唯一)计算模式; + +2. 重新计算:从 TSDB 中重新查找对应窗口的所有数据并重新计算得到最新结果; + +模式 1 创建流时需要在 stream_options 中配置 IGNORE EXPIRED,对于已经关闭的窗口,再次落入该窗口的乱序数据会被直接丢弃; + +无论在哪种模式下,WATERMARK 都应该被妥善设置,来得到正确结果(直接丢弃模式)或避免频繁触发重算带来的性能开销(重新计算模式)。 ## 流式计算的展示 @@ -90,7 +100,7 @@ SHOW STREAMS; ## 流式计算的删除 ```sql -DROP STREAM [IF NOT EXISTS] stream_name; +DROP STREAM [IF EXISTS] stream_name; ``` ## 使用案例 @@ -99,11 +109,11 @@ DROP STREAM [IF NOT EXISTS] stream_name; ### 创建 DB 和原始数据表 -首先准备数据,完成建库、建一张超级表和多张子表操作: +首先准备数据,完成建库、建一张超级表和多张子表操作 ```sql drop database if exists stream_db; -create database stream_db; +create database stream_db; create table stream_db.stb (ts timestamp, c1 int, c2 float, c3 varchar(16)) tags(t1 int, t3 varchar(16)); create table stream_db.ctb0 using stream_db.stb tags(0, "subtable0"); @@ -113,6 +123,7 @@ create table stream_db.ctb3 using stream_db.stb tags(3, "subtable3"); ``` ### 创建流 + case1. 创建流实现数据过滤 ```sql @@ -156,18 +167,21 @@ create stream stream7 trigger at_once ignore expired into stream_db.stream7_outp ``` ### 写入数据 + ```sql -insert into stream_db.ctb0 values("2022-08-13 00:00:00", 0, 0, 'a0'); insert into stream_db.ctb0 values("2022-08-13 00:00:01", 1, 1, 'a1'); insert into stream_db.ctb0 values("2022-08-13 00:00:07", 7, 7, 'a7'); -insert into stream_db.ctb0 values("2022-08-13 00:00:10", 10, 10, 'a10'); -insert into stream_db.ctb0 values("2022-08-13 00:00:13", 13, 13, 'a13'); -insert into stream_db.ctb0 values("2022-08-13 00:00:20", 20, 20, 'a20'); +insert into stream_db.ctb0 values("2022-08-13 00:00:11", 11, 11, 'a11'); insert into stream_db.ctb0 values("2022-08-13 00:00:21", 21, 21, 'a21'); +insert into stream_db.ctb0 values("2022-08-13 00:00:24", 24, 24, 'a24'); insert into stream_db.ctb0 values("2022-08-13 00:00:25", 25, 25, 'a25'); -insert into stream_db.ctb0 values("2022-08-13 00:00:26", 26, 26, 'a26'); +insert into stream_db.ctb0 values("2022-08-13 00:00:34", 34, 34, 'a34'); +insert into stream_db.ctb0 values("2022-08-13 00:00:35", 35, 35, 'a35'); +insert into stream_db.ctb0 values("2022-08-13 00:00:02", 2, 2, 'a2'); ``` + ### 查询以观查结果 + ```sql select * from stream_db.stream1_output_stb; select * from stream_db.stream2_output_stb; @@ -176,4 +190,4 @@ select * from stream_db.stream4_output_stb; select * from stream_db.stream5_output_stb; select * from stream_db.stream6_output_stb; select * from stream_db.stream7_output_stb; -``` \ No newline at end of file +``` From 761149051795a189fdf581c5e768f3d992b1991c Mon Sep 17 00:00:00 2001 From: jiajingbin Date: Mon, 8 Aug 2022 19:31:22 +0800 Subject: [PATCH 03/14] docs: update 06-stream.md for stream-computing --- docs/zh/07-develop/06-stream.md | 228 +++++++++++--------------------- 1 file changed, 80 insertions(+), 148 deletions(-) diff --git a/docs/zh/07-develop/06-stream.md b/docs/zh/07-develop/06-stream.md index 194ed4646c..61f17ff5b4 100644 --- a/docs/zh/07-develop/06-stream.md +++ b/docs/zh/07-develop/06-stream.md @@ -7,7 +7,7 @@ title: 流式计算 在时序数据的处理中,经常要对原始数据进行清洗、预处理,再使用时序数据库进行长久的储存。用户通常需要在时序数据库之外再搭建 Kafka、Flink、Spark 等流计算处理引擎,增加了用户的开发成本和维护成本。 使用 TDengine 3.0 的流式计算引擎能够最大限度的减少对这些额外中间件的依赖,真正将数据的写入、预处理、长期存储、复杂分析、实时计算、实时报警触发等功能融为一体,并且,所有这些任务只需要使用 SQL 完成,极大降低了用户的学习成本、使用成本。 -## 创建流 +## 流式计算的创建 ```sql CREATE STREAM [IF NOT EXISTS] stream_name [stream_options] INTO stb_name AS subquery @@ -16,96 +16,13 @@ stream_options: { WATERMARK time IGNORE EXPIRED } - -其中 subquery 是 select 普通查询语法的子集: - -subquery: SELECT [DISTINCT] select_list - from_clause - [WHERE condition] - [PARTITION BY tag_list] - [window_clause] - [group_by_clause] - -不支持 order_by,limit,slimit,fill 语句 ``` -### 流式计算与窗口切分查询 +详细的语法规则参考 [流式计算](/taos-sql/stream/) -窗口子句语法如下: +## 示例一 -```sql -window_clause: { - SESSION(ts_col, tol_val) - | STATE_WINDOW(col) - | INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] -} -``` - -其中,SESSION 是会话窗口,tol_val 是时间间隔的最大范围。在 tol_val 时间间隔范围内的数据都属于同一个窗口,如果连续的两条数据的时间超过 tol_val,则自动开启下一个窗口; -STATE_WINDOW 是状态窗口,产生的连续记录如果具有相同的状态量数值则归属于同一个状态窗口,数值改变后该窗口关闭; -INTERVAL 是时间窗口,用于产生相等时间周期的窗口,查询过滤、聚合等操作按照每个时间窗口为独立的单位执行; - -为了便于理解,下面以 interval(10s) 为例,假设事件时间为 "2022-08-06 00:00:01",对应的窗口为 "2022-08-06 00:00:00" ~ "2022-08-06 00:00:10"(窗口 A),那么下一个窗口为 "2022-08-06 00:00:10" ~ "2022-08-06 00:00:20"(窗口 B)。 - -### 流式计算的触发模式 - -在创建流时,可以通过 TRIGGER 指令指定流式计算的触发模式。 - -对于非窗口计算,流式计算的触发是实时的; - -对于窗口计算,目前提供 3 种触发模式: - -1. AT_ONCE:写入立即触发,窗口 A 和窗口 B 的数据写入后均可以立即触发计算; - -2. WINDOW_CLOSE:窗口关闭时触发(可配合 WATERMARK 使用,详见[流式计算的乱序数据容忍策略](#流式计算的乱序数据容忍策略),当窗口 B 的数据到达时,窗口 A 才会关闭并触发 WINDOW_CLOSE; - -3. MAX_DELAY time:若窗口 A 关闭,则触发计算。若窗口 B 未关闭,且未关闭时长超过 MAX_DELAY 指定的时间,则触发计算。 - -由于窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,则事件时间无法更新,可能导致无法得到最新的计算结果; - -因此,流式计算提供了以事件时间结合处理时间计算的 MAX_DELAY 触发模式; - -MAX_DELAY 模式在窗口关闭时或者数据写入后计算触发的时间超过 MAX_DELAY 指定的时间,会立即触发计算。 - -### 流式计算的乱序数据容忍策略 - -在创建流时,可以在 stream_options 中指定 WATERMARK; - -流式计算通过 WATERMARK 来度量对乱序数据的容忍程度,WATERMARK 默认为 0。 - - T = 最新事件时间 - WATERMARK - -每批到来的数据都会以上述公式更新窗口关闭时间,并将窗口结束时间 < T 的所有打开的窗口关闭,若触发模式为 WINDOW_CLOSE 或 MAX_DELAY,则推送窗口聚合结果。 - -以上面的 WINDOW_CLOSE 为例,如果设置了 WATERMARK 15s,那么窗口 A 和 B 均会延迟推送计算结果,当最新事件时间为 "2022-08-06 00:00:25" 时会推送窗口 A 的结果,当最新事件时间为 "2022-08-06 00:00:35" 时会推送窗口 B 的结果。 - -### 流式计算的过期数据处理策略 - -对于已关闭的窗口,再次落入该窗口中的数据被标记为过期数据,对于过期数据,流式计算提供两种处理方式: - -1. 直接丢弃:这是常见流式计算引擎提供的默认(甚至是唯一)计算模式; - -2. 重新计算:从 TSDB 中重新查找对应窗口的所有数据并重新计算得到最新结果; - -模式 1 创建流时需要在 stream_options 中配置 IGNORE EXPIRED,对于已经关闭的窗口,再次落入该窗口的乱序数据会被直接丢弃; - -无论在哪种模式下,WATERMARK 都应该被妥善设置,来得到正确结果(直接丢弃模式)或避免频繁触发重算带来的性能开销(重新计算模式)。 - -## 流式计算的展示 - -```sql -SHOW STREAMS; -``` - -## 流式计算的删除 - -```sql -DROP STREAM [IF EXISTS] stream_name; -``` - -## 使用案例 - -通过以下案例,进一步了解 TDengine 流计算的使用 +查找过去 12 小时电表电压大于 220V 的记录条数和电流的最大值,并对采集的数据按时间窗口聚合。 ### 创建 DB 和原始数据表 @@ -115,79 +32,94 @@ DROP STREAM [IF EXISTS] stream_name; drop database if exists stream_db; create database stream_db; -create table stream_db.stb (ts timestamp, c1 int, c2 float, c3 varchar(16)) tags(t1 int, t3 varchar(16)); -create table stream_db.ctb0 using stream_db.stb tags(0, "subtable0"); -create table stream_db.ctb1 using stream_db.stb tags(1, "subtable1"); -create table stream_db.ctb2 using stream_db.stb tags(2, "subtable2"); -create table stream_db.ctb3 using stream_db.stb tags(3, "subtable3"); +create stable stream_db.meters (ts timestamp, current float, voltage int) TAGS (location varchar(64), groupId int); + +create table stream_db.d1001 using stream_db.meters tags("beijing", 1); +create table stream_db.d1002 using stream_db.meters tags("guangzhou", 2); +create table stream_db.d1003 using stream_db.meters tags("shanghai", 3); ``` ### 创建流 -case1. 创建流实现数据过滤 - ```sql -create stream stream1 into stream_db.stream1_output_stb as select * from stream_db.stb where c1 > 0 and c2 != 10 and c3 is not Null; -``` - -case2. 创建流实现标量函数的数据转换 - -```sql -create stream stream2 into stream_db.stream2_output_stb as select ts, abs(c2), char_length(c3), cast(c1 as binary(16)),timezone() from stream_db.stb partition by tbname; -``` - -case3. 创建流实现数据降采样 - -```sql -create stream stream3 into stream_db.stream3_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); -``` - -case4. 通过 trigger window_close 控制流的触发频率 - -```sql -create stream stream4 trigger window_close into stream_db.stream4_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); -``` - -case4. 通过 trigger max_delay 控制流的触发频率 - -```sql -create stream stream5 trigger max_delay 3s into stream_db.stream5_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); -``` - -case6. 通过 watermark 实现乱序数据容忍 - -```sql -create stream stream6 trigger window_close watermark 15s into stream_db.stream6_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); -``` - -case7. 通过 ignore expired 实现乱序数据丢弃 - -```sql -create stream stream7 trigger at_once ignore expired into stream_db.stream7_output_stb as select _wstart as start, min(c1), max(c2), count(c3) from stream_db.stb interval (10s); +create stream stream1 into stream_db.stream1_output_stb as select _wstart as start, count(voltage), max(current) from stream_db.meters where voltage > 220 and ts > now - 12h interval (1h); ``` ### 写入数据 - ```sql -insert into stream_db.ctb0 values("2022-08-13 00:00:01", 1, 1, 'a1'); -insert into stream_db.ctb0 values("2022-08-13 00:00:07", 7, 7, 'a7'); -insert into stream_db.ctb0 values("2022-08-13 00:00:11", 11, 11, 'a11'); -insert into stream_db.ctb0 values("2022-08-13 00:00:21", 21, 21, 'a21'); -insert into stream_db.ctb0 values("2022-08-13 00:00:24", 24, 24, 'a24'); -insert into stream_db.ctb0 values("2022-08-13 00:00:25", 25, 25, 'a25'); -insert into stream_db.ctb0 values("2022-08-13 00:00:34", 34, 34, 'a34'); -insert into stream_db.ctb0 values("2022-08-13 00:00:35", 35, 35, 'a35'); -insert into stream_db.ctb0 values("2022-08-13 00:00:02", 2, 2, 'a2'); +insert into stream_db.d1001 values(now-14h, 10.3, 210); +insert into stream_db.d1001 values(now-13h, 13.5, 226); +insert into stream_db.d1001 values(now-12h, 12.5, 221); +insert into stream_db.d1002 values(now-11h, 14.7, 221); +insert into stream_db.d1002 values(now-10h, 10.5, 219); +insert into stream_db.d1002 values(now-9h, 11.2, 217); +insert into stream_db.d1003 values(now-8h, 11.5, 222); +insert into stream_db.d1003 values(now-7h, 12.3, 227); +insert into stream_db.d1003 values(now-6h, 12.3, 215); ``` ### 查询以观查结果 +```sql +taos> select * from stream_db.stream1_output_stb; + start | count(voltage) | max(current) | group_id | +================================================================================================= + 2022-08-08 08:00:00.000 | 1 | 14.70000 | 0 | + 2022-08-08 11:00:00.000 | 1 | 11.50000 | 0 | + 2022-08-08 12:00:00.000 | 1 | 12.30000 | 0 | +Query OK, 3 rows in database (0.008239s) +``` + +## 示例二 +查询所有电表中电压等于 220V 的数据,对过滤出的电表电流数据进行四舍五入运算,同时将主键时间戳列转换为 bigint 类型,并对采集的数据按表名分组。 + +### 创建 DB 和原始数据表 +首先准备数据,完成建库、建一张超级表和多张子表操作 ```sql -select * from stream_db.stream1_output_stb; -select * from stream_db.stream2_output_stb; -select * from stream_db.stream3_output_stb; -select * from stream_db.stream4_output_stb; -select * from stream_db.stream5_output_stb; -select * from stream_db.stream6_output_stb; -select * from stream_db.stream7_output_stb; +drop database if exists stream_db; +create database stream_db; + +create stable stream_db.meters (ts timestamp, current float, voltage int) TAGS (location varchar(64), groupId int); + +create table stream_db.d1001 using stream_db.meters tags("beijing", 1); +create table stream_db.d1002 using stream_db.meters tags("shanghai", 2); +create table stream_db.d1003 using stream_db.meters tags("beijing", 2); +create table stream_db.d1004 using stream_db.meters tags("tianjin", 3); +create table stream_db.d1005 using stream_db.meters tags("shanghai", 1); ``` + +### 创建流 + +```sql +create stream stream2 into stream_db.stream2_output_stb as select ts,cast(ts as bigint),round(current),location from stream_db.meters where voltage=220 partition by tbname; +``` + +### 写入数据 +```sql +insert into stream_db.d1001 values(now-14h, 10.3, 210); +insert into stream_db.d1001 values(now-13h, 13.5, 220); +insert into stream_db.d1002 values(now-12h, 14.7, 218); +insert into stream_db.d1002 values(now-11h, 10.5, 220); +insert into stream_db.d1003 values(now-10h, 11.5, 220); +insert into stream_db.d1003 values(now-9h, 12.3, 215); +insert into stream_db.d1004 values(now-8h, 11.5, 220); +insert into stream_db.d1004 values(now-7h, 15.3, 217); +insert into stream_db.d1005 values(now-6h, 16.5, 216); +insert into stream_db.d1005 values(now-5h, 12.3, 220); +``` +### 查询以观查结果 +```sql +taos> select * from stream_db.stream2_output_stb; + ts | cast(ts as bigint) | round(current) | location | group_id | +================================================================================================================================== + 2022-08-08 09:29:55.557 | 1659922195557 | 12.00000 | beijing | 7226905450883977166 | + 2022-08-08 11:29:55.570 | 1659929395570 | 12.00000 | tianjin | 7226905450884501455 | + 2022-08-08 08:29:55.549 | 1659918595549 | 11.00000 | shanghai | 7226905450883452877 | + 2022-08-08 06:29:55.534 | 1659911395534 | 14.00000 | beijing | 7226905450882928588 | + 2022-08-08 14:29:56.175 | 1659940196175 | 12.00000 | shanghai | 7226905450895708112 | +Query OK, 5 rows in database (0.015235s) +``` + +## 示例三 +...待续 + From 88555c21201fdb224b895c244bec1bc87ad5b1e3 Mon Sep 17 00:00:00 2001 From: jiajingbin Date: Tue, 9 Aug 2022 09:03:51 +0800 Subject: [PATCH 04/14] docs: update 06-stream.md for stream-computing --- docs/zh/07-develop/06-stream.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/07-develop/06-stream.md b/docs/zh/07-develop/06-stream.md index 61f17ff5b4..78f1edbfe8 100644 --- a/docs/zh/07-develop/06-stream.md +++ b/docs/zh/07-develop/06-stream.md @@ -18,7 +18,7 @@ stream_options: { } ``` -详细的语法规则参考 [流式计算](/taos-sql/stream/) +详细的语法规则参考 [流式计算](../../taos-sql/stream) ## 示例一 From 29402da45f377fefc47a2ebcba4018415a05b8cc Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Tue, 9 Aug 2022 20:46:37 +0800 Subject: [PATCH 05/14] test: adjust case --- tests/script/jenkins/basic.txt | 2 +- tests/script/tsim/db/basic6.sim | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 23676153b5..90f213ec17 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -7,7 +7,7 @@ ./test.sh -f tsim/user/privilege_db.sim ./test.sh -f tsim/user/privilege_sysinfo.sim -# ---- db +# ---- db ---- ./test.sh -f tsim/db/alter_option.sim # unsupport ./test.sh -f tsim/db/alter_replica_13.sim # unsupport ./test.sh -f tsim/db/alter_replica_31.sim diff --git a/tests/script/tsim/db/basic6.sim b/tests/script/tsim/db/basic6.sim index 917345e25f..c978dc66c8 100644 --- a/tests/script/tsim/db/basic6.sim +++ b/tests/script/tsim/db/basic6.sim @@ -82,8 +82,6 @@ if $data26 != 21600m then return -1 endi -return - print =============== step6 $i = $i + 1 while $i < 5 @@ -251,7 +249,7 @@ if $rows != 5 then return -1 endi -sql select * from $stb +sql select * from $st if $rows != 5 then return -1 endi @@ -306,7 +304,7 @@ if $rows != 5 then return -1 endi -sql select * from $stb +sql select * from $st if $rows != 5 then return -1 endi From 06aac0fca1b05de89a6e66b5bb961a801b8e941c Mon Sep 17 00:00:00 2001 From: jiajingbin Date: Wed, 10 Aug 2022 00:37:34 +0800 Subject: [PATCH 06/14] docs: update 06-stream.md for stream-computing --- docs/zh/07-develop/06-stream.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/zh/07-develop/06-stream.md b/docs/zh/07-develop/06-stream.md index 78f1edbfe8..ee5969143a 100644 --- a/docs/zh/07-develop/06-stream.md +++ b/docs/zh/07-develop/06-stream.md @@ -22,7 +22,7 @@ stream_options: { ## 示例一 -查找过去 12 小时电表电压大于 220V 的记录条数和电流的最大值,并对采集的数据按时间窗口聚合。 +企业电表的数据经常都是成百上千亿条的,那么想要将这些分散、凌乱的数据清洗或转换都需要比较长的时间,很难做到高效性和实时性,以下例子中,通过流计算可以将过去 12 小时电表电压大于 220V 的数据清洗掉,然后以小时为窗口整合并计算出每个窗口中电流的最大值,并将结果输出到指定的数据表中。 ### 创建 DB 和原始数据表 @@ -42,18 +42,18 @@ create table stream_db.d1003 using stream_db.meters tags("shanghai", 3); ### 创建流 ```sql -create stream stream1 into stream_db.stream1_output_stb as select _wstart as start, count(voltage), max(current) from stream_db.meters where voltage > 220 and ts > now - 12h interval (1h); +create stream stream1 into stream_db.stream1_output_stb as select _wstart as start, _wend as end, max(current) as max_current from stream_db.meters where voltage <= 220 and ts > now - 12h interval (1h); ``` ### 写入数据 ```sql insert into stream_db.d1001 values(now-14h, 10.3, 210); -insert into stream_db.d1001 values(now-13h, 13.5, 226); -insert into stream_db.d1001 values(now-12h, 12.5, 221); +insert into stream_db.d1001 values(now-13h, 13.5, 216); +insert into stream_db.d1001 values(now-12h, 12.5, 219); insert into stream_db.d1002 values(now-11h, 14.7, 221); -insert into stream_db.d1002 values(now-10h, 10.5, 219); -insert into stream_db.d1002 values(now-9h, 11.2, 217); -insert into stream_db.d1003 values(now-8h, 11.5, 222); +insert into stream_db.d1002 values(now-10h, 10.5, 218); +insert into stream_db.d1002 values(now-9h, 11.2, 220); +insert into stream_db.d1003 values(now-8h, 11.5, 217); insert into stream_db.d1003 values(now-7h, 12.3, 227); insert into stream_db.d1003 values(now-6h, 12.3, 215); ``` @@ -61,12 +61,13 @@ insert into stream_db.d1003 values(now-6h, 12.3, 215); ### 查询以观查结果 ```sql taos> select * from stream_db.stream1_output_stb; - start | count(voltage) | max(current) | group_id | -================================================================================================= - 2022-08-08 08:00:00.000 | 1 | 14.70000 | 0 | - 2022-08-08 11:00:00.000 | 1 | 11.50000 | 0 | - 2022-08-08 12:00:00.000 | 1 | 12.30000 | 0 | -Query OK, 3 rows in database (0.008239s) + start | end | max_current | group_id | +=================================================================================================== + 2022-08-09 14:00:00.000 | 2022-08-09 15:00:00.000 | 10.50000 | 0 | + 2022-08-09 15:00:00.000 | 2022-08-09 16:00:00.000 | 11.20000 | 0 | + 2022-08-09 16:00:00.000 | 2022-08-09 17:00:00.000 | 11.50000 | 0 | + 2022-08-09 18:00:00.000 | 2022-08-09 19:00:00.000 | 12.30000 | 0 | +Query OK, 4 rows in database (0.012033s) ``` ## 示例二 From 8a9e3ed76cb62b08c44801f2d5e64d28f02ef86d Mon Sep 17 00:00:00 2001 From: jiajingbin Date: Wed, 10 Aug 2022 11:30:04 +0800 Subject: [PATCH 07/14] docs: update 06-stream.md for stream-computing --- docs/zh/07-develop/06-stream.md | 62 +++++++++++++++++---------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/docs/zh/07-develop/06-stream.md b/docs/zh/07-develop/06-stream.md index ee5969143a..dbf8684008 100644 --- a/docs/zh/07-develop/06-stream.md +++ b/docs/zh/07-develop/06-stream.md @@ -71,7 +71,7 @@ Query OK, 4 rows in database (0.012033s) ``` ## 示例二 -查询所有电表中电压等于 220V 的数据,对过滤出的电表电流数据进行四舍五入运算,同时将主键时间戳列转换为 bigint 类型,并对采集的数据按表名分组。 +某运营商平台要采集机房所有服务器的系统资源指标,包含 cpu、内存、网络延迟等,采集后需要对数据进行四舍五入运算,将地域和服务器名以下划线拼接,然后将结果按时间排序并以服务器名分组输出到新的数据表中。 ### 创建 DB 和原始数据表 首先准备数据,完成建库、建一张超级表和多张子表操作 @@ -80,47 +80,49 @@ Query OK, 4 rows in database (0.012033s) drop database if exists stream_db; create database stream_db; -create stable stream_db.meters (ts timestamp, current float, voltage int) TAGS (location varchar(64), groupId int); +create stable stream_db.idc (ts timestamp, cpu float, mem float, latency float) TAGS (location varchar(64), groupId int); -create table stream_db.d1001 using stream_db.meters tags("beijing", 1); -create table stream_db.d1002 using stream_db.meters tags("shanghai", 2); -create table stream_db.d1003 using stream_db.meters tags("beijing", 2); -create table stream_db.d1004 using stream_db.meters tags("tianjin", 3); -create table stream_db.d1005 using stream_db.meters tags("shanghai", 1); +create table stream_db.server01 using stream_db.idc tags("beijing", 1); +create table stream_db.server02 using stream_db.idc tags("shanghai", 2); +create table stream_db.server03 using stream_db.idc tags("beijing", 2); +create table stream_db.server04 using stream_db.idc tags("tianjin", 3); +create table stream_db.server05 using stream_db.idc tags("shanghai", 1); ``` ### 创建流 ```sql -create stream stream2 into stream_db.stream2_output_stb as select ts,cast(ts as bigint),round(current),location from stream_db.meters where voltage=220 partition by tbname; +create stream stream2 into stream_db.stream2_output_stb as select ts, concat_ws("_", location, tbname) as server_location, round(cpu) as cpu, round(mem) as mem, round(latency) as latency from stream_db.idc partition by tbname order by ts; ``` ### 写入数据 ```sql -insert into stream_db.d1001 values(now-14h, 10.3, 210); -insert into stream_db.d1001 values(now-13h, 13.5, 220); -insert into stream_db.d1002 values(now-12h, 14.7, 218); -insert into stream_db.d1002 values(now-11h, 10.5, 220); -insert into stream_db.d1003 values(now-10h, 11.5, 220); -insert into stream_db.d1003 values(now-9h, 12.3, 215); -insert into stream_db.d1004 values(now-8h, 11.5, 220); -insert into stream_db.d1004 values(now-7h, 15.3, 217); -insert into stream_db.d1005 values(now-6h, 16.5, 216); -insert into stream_db.d1005 values(now-5h, 12.3, 220); +insert into stream_db.server01 values(now-14h, 50.9, 654.8, 23.11); +insert into stream_db.server01 values(now-13h, 13.5, 221.2, 11.22); +insert into stream_db.server02 values(now-12h, 154.7, 218.3, 22.33); +insert into stream_db.server02 values(now-11h, 120.5, 111.5, 5.55); +insert into stream_db.server03 values(now-10h, 101.5, 125.6, 5.99); +insert into stream_db.server03 values(now-9h, 12.3, 165.6, 6.02); +insert into stream_db.server04 values(now-8h, 160.9, 120.7, 43.51); +insert into stream_db.server04 values(now-7h, 240.9, 520.7, 54.55); +insert into stream_db.server05 values(now-6h, 190.9, 320.7, 55.43); +insert into stream_db.server05 values(now-5h, 110.9, 600.7, 35.54); ``` ### 查询以观查结果 ```sql -taos> select * from stream_db.stream2_output_stb; - ts | cast(ts as bigint) | round(current) | location | group_id | -================================================================================================================================== - 2022-08-08 09:29:55.557 | 1659922195557 | 12.00000 | beijing | 7226905450883977166 | - 2022-08-08 11:29:55.570 | 1659929395570 | 12.00000 | tianjin | 7226905450884501455 | - 2022-08-08 08:29:55.549 | 1659918595549 | 11.00000 | shanghai | 7226905450883452877 | - 2022-08-08 06:29:55.534 | 1659911395534 | 14.00000 | beijing | 7226905450882928588 | - 2022-08-08 14:29:56.175 | 1659940196175 | 12.00000 | shanghai | 7226905450895708112 | -Query OK, 5 rows in database (0.015235s) +taos> select ts, server_location, cpu, mem, latency from stream_db.stream2_output_stb; + ts | server_location | cpu | mem | latency | +================================================================================================================================ + 2022-08-09 21:24:56.785 | beijing_server01 | 51.00000 | 655.00000 | 23.00000 | + 2022-08-09 22:24:56.795 | beijing_server01 | 14.00000 | 221.00000 | 11.00000 | + 2022-08-09 23:24:56.806 | shanghai_server02 | 155.00000 | 218.00000 | 22.00000 | + 2022-08-10 00:24:56.815 | shanghai_server02 | 121.00000 | 112.00000 | 6.00000 | + 2022-08-10 01:24:56.826 | beijing_server03 | 102.00000 | 126.00000 | 6.00000 | + 2022-08-10 02:24:56.838 | beijing_server03 | 12.00000 | 166.00000 | 6.00000 | + 2022-08-10 03:24:56.846 | tianjin_server04 | 161.00000 | 121.00000 | 44.00000 | + 2022-08-10 04:24:56.853 | tianjin_server04 | 241.00000 | 521.00000 | 55.00000 | + 2022-08-10 05:24:56.866 | shanghai_server05 | 191.00000 | 321.00000 | 55.00000 | + 2022-08-10 06:24:57.301 | shanghai_server05 | 111.00000 | 601.00000 | 36.00000 | +Query OK, 10 rows in database (0.022950s) ``` -## 示例三 -...待续 - From 2aad872a173f9dd95e093ca3cb6baad9b1f528f8 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 11 Aug 2022 10:38:34 +0800 Subject: [PATCH 08/14] test: valgrind case --- tests/script/jenkins/basic.txt | 1 + tests/script/tsim/valgrind/basic3.sim | 10 ++++++++++ tests/script/tsim/valgrind/checkError6.sim | 3 +++ 3 files changed, 14 insertions(+) diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 6d885131c2..97295d75e0 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -316,6 +316,7 @@ ./test.sh -f tsim/valgrind/checkError5.sim ./test.sh -f tsim/valgrind/checkError6.sim ./test.sh -f tsim/valgrind/checkError7.sim +./test.sh -f tsim/valgrind/checkError8.sim ./test.sh -f tsim/valgrind/checkUdf.sim # --- vnode ---- diff --git a/tests/script/tsim/valgrind/basic3.sim b/tests/script/tsim/valgrind/basic3.sim index 3a51186d55..8ef1ff2a41 100644 --- a/tests/script/tsim/valgrind/basic3.sim +++ b/tests/script/tsim/valgrind/basic3.sim @@ -53,6 +53,16 @@ print =============== step3: tb sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 1 soffset 1; sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 2 soffset 4 limit 10 offset 1; +sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 1 soffset 1; +sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 2 soffset 4 limit 10 offset 1; +sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 1 soffset 1; +sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 2 soffset 4 limit 10 offset 1; +sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 1 soffset 1; +sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 2 soffset 4 limit 10 offset 1; +sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 1 soffset 1; +sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 2 soffset 4 limit 10 offset 1; + +sleep 1000 _OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/valgrind/checkError6.sim b/tests/script/tsim/valgrind/checkError6.sim index 70f55370d2..cd8b94e1d0 100644 --- a/tests/script/tsim/valgrind/checkError6.sim +++ b/tests/script/tsim/valgrind/checkError6.sim @@ -113,6 +113,9 @@ sql select tbcol5 - tbcol3 from stb sql select spread( tbcol2 )/44, spread(tbcol2), 0.204545455 * 44 from stb; sql select min(tbcol) * max(tbcol) /4, sum(tbcol2) * apercentile(tbcol2, 20), apercentile(tbcol2, 33) + 52/9 from stb; +sql select distinct(tbname), tgcol from stb; +#sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 1 soffset 1; +#sql select sum(tbcol) from stb partition by tbname interval(1s) slimit 2 soffset 4 limit 10 offset 1; print =============== step5: explain sql explain analyze select ts from stb where -2; From 009777a727564a98bbc1e3db736508e0186ac2fe Mon Sep 17 00:00:00 2001 From: slzhou Date: Thu, 11 Aug 2022 16:23:53 +0800 Subject: [PATCH 09/14] fix: add multi-timeline support for session and state --- source/libs/executor/inc/executorimpl.h | 1 + source/libs/executor/src/timewindowoperator.c | 35 ++++++++++--------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index d460644633..9ea1d534cc 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -682,6 +682,7 @@ typedef struct SWindowRowsSup { TSKEY prevTs; int32_t startRowIndex; int32_t numOfRows; + uint64_t groupId; } SWindowRowsSup; typedef struct SSessionAggOperatorInfo { diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 610303dc50..029bbf3d8f 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -90,16 +90,18 @@ static void updateTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pWin, b ts[4] = pWin->ekey + delta; // window end key } -static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts) { +static void doKeepTuple(SWindowRowsSup* pRowSup, int64_t ts, uint64_t groupId) { pRowSup->win.ekey = ts; pRowSup->prevTs = ts; pRowSup->numOfRows += 1; + pRowSup->groupId = groupId; } -static void doKeepNewWindowStartInfo(SWindowRowsSup* pRowSup, const int64_t* tsList, int32_t rowIndex) { +static void doKeepNewWindowStartInfo(SWindowRowsSup* pRowSup, const int64_t* tsList, int32_t rowIndex, uint64_t groupId) { pRowSup->startRowIndex = rowIndex; pRowSup->numOfRows = 0; pRowSup->win.skey = tsList[rowIndex]; + pRowSup->groupId = groupId; } static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn_t searchFn, TSKEY ekey, @@ -1142,7 +1144,7 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI char* val = colDataGetData(pStateColInfoData, j); - if (!pInfo->hasKey) { + if (gid != pRowSup->groupId || !pInfo->hasKey) { // todo extract method if (IS_VAR_DATA_TYPE(pInfo->stateKey.type)) { varDataCopy(pInfo->stateKey.pData, val); @@ -1152,10 +1154,10 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI pInfo->hasKey = true; - doKeepNewWindowStartInfo(pRowSup, tsList, j); - doKeepTuple(pRowSup, tsList[j]); + doKeepNewWindowStartInfo(pRowSup, tsList, j, gid); + doKeepTuple(pRowSup, tsList[j], gid); } else if (compareVal(val, &pInfo->stateKey)) { - doKeepTuple(pRowSup, tsList[j]); + doKeepTuple(pRowSup, tsList[j], gid); if (j == 0 && pRowSup->startRowIndex != 0) { pRowSup->startRowIndex = 0; } @@ -1177,8 +1179,8 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC); // here we start a new session window - doKeepNewWindowStartInfo(pRowSup, tsList, j); - doKeepTuple(pRowSup, tsList[j]); + doKeepNewWindowStartInfo(pRowSup, tsList, j, gid); + doKeepTuple(pRowSup, tsList[j], gid); // todo extract method if (IS_VAR_DATA_TYPE(pInfo->stateKey.type)) { @@ -1911,7 +1913,7 @@ _error: return NULL; } -// todo handle multiple tables cases. +// todo handle multiple timeline cases. assume no timeline interweaving static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperatorInfo* pInfo, SSDataBlock* pBlock) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExprSupp* pSup = &pOperator->exprSupp; @@ -1935,12 +1937,13 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperator // In case of ascending or descending order scan data, only one time window needs to be kepted for each table. TSKEY* tsList = (TSKEY*)pColInfoData->pData; for (int32_t j = 0; j < pBlock->info.rows; ++j) { - if (pInfo->winSup.prevTs == INT64_MIN) { - doKeepNewWindowStartInfo(pRowSup, tsList, j); - doKeepTuple(pRowSup, tsList[j]); - } else if (tsList[j] - pRowSup->prevTs <= gap && (tsList[j] - pRowSup->prevTs) >= 0) { + if (gid != pRowSup->groupId || pInfo->winSup.prevTs == INT64_MIN) { + doKeepNewWindowStartInfo(pRowSup, tsList, j, gid); + doKeepTuple(pRowSup, tsList[j], gid); + } else if ((tsList[j] - pRowSup->prevTs >= 0) && tsList[j] - pRowSup->prevTs <= gap || + (pRowSup->prevTs - tsList[j] >= 0 ) && (pRowSup->prevTs - tsList[j] <= gap)) { // The gap is less than the threshold, so it belongs to current session window that has been opened already. - doKeepTuple(pRowSup, tsList[j]); + doKeepTuple(pRowSup, tsList[j], gid); if (j == 0 && pRowSup->startRowIndex != 0) { pRowSup->startRowIndex = 0; } @@ -1963,8 +1966,8 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperator pRowSup->numOfRows, NULL, pBlock->info.rows, numOfOutput, TSDB_ORDER_ASC); // here we start a new session window - doKeepNewWindowStartInfo(pRowSup, tsList, j); - doKeepTuple(pRowSup, tsList[j]); + doKeepNewWindowStartInfo(pRowSup, tsList, j, gid); + doKeepTuple(pRowSup, tsList[j], gid); } } From c10a1adbd3958c41ed1bed6dd1160162e2cf4c7d Mon Sep 17 00:00:00 2001 From: 54liuyao <54liuyao@163.com> Date: Thu, 11 Aug 2022 16:31:51 +0800 Subject: [PATCH 10/14] feat(stream):delete window --- source/libs/executor/src/timewindowoperator.c | 4 +--- source/libs/function/src/builtinsimpl.c | 9 +++++++++ tests/script/tsim/stream/session0.sim | 6 +++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index cf8d81cbb5..bdc0666d51 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -3586,9 +3586,7 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh _hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); pInfo->pStDeleted = taosHashInit(64, hashFn, true, HASH_NO_LOCK); pInfo->pDelIterator = NULL; - // pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); - pInfo->pDelRes = createOneDataBlock(pInfo->binfo.pRes, false); // todo(liuyao) for delete - pInfo->pDelRes->info.type = STREAM_DELETE_RESULT; // todo(liuyao) for delete + pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT); pInfo->pChildren = NULL; pInfo->isFinal = false; pInfo->pPhyNode = pPhyNode; diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index d44cb952e3..de72c32fa1 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -748,6 +748,7 @@ int32_t sumCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { pDBuf->dsum += pSBuf->dsum; } pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); + pDResInfo->isNullRes &= pSResInfo->isNullRes; return TSDB_CODE_SUCCESS; } @@ -1746,6 +1747,7 @@ int32_t minMaxCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx, int3 } } pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); + pDResInfo->isNullRes &= pSResInfo->isNullRes; return TSDB_CODE_SUCCESS; } @@ -2121,6 +2123,7 @@ int32_t stddevCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { } pDBuf->count += pSBuf->count; pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); + pDResInfo->isNullRes &= pSResInfo->isNullRes; return TSDB_CODE_SUCCESS; } @@ -2311,6 +2314,7 @@ int32_t leastSQRCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { pDparam[1][2] += pSparam[1][2]; pDBuf->num += pSBuf->num; pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); + pDResInfo->isNullRes &= pSResInfo->isNullRes; return TSDB_CODE_SUCCESS; } @@ -2707,6 +2711,7 @@ int32_t apercentileCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) apercentileTransferInfo(pSBuf, pDBuf); pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); + pDResInfo->isNullRes &= pSResInfo->isNullRes; return TSDB_CODE_SUCCESS; } @@ -3890,6 +3895,7 @@ int32_t spreadCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { SSpreadInfo* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo); spreadTransferInfo(pSBuf, pDBuf); pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); + pDResInfo->isNullRes &= pSResInfo->isNullRes; return TSDB_CODE_SUCCESS; } @@ -4062,6 +4068,7 @@ int32_t elapsedCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { elapsedTransferInfo(pSBuf, pDBuf); pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); + pDResInfo->isNullRes &= pSResInfo->isNullRes; return TSDB_CODE_SUCCESS; } @@ -4379,6 +4386,7 @@ int32_t histogramCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { histogramTransferInfo(pSBuf, pDBuf); pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); + pDResInfo->isNullRes &= pSResInfo->isNullRes; return TSDB_CODE_SUCCESS; } @@ -4576,6 +4584,7 @@ int32_t hllCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { hllTransferInfo(pSBuf, pDBuf); pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); + pDResInfo->isNullRes &= pSResInfo->isNullRes; return TSDB_CODE_SUCCESS; } diff --git a/tests/script/tsim/stream/session0.sim b/tests/script/tsim/stream/session0.sim index d05a9e1814..7cd9b75a4b 100644 --- a/tests/script/tsim/stream/session0.sim +++ b/tests/script/tsim/stream/session0.sim @@ -5,15 +5,15 @@ sleep 50 sql connect print =============== create database -sql create database test vgroups 1 -sql show databases +sql create database test vgroups 1; +sql show databases; if $rows != 3 then return -1 endi print $data00 $data01 $data02 -sql use test +sql use test; sql create table t1(ts timestamp, a int, b int , c int, d double,id int); From 7ee1a87f20aa05c990b4757d5c1530a39a39b999 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang <59301069+xiao-yu-wang@users.noreply.github.com> Date: Thu, 11 Aug 2022 17:16:09 +0800 Subject: [PATCH 11/14] Update 06-select.md --- docs/zh/12-taos-sql/06-select.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/12-taos-sql/06-select.md b/docs/zh/12-taos-sql/06-select.md index 75f149d0ae..635e74288d 100644 --- a/docs/zh/12-taos-sql/06-select.md +++ b/docs/zh/12-taos-sql/06-select.md @@ -152,7 +152,7 @@ taos> SELECT ts, ts AS primary_key_ts FROM d1001; 获取一个超级表所有的子表名及相关的标签信息: ```mysql -SELECT TBNAME, location FROM meters; +SELECT DISTINCT TBNAME, location FROM meters; ``` 统计超级表下辖子表数量: From 161468d776f8b750c9bd89cce90c7a6792686377 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang <59301069+xiao-yu-wang@users.noreply.github.com> Date: Thu, 11 Aug 2022 17:20:45 +0800 Subject: [PATCH 12/14] Update 06-select.md --- docs/zh/12-taos-sql/06-select.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/zh/12-taos-sql/06-select.md b/docs/zh/12-taos-sql/06-select.md index 635e74288d..8aa6c43747 100644 --- a/docs/zh/12-taos-sql/06-select.md +++ b/docs/zh/12-taos-sql/06-select.md @@ -140,10 +140,6 @@ taos> SELECT ts, ts AS primary_key_ts FROM d1001; 但是针对`first(*)`、`last(*)`、`last_row(*)`不支持针对单列的重命名。 -### 隐式结果列 - -`Select_exprs`可以是表所属列的列名,也可以是基于列的函数表达式或计算式,数量的上限 256 个。当用户使用了`interval`或`group by tags`的子句以后,在最后返回结果中会强制返回时间戳列(第一列)和 group by 子句中的标签列。后续的版本中可以支持关闭 group by 子句中隐式列的输出,列输出完全由 select 子句控制。 - ### 伪列 **TBNAME** @@ -155,6 +151,12 @@ taos> SELECT ts, ts AS primary_key_ts FROM d1001; SELECT DISTINCT TBNAME, location FROM meters; ``` +建议用户使用 INFORMATION_SCHEMA 下的 INS_TAGS 系统表来查询超级表的子表标签信息,例如获取超级表 meters 所有的子表名和标签值: + +```mysql +SELECT table_name, tag_name, tag_type, tag_value FROM information_schema.ins_tags WHERE stable_name='meters'; +``` + 统计超级表下辖子表数量: ```mysql From be2dcaad74ad597d9aa45c45241c9443afed20ae Mon Sep 17 00:00:00 2001 From: dingbo Date: Thu, 11 Aug 2022 17:21:48 +0800 Subject: [PATCH 13/14] docs: change images --- docs/en/02-intro/eco_system.webp | Bin 8968 -> 38010 bytes docs/zh/eco_system.webp | Bin 8968 -> 38010 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/en/02-intro/eco_system.webp b/docs/en/02-intro/eco_system.webp index d60c38e97c67fa7b2acc703b2ba777d19ae5be13..9bd12f5fd46d02cf4f0fff8e09c0241558dd72f6 100644 GIT binary patch literal 38010 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 diff --git a/docs/zh/eco_system.webp b/docs/zh/eco_system.webp index d60c38e97c67fa7b2acc703b2ba777d19ae5be13..9bd12f5fd46d02cf4f0fff8e09c0241558dd72f6 100644 GIT binary patch literal 38010 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 From 220e5571fcba288d0c4d6d44c79cc4a455cb447b Mon Sep 17 00:00:00 2001 From: wade zhang <95411902+gccgdb1234@users.noreply.github.com> Date: Thu, 11 Aug 2022 18:03:42 +0800 Subject: [PATCH 14/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3273a11460..74078eb1ab 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ TDengine is an open source, cloud native time-series database optimized for Inte # Documentation -For user manual, system design and architecture, engineering blogs, refer to [TDengine Documentation](https://docs.tdengine.com)(中文版请点击[这里](https://docs.taosdata.com)) +For user manual, system design and architecture, please refer to [TDengine Documentation](https://docs.tdengine.com) (中文版请点击[这里](https://docs.taosdata.com)) # Building