influxdb基礎那些事兒

InfluxDB是一個開源的時序數據庫,使用GO語言開發,特別適合用於處理和分析資源監控數據這種時序相關數據。而InfluxDB自帶的各種特殊函數如求標準差,隨機取樣數據,統計數據變化比等,使數據統計和實時分析變得十分方便。

influxdb的單機版是開源的,而集羣版是商業版,influxdb被設計運行在SSD上,如果使用機器或者網絡磁盤作爲存儲介質,會導致性能下降至少一個數量級。influxdb支持restful api,同時也支持https,爲了保證安全性,非局域網建議使用https與Influxdb進行通信。

influxdb基礎

infludb中存儲的是時間序列數據,比如說某個時間點系統負載、服務耗時等信息,時間序列數據可以包含多個值。關於什麼是時間序列數據,簡單來來說就是數據是和一個時間點關聯的,結合mysql中的記錄與id關係來看就是時間序列數據的主鍵就是時間點(timestrap)。

infludb中的一條數據至少包括measurement(對應mysql中表概念)、timestamp、至少一個k-v結構的field,再加上0個或者多個k-v結構的tag。對比mysql來看,measurement就是一張表,其主鍵是timestamp時間戳,tag和field對應就是表中列,tag和field都是k-v接口,k對應列的名字,v對應該列存儲的值,tag和field不同的是,tag是有索引的而field沒有(如果查詢條件爲tag則會掃描所有查詢到的數據),對於mysql表的有索引列和無索引列。注意mysql中的表需要提前定義結構,而influxdb中的measurement無需提前定義,其null值也不會被存儲。

influxdb中measurement無需定義,即無模式設計,開發者可以在任意添加measurement,tags和fields,不過針對同一個field,第二次和第一次寫入的數據類型不匹配,influxdb會報錯(由於默認tag的v都是字符串類型,所有不存在這個問題,不管輸入是什麼數據都當做字符串來處理)。

數據讀寫

influxdb數據寫入需滿足如下格式:

insert <measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>[,<field2-key>=<field2-value>...] [unix-nano-timestamp] 

注意:measurement和至少一個fileld的k-v是必須的,tag和timestrap時間戳是可選的。

說實話,這個寫入格式還是有點小嚴格的,因爲它要求measurement和可能的0個或多個tag之間必須是緊挨着的,中間不能有空格;同時多個filed之間也是不能有空格,tag和field的k,tag的v都是字符串類型;時間戳不是必須的,如果爲空則使用服務端的本地時間作爲時間戳。相同時間戳的數據第二次寫入會覆蓋第一次寫入的數據,相當於更新操作。

爲什麼至少有一個filed是必須的,而tag是可選的呢?

這是influxdb的存儲模型決定的,measurement+tag set+field key作爲key,field value作爲value,如果沒有field則沒有了對應的value了。

插入數據的tag key和field key能一樣麼?

數據插入沒問題,這是由於infludb底層存儲tag和field是在不同地方的,只不過爲了區分會加上_序號而已,如下圖:

當在use某個db之後,就可以執行數據讀寫操作,比如下面往名字爲cpu的MEASUREMENT(對應mysql中的表概念)中寫入如下數據:

insert cpu,host=s01,region=hangzhou value=0.64 1520052020000000000
命令說明:
- 插入數據對應的MEASUREMENT名字爲cpu;
- 數據tag分別是host和region,field是value;
- 數據的最後一項是時間戳(1520052020000000000),時間戳不是必須的,如果不傳則使用influxdb服務端本地時間戳,注意時間戳都是UTC時間

數據保留策略

Influxdb可支持每秒十萬級別的數據量,如果長時間保存會對存儲造成很大壓力,因此和一般數據存儲系統一樣有一個數據保留策略,同時針對大流量量數據可採樣保存,小流量數據可全量保存。influxdb通過保留策略(RP,Retention Policy)來管理過期數據,使用連續查詢(CR,Continuous Queries)來進行數據採樣。

  • RP:數據保留策略,過期數據會被清除,每個數據庫可擁有多種RP策略;
  • CQ:數據連續查詢,定時跑的一個查詢語句,比如週期性統計某個數據指標,查詢語句需要在select語句中使用並且包含group by time子句(這裏有點類似Flink中流數據處理的按時間窗口統計功能)。

默認寫數據不指定保留策略(RP,Retention Policy)時,默認使用influxdb默認的RP,名字叫做autogen的RP會永久保留數據。如果使用命令 create retention policy "default2" on "db2" duration 2h replication 1 default,執行該命令後default2會取代默認的autugen作爲db2數據庫的默認RP,默認influxdb會間隔半個小時執行一次RP操作。

比如有一個服務請求日誌measurement的名字爲log(RP策略是2小時,數據庫是db2),其中數據有服務耗時(字段對應名字time),我們想統計每分鐘平均服務耗時,然後將平均耗時數據寫入到名字爲log2的measurement(RP策略是2天),該如何做呢?

首先創建2小時和2天的RP策略:

create retention policy "tow_hour" on db2 duration 2h replication 1
# 對數據庫db2創建一個名字叫"tow_hour"的RP策略,數據保存2小時,由於最後沒有加default,所以數據讀寫如果沒有執行RP仍然使用的是influxdb默認的RP
create retention policy "tow_day" on db2 duration 2d replication 1
# 對數據庫db2創建一個名字叫"tow_day"的RP策略,注意對於單機版influxdb來說replication無意義

然後使用create continuous query創建CQ策略:

create continuous query "cq_avg_time" on db2 
begin 
    select mean("time") as "mean_time" into "tow_day"."log2" from log 
    group by time(1m) 
end

這樣就創建了一個名字叫cq_avg_time的CQ作用於db2數據庫,每1分鐘一次計算measurement爲log的time字段的平均值,然後寫入到另一個measurement爲log2中。

推薦閱讀

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章