相关文章:
时序数据库 InfluxDB(一)
时序数据库 InfluxDB(二)
时序数据库 InfluxDB(三)
时序数据库 InfluxDB(四)
时序数据库 InfluxDB(五)
时序数据库 InfluxDB(六)数据库
连续查询 Continuous Queries( CQ )是 InfluxDB 很重要的一项功能,它的做用是在 InfluxDB 数据库内部自动按期的执行查询,而后将查询结果存储到指定的 measurement 里。segmentfault
配置文件中的相关配置:函数
[continuous_queries] enabled = true log-enabled = true query-stats-enabled = false run-interval = "1s"
基本语法:spa
CREATE CONTINUOUS QUERY <cq_name> ON <database_name> BEGIN <cq_query> END
在某个数据库上建立一个 CQ ,而查询的具体内容 cq_query 的语法为:日志
SELECT <function[s]> INTO <destination_measurement> FROM <measurement> [WHERE <stuff>] GROUP BY time(<interval>)[,<tag_key[s]>]
定位一个 measurement 的完整格式是:code
<database>.<RP>.<measurement>
使用当前数据库和默认 RP 的状况就只须要 measurement 。flux
InfluxDB 支持的时长单位:rem
CQ 在什么时候执行取决于 CQ 建立完成的时间点、GROUP BY time() 设置的时间间隔、以及 InfluxDB 数据库预设的时间边界(这个预设的时间边界其实就是 1970.01.01 00:00:00 UTC 时间,对应 Unix timestamp 的 0 值)。get
假设我在 2019.11.05(北京时间)建立好了一个 GROUP BY time(30d) 的 CQ(也就是时间间隔为 30 天),那么这个 CQ 会在什么时间点执行? it
首先,2019.11.05 号转换为 timestamp 是 1572883200 秒;
再算1572883200 距离 0 值隔了多少个 30 天(一天是 86400 秒),1572883200/86400/30 = 606.8 ;
那么下一个 30 天就是 606.8 向上取整 607 ,6078640030 = 1573344000 ,转换为对应的日期就是 2019.11.10 号,这也就是第一次执行 CQ 的时间,以后每次执行就是日后推 30 天。
若是每次都这样算就很麻烦,但其实咱们更常使用的时间间隔没有那么长,一般都是秒、分钟、小时单位,这种状况下直接从 0 速算就能够了,好比:
连续查询会根据 GROUP BY time() 的时间间隔肯定做用的数据,每次执行所针对的数据的时间范围是 [ now() - GROUP BY time() ,now() ) 。
例如,GROUP BY time(1h) :
你可使用 WHERE 去过滤数据,可是 WHERE 里指定的时间范围会被忽略掉。
CQ 会将执行结果存储到指定的 measurement ,可是存储的具体字段有哪些呢?首先 time 是必不可少的,time 写入的是 CQ 执行时数据范围的开始时间点;其次就是 function 的处理结果,若是只有单一字段,那么 field key 就是 function 的名称,若是有多个字段,那么 field key 就是 function 名称_做用字段。
例如,GROUP BY time(30m) ,UTC 7:30 执行:
单一字段:
SELECT mean("field") INTO "result_measurement" FROM "source_measurement" GROUP BY time(30m)
CQ 结果:
time mean 2019-11-05T07:00:00Z 7
多字段:
SELECT mean("*") INTO "result_measurement" FROM "source_measurement" GROUP BY time(30m)
CQ 结果:
time mean_field1 mean_field2 2019-11-05T07:00:00Z 7 6.5
这里的 mean 对应的是 function 里的平均值函数。
GROUP BY time() 的完整格式是:
GROUP BY time(<interval>[,<offset_interval>])
第二个参数 offset_interval 偏移量是可选的,这个偏移量会对 CQ 的执行时间和数据范围产生影响。
若是 GROUP BY time(1h) ,在 8:00 执行,数据范围是 [ 7:00 , 8:00 ) 。
那么 GROUP BY time(1h, 15m) 会使 CQ 的执行时间向后推迟 15m ,即在 8:15 执行,数据范围也就变成了 [ 7:15 , 8:15 ) 。
高级语法:
CREATE CONTINUOUS QUERY <cq_name> ON <database_name> RESAMPLE EVERY <interval> FOR <interval> BEGIN <cq_query> END
与基本语法不一样的是,高级语法多了
RESAMPLE EVERY <interval> FOR <interval>
EVERY 定义了 CQ 执行的间隔:
RESAMPLE EVERY 30m
意思就是每隔 30m 执行一次 CQ 。
示例:
CREATE CONTINUOUS QUERY "cq_every" ON "db" RESAMPLE EVERY 30m BEGIN SELECT mean("field") INTO "result_measurement" FROM "source_measurement" GROUP BY time(1h) END
若是没有 RESAMPLE EVERY 30m ,只有 GROUP BY time(1h) 将会:
增长了 RESAMPLE EVERY 30m 以后,每 30m 执行一次 CQ :
当 EVERY 的时间间隔小于 GROUP BY time() 时,会增长 CQ 的执行频率(如上述示例)。
当 EVERY 与 GROUP BY time() 的时间间隔一致时,无影响。
当 EVERY 的时间间隔大于 GROUP BY time() 时,CQ 执行时间和数据范围彻底由 EVERY 控制,例如 EVERY 30m ,GROUP BY time(10m) :
FOR 定义了数据的时间范围:
RESAMPLE FOR 1h
意思就是每次 CQ 的数据的时间范围是 1h 。
示例:
CREATE CONTINUOUS QUERY "cq_for" ON "db" RESAMPLE FOR 1h BEGIN SELECT mean("field") INTO "result_measurement" FROM "source_measurement" GROUP BY time(30m) END
若是没有 RESAMPLE FOR 1h ,只有 GROUP BY time(30m) 将会:
增长了 RESAMPLE FOR 1h 以后,每次 CQ 的时间范围是 1h ,可是由于 GROUP BY time(30m) ,每次 CQ 将会按照 30m 写入两点数据:
当 FOR 的时间间隔大于 GROUP BY time() 时,每次 CQ 的时间范围被扩大,可是每个点仍然按照 GROUP BY time() 的时间间隔,所以每次 CQ 会写入多个点(如上述示例)。
当 FOR 与 GROUP BY time() 的时间间隔一致时,无影响。
当 FOR 的时间间隔小于 GROUP BY time() 时,建立 CQ 时报错,不容许这种状况。
EVERY 和 FOR 能够一块儿使用。
示例:
CREATE CONTINUOUS QUERY "cq_every_for" ON "db" RESAMPLE EVERY 1h FOR 90m BEGIN SELECT mean("field") INTO "result_measurement" FROM "source_measurement" GROUP BY time(30m) END
EVERY 1h 大于 GROUP BY time(30m),所以 CQ 每隔 1h 执行一次;FOR 90m ,每次 CQ 执行的时间范围是 90m,按照 30m 拆分红三个点:
最后,CQ 只能建立和删除,没法修改。
我的公众号持续输出原创文章,有兴趣的能够关注下。