時序數據庫 InfluxDB(一)
數據庫種類有很多,比如傳統的關系型數據庫 RDBMS( 如 MySQL ),NoSQL 數據庫( 如 MongoDB ),Key-Value 類型( 如 redis ),Wide column 類型( 如 HBase )等等等等,當然還有本系列文章將會介紹的時序數據庫 TSDB( 如 InfluxDB )。
時序數據庫 TSDB
不同的數據庫針對的應用場景有不同的偏重。TSDB( time series database )時序數據庫是專門以時間維度進行設計和優化的。
TSDB 通常具有以下的特點:
- 時間是不可或缺的絕對主角(就像 MySQL 中的主鍵一樣),數據按照時間順序組織管理
- 高并發高吞吐量的數據寫入
- 數據的更新很少發生
- 過期的數據可以批量刪除
InfluxDB 就是一款非常優秀的時序數據庫,高居 DB-Engines TSDB rank 榜首。
InfluxDB 分為免費的社區開源版本,以及需要收費的閉源商業版本,目前只有商業版本支持集群。
InfluxDB 的底層數據結構從 LSM 樹到 B+ 樹折騰了一通,最后自創了一個 TSM 樹( Time-Structured Merge Tree ),這也是它性能高且資源占用少的重要原因。
InfluxDB 由 go 語言編寫而成,沒有額外的依賴,它的查詢語言 InfluxQL 與 SQL 極其相似,使用特別簡單。
InfluxDB 基本概念
InfluxDB 有以下幾個核心概念:
1、database :
數據庫。
2、measurement
類似于表。
3、retention policy( 簡稱 RP )
保留策略,由以下三個部分構成:
- DURATION:數據的保留時長。
- REPLICATION:集群模式下數據的副本數,單節點無效。
- SHARD DURATION:可選項,shard group 劃分的時間范圍。
4、timestamp
時間戳,就像是所有數據的主鍵一樣。
5、tag
tag key = tag value 鍵值對存儲具體的數據,會構建索引有利于查詢。tag set 就是 tag key-value 鍵值對的不同組合。
6、field
field key = field value 鍵值對也是存儲具體的數據,但不會被索引。類似的 field set 就是 field key-value 的組合。
7、series
一個 series 序列是由同一個 RP 策略下的同一個 measurement 里的同一個 tag set 構成的數據集合。
8、point
一個 point 點代表了一條數據,由 measurement、tag set、field set、timestamp 組成。一個 series 上的某個 timestamp 時間對應唯一一個 point 。
Line protocol 行協議
行協議指定了寫入數據的格式:
<measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>[,<field2-key>=<field2-value>...] [unix-nano-timestamp]
符號 [] 代表可選項,符號 … 代表可以有多個,符號 ,用來分隔相同 tag 或者 field 下的多個數據,符號空格分隔 tag、field、timestamp 。
示例:
怎么去理解 series 和 point ?先看下圖:
這張圖選取了三種時序數據庫的歷年排名得分情況。首先,整個圖表可以看成是一個 measurement ,它包含了許多數據;然后我們根據 db 名稱構建 tag ,把 score 排名得分作為 field ,那么所有數據行就類似于:
measurement,db=InfluxDB score=5 timestamp
measurement,db=Kdb+ score=1 timestamp
measurement,db=Prometheus score=0.2 timestamp
...
上文說過 tag set 就是 tag key = tag value 的不同組合,因此這里的 tag set 有以下三種:
db=InfluxDB
db=Kdb+
db=Prometheus
三個 tag set 構成了三個 series ,每個 series 就可以看成是圖中的一條線(一個維度),而每個 point 點就是 series 上具體某個 timestamp 對應的點。
與傳統數據庫的不同
InfluxDB 就是被設計用于處理時間序列的數據。傳統SQL數據庫雖然也可以處理時間序列數據,但并不是專門以此為目標的。InfluxDB 可以更加高效快速的存儲大量時間序列數據并對這些數據進行實時分析。
在 InfluxDB 中,時間是絕對的主角,就像是SQL數據庫中的主鍵一樣,如果你不指定則會默認為系統當前時間,時間必須是 UNIX epoch ( GMT ) 或者 RFC3339 格式。
InfluxDB 不需要預先定義好數據的結構,你可以隨時改變你的數據結構。InfluxDB 支持 continuous queries(連續查詢,就是以時間劃分范圍自動定期執行某個查詢)和 retention policies(保留策略)。InfluxDB 不支持跨 measurement 的 JOIN 查詢。
InfluxDB 中的查詢語言叫 InfluxQL ,語法與 SQL 極其相似,就是 select from where 那一套。
InfluxDB 并不是 CRUD,更像是 CR-ud ,意思就是更新和刪除數據跟傳統SQL數據庫明顯不一樣:
- 更新某個 point 數據,只需向原來的 measurement,tag set,timestamp 重寫數據即可。
- 你可以刪除 series ,但是不能基于 field 值去刪除獨立的 points ,解決方法是,你需要先查詢 field 值的時間戳,然后根據時間戳去刪除。
- 無法更新或重命名 tags ,因為 tags 會構建索引,你只能創建新的 tags 并導入數據然后刪除老的。
- 無法通過 tag key 或者 tag value 去刪除 tags 。
設計與權衡之道
InfluxDB 為了更高的性能做了一些設計與權衡之道:
1、對于時間序列用例,即使相同的數據被發送多次也會被認為是同一筆數據。
- 優點:簡化了沖突,提高了寫入性能。
- 缺點:不能存儲重復數據,可能會在極少數情況下覆蓋數據。
2、刪除是罕見的,當它們發生時肯定是針對大量的舊數據。
- 優點:提高了讀寫性能。
- 缺點:刪除功能受到了很大限制。
3、更新是罕見的,持續或者大批量的更新不會發生。時間序列的數據主要是永遠也不會更新的新數據。
- 優點:提高了讀寫性能。
- 缺點:更新功能受到了很大限制。
4、絕大多數寫入都是接近當前時間戳的數據,并且是按時間遞增順序添加。
- 優點:按時間遞增的順序寫入數據更高效。
- 缺點:隨機時間寫入的性能要低很多。
5、數據規模至關重要,數據庫必須能夠處理大量的讀寫。
- 優點:數據庫可以處理大批量數據的讀寫。
- 缺點:被迫做出的一些權衡去提高性能。
6、能夠寫入和查詢數據比具有強一致性更重要。
- 優點:多個客戶端可以在高負載的情況下完成查詢和寫入操作。
- 缺點:如果負載過高,查詢結果可能不包含最近的點。
7、許多時間序列都是短暫的。時間序列可能只有幾個小時然后就沒了,比如一臺新的主機開機,監控數據寫入一段時間,然后關機了。
- 優點:InfluxDB 善于管理不連續的數據。
- 缺點:無模式設計意味著不支持某些數據庫功能,例如沒有 join 交叉表連接。
8、No one point is too important 。
- 優點:InfluxDB 具有非常強大的工具去處理聚合數據和大數據集。
- 缺點:Points 數據點沒有傳統意義上的 ID ,它們被時間戳和 series 區分。