時序數據庫 InfluxDB(六)

相關文章:
時序數據庫 InfluxDB(一)
時序數據庫 InfluxDB(二)
時序數據庫 InfluxDB(三)
時序數據庫 InfluxDB(四)
時序數據庫 InfluxDB(五)
時序數據庫 InfluxDB(六)數據庫


CQ 連續查詢


連續查詢 Continuous Queries( CQ )是 InfluxDB 很重要的一項功能,它的做用是在 InfluxDB 數據庫內部自動按期的執行查詢,而後將查詢結果存儲到指定的 measurement 裏。segmentfault

配置文件中的相關配置:函數

[continuous_queries]
  enabled = true
  log-enabled = true
  query-stats-enabled = false
  run-interval = "1s"
  • enabled = true :開啓CQ
  • log-enabled = true :輸出 CQ 日誌
  • query-stats-enabled = false :關閉 CQ 執行相關的監控,不會將統計數據寫入默認的監控數據庫 _internal
  • run-interval = "1s" :InfluxDB 每隔 1s 檢查是否有 CQ 須要執行

基本語法


一 、

基本語法: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]>]
  • SELECT function[s] : 連續查詢並不僅是簡單的查詢原始數據,而是基於原始數據進行聚合、特選、轉換、預測等處理,因此 CQ 必需要有一個或多個數據處理函數。
  • INTO <destination_measurement> : 將 CQ 的結果存儲到指定的 measurement 中。
  • FROM <measurement> : 原始數據的來源 measurement 。
  • [WHERE <stuff>] : 可選項,原始數據的篩選條件。
  • GROUP BY time(<interval>)[,<tag_key[s]>] : 連續查詢不是查一次就完了,而是每次查詢指定時間範圍內的數據,不斷週期性的執行下去。

定位一個 measurement 的完整格式是:code

<database>.<RP>.<measurement>

使用當前數據庫和默認 RP 的狀況就只須要 measurement 。flux

InfluxDB 支持的時長單位:rem

  • ns : 納秒
  • u / µ : 微秒
  • ms : 毫秒
  • s : 秒
  • m : 分鐘
  • h : 小時
  • d : 天
  • w : 周

2、

一、CQ 在什麼時候執行?

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 速算就能夠了,好比:

  • 在時間點 16:09:35 建立了 CQ ,GROUP BY time(30s) ,那麼 CQ 的執行時間就是 16:10:00、16:10:30、16:11:00 以此類推(從 0s 開始速算)。
  • 在時間點 16:16:08 建立了 CQ ,GROUP BY time(5m) ,那麼 CQ 的執行時間就是 16:20:00、16:25:00、16:30:00 以此類推(從 0m 開始速算)。
  • 在時間點 16:38:27 建立了 CQ ,GROUP BY time(2h) ,那麼 CQ 的執行時間就是 18:00:00 、20:00:00 、22:00:00 以此類推(從 0h 開始速算)。
二、CQ 執行的數據範圍?

連續查詢會根據 GROUP BY time() 的時間間隔肯定做用的數據,每次執行所針對的數據的時間範圍是 [ now() - GROUP BY time() ,now() ) 。

例如,GROUP BY time(1h) :

  • 在 8:00 執行時,數據是時間大於等於 7:00,小於 8:00,即 [ 7:00 , 8:00 ) 範圍內的數據。
  • 在 9:00 執行時,數據是時間大於等於 8:00,小於 9:00,即 [ 8:00 , 9:00 ) 範圍內的數據。

你可使用 WHERE 去過濾數據,可是 WHERE 裏指定的時間範圍會被忽略掉。

三、CQ 的執行結果?

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 裏的平均值函數。

3、

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>

一、RESAMPLE EVERY

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) 將會:

  • 在 8:00 執行 CQ ,數據範圍是 [ 7:00 , 8:00 )
  • 在 9:00 執行 CQ ,數據範圍是 [ 8:00 , 9:00 )

增長了 RESAMPLE EVERY 30m 以後,每 30m 執行一次 CQ :

  • 在 8:00 執行 CQ ,數據範圍是 [ 7:00 , 8:00 )
  • 在 8:30 執行 CQ ,數據範圍是 [ 8:00 , 9:00 )
  • 在 9:00 執行 CQ ,數據範圍是 [ 8:00 , 9:00 ) ,因爲執行結果的 time 字段是 8:00 與上一次 CQ 一致,所以會覆蓋上一次 CQ 的結果。

當 EVERY 的時間間隔小於 GROUP BY time() 時,會增長 CQ 的執行頻率(如上述示例)。

當 EVERY 與 GROUP BY time() 的時間間隔一致時,無影響。

當 EVERY 的時間間隔大於 GROUP BY time() 時,CQ 執行時間和數據範圍徹底由 EVERY 控制,例如 EVERY 30m ,GROUP BY time(10m) :

  • 在 8:00 執行 CQ ,數據範圍是 [ 7:30 , 8:00 )
  • 在 8:30 執行 CQ ,數據範圍是 [ 8:00 , 8:30 )

二、RESAMPLE FOR

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) 將會:

  • 在 8:00 執行 CQ ,數據範圍是 [ 7:30 , 8:00 )
  • 在 8:30 執行 CQ ,數據範圍是 [ 8:00 , 8:30 )

增長了 RESAMPLE FOR 1h 以後,每次 CQ 的時間範圍是 1h ,可是由於 GROUP BY time(30m) ,每次 CQ 將會按照 30m 寫入兩點數據:

  • 在 8:00 執行 CQ ,數據總範圍是 [ 7:00 , 8:00 ) ,實際會拆分紅兩點 [ 7:00 , 7:30 ) 和 [ 7:30 , 8:00 )
  • 在 8:30 執行 CQ ,數據總範圍是 [ 7:30 , 8:30 ) ,實際會拆分紅兩點 [ 7:30 , 8:00 ) 和 [ 8:00 , 8:30 )

當 FOR 的時間間隔大於 GROUP BY time() 時,每次 CQ 的時間範圍被擴大,可是每個點仍然按照 GROUP BY time() 的時間間隔,所以每次 CQ 會寫入多個點(如上述示例)。

當 FOR 與 GROUP BY time() 的時間間隔一致時,無影響。

當 FOR 的時間間隔小於 GROUP BY time() 時,建立 CQ 時報錯,不容許這種狀況。

三、EVERY ... FOR

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 拆分紅三個點:

  • 在 8:00 執行 CQ ,數據總範圍 [ 6:30 , 8:00 ) ,實際會拆分爲三個點 [ 6:30 , 7:00 )、 [ 7:00 , 7:30 )、 [ 7:30 , 8:00 )
  • 在 9:00 執行 CQ ,數據總範圍 [ 7:30 , 9:00 ) ,實際會拆分爲三個點 [ 7:30 , 8:00 )、 [ 8:00 , 8:30 )、 [ 8:30 , 9:00 )

最後,CQ 只能建立和刪除,沒法修改。

我的公衆號持續輸出原創文章,有興趣的能夠關注下。
qrcode_for_gh_9ccbe5e0dfb3_258.jpg

相關文章
相關標籤/搜索