基於 Go 語言開發,社區非常活躍,項目更新速度很快,日新月異,關注度高
測試版本
1.0.0_beta2-1
安裝部署
wget https://dl.influxdata.com/influxdb/releases/influxdb-1.0.0_beta2.x86_64.rpm sudo yum localinstall influxdb-1.0.0_beta2.x86_64.rpm
配置文件路徑為 /etc/influxdb/influxdb.conf,修改后啟動服務
sudo service influxdb start
特點
- 可以設置metric的保存時間。
- 支持通過條件過濾以及正則表達式刪除數據。
- 支持類似 sql 的語法。
- 可以設置數據在集群中的副本數。
- 支持定期采樣數據,寫入另外的measurement,方便分粒度存儲數據
概念
數據格式 Line Protocol
weather,location=us-midwest temperature=82 1465839830100400200
| -------------------- -------------- |
| | | |
| | | |
+-----------+--------+-+---------+-+---------+
|measurement|,tag_set| |field_set| |timestamp|
+-----------+--------+-+---------+-+---------+
cpu_load,host_id=1 value=0.1 1434055562000000000
相比於 JSON 格式,無需序列化,更加高效。
- measurement: metric name,例如 cpu_load。
- field-key, field-value: 通常用來存儲數據,類似 opentsdb 中的 value=0.6,但是支持各種類型(4種類型),數據存儲時不會進行索引,每條數據必須擁有一個 field-key,如果使用 field-key 進行過濾,需要遍歷一遍所有數據。
- tags-key, tags-value: 和 field-key 類似,但是會進行索引,方便查詢時用於過濾條件。
Series
measurement, tag set, retention policy 相同的數據集合算做一個 series。
假設 cpu_load 有兩個 tags,host_id 和 name,host_id 的數量為 100,name 的數量為 200,則 series 基數為 100 * 200 = 20000。
數據存儲
measurements, tag keys, field keys,tag values 全局存一份。
field values 和 timestamps 每條數據存一份
Retention Policy
保留策略包括設置數據保存的時間以及在集群中的副本個數。
默認的 RP 為 default,保存時間不限制,副本個數為 1,默認 RP 是可以修改的,並且我們可以創建新的 RP。
Continuous Query
CQ 是預先配置好的一些查詢命令,SELECT 語句必須包含 GROUP BY time(),influxdb 會定期自動執行這些命令並將查詢結果寫入指定的另外的 measurement 中。
利用這個特性並結合 RP 我們可以方便地保存不同粒度的數據,根據數據粒度的不同設置不同的保存時間,這樣不僅節約了存儲空間,而且加速了時間間隔較長的數據查詢效率,避免查詢時再進行聚合計算。
Shard
Shard 這個概念並不對普通用戶開放,實際上是 InfluxDB 將連續一段時間內的數據作為一個 shard 存儲,根據數據保存策略來決定,通常是保存1天或者7天的數據。例如如果保存策略 RP 是無限制的話,shard 將會保存7天的數據。這樣方便之后的刪除操作,直接關閉下層對應的一個數據庫即可
存儲引擎
從 LevelDB(LSM Tree),到 BoltDB(mmap B+樹),現在是自己實現的 TSM Tree 的算法,類似 LSM Tree,針對 InfluxDB 的使用做了特殊優化。
LevelDB
LevelDB 底層使用了 LSM Tree 作為數據結構,用於存儲大量的 key 值有序的 K-V 數據,鑒於時序數據的特點,只要將時間戳放入 key 中,就可以非常快速的遍歷指定時間范圍內的數據。LSM Tree 將大量隨機寫變成順序寫,所以擁有很高的寫吞吐量,並且 LevelDB 內置了壓縮功能。
數據操作被先順序寫入 WAL 日志中,成功之后寫入內存中的 MemTable,當 MemTable 中的數據量達到一定閥值后,會轉換為 Immutable MemTable,只讀,之后寫入 SSTable。SSTable 是磁盤上只讀的用於存儲有序鍵值對的文件,並且會持續進行合並,生成新的 SSTable。在 LevelDB 中是分了不同層級的 SSTable 用於存儲數據。
LevelDB 不支持熱備份,它的變種 RocksDB 和 HyperLevelDB 實現了這個功能。
最嚴重的問題是由於 InfluxDB 通過 shard 來組織數據,每一個 shard 對應的就是一個 LevelDB 數據庫,而由於 LevelDB 的底層存儲是大量 SSTable 文件,所以當用戶需要存儲長時間的數據,例如幾個月或者一年的時候,會產生大量的 shard,從而消耗大量文件描述符,將系統資源耗盡。
BoltDB
之后 InfluxDB 采用了 BoltDB 作為數據存儲引擎。BoltDB 是基於 LMDB 使用 Go 語言開發的數據庫。同 LevelDB 類似的是,都可以用於存儲 key 有序的 K-V 數據。
雖然采用 BoltDB 的寫效率有所下降,但是考慮到用於生產環境需要更高的穩定性,BoltDB 是一個合適的選擇,而且 BoltDB 使用純 Go 編寫,更易於跨平台編譯部署。
最重要的是 BoltDB 的一個數據庫存儲只使用一個單獨的文件。Bolt 還解決了熱備的問題,很容易將一個 shard 從一台機器轉移到另外一台。
但是當數據庫容量達到數GB級別時,同時往大量 series 中寫入數據,相當於是大量隨機寫,會造成 IOPS 上升。
TSM Tree
TSM Tree 是 InfluxDB 根據實際需求在 LSM Tree 的基礎上稍作修改優化而來。
WAL
每一個 shard 對應底層的一個數據庫。每一個數據庫有自己的 WAL 文件,壓縮后的元數據文件,索引文件。
WAL 文件名類似 _000001.wal,數字遞增,每達到 2MB 時,會關閉此文件並創建新的文件,有一個寫鎖用於處理多協程並發寫入的問題。
可以指定將 WAL 從內存刷新到磁盤上的時間,例如30s,這樣會提高寫入性能,同時有可能會丟失這30s內的數據。
每一個 WAL 中的條目遵循 TLV 的格式,1字節用於表示類型(points,new fields,new series,delete),4字節表示 block 的長度,后面則是具體壓縮后的 block 內容。WAL 文件中得內容在內存中會進行緩存,並且不會壓縮,每一個 point 的 key 為 measurement, tagset 以及 unique field,每一個 field 按照自己的時間順序排列。
查詢操作將會去 WAL 以及索引中查詢,WAL 在內存中緩存有一個讀寫鎖進行控制。刪除操作會將緩存中的key刪除,同時在 WAL 文件中進行記錄並且在內存的索引中進行刪除標記。
Data Files(SSTables)
這部分 InfluxDB 自己定義了特定的數據結構,將時間戳編碼到了 DataFiles 中,進行了相對於時間序列數據的優化。
API
通過 HTTP 訪問 influxdb。
語法上是一種類似於 SQL 的命令,官方稱為 InfluxQL。
創建數據庫
curl -POST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE mydb"
插入數據
curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'
cpu_load_short 是 measurement,host 和 region 是 tags-key,value 是 field-key。
多條數據時,用換行區分每條數據
curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server02 value=0.67 cpu_load_short,host=server02,region=us-west value=0.55 1422568543702900257 cpu_load_short,direction=in,host=server01,region=us-west value=2.0 1422568543702900257'
讀取數據
curl -GET 'http://localhost:8086/query' --data-urlencode "db=mydb" --data-urlencode "epoch=s" --data-urlencode "q=SELECT value FROM cpu_load_short WHERE region='us-west'"
同時查詢多條數據時,以分號分隔
curl -G 'http://localhost:8086/query' --data-urlencode "db=mydb" --data-urlencode "epoch=s" --data-urlencode "q=SELECT value FROM cpu_load_short WHERE region='us-west';SELECT count(value) FROM cpu_load_short WHERE region='us-west'"
這里 --data-urlencode "epoch=s" 會使返回的時間戳為 unix 時間戳格式
創建 RP
CREATE RETENTION POLICY two_hours ON food_data DURATION 2h REPLICATION 1 DEFAULT
這里將 two_hours 設置成了默認保存策略,存入 food_data 中的數據如果沒有明確指定 RP 將會默認采用此策略,數據保存時間為 2 小時,副本數為 1。
創建 CQ
CREATE CONTINUOUS QUERY cq_5m ON food_data BEGIN SELECT mean(website) AS mean_website,mean(phone) AS mean_phone INTO food_data."default".downsampled_orders FROM orders GROUP BY time(5m) END
這里創建了一個 CQ,每個5分鍾將 two_hours.orders 中的數據計算5分鍾的平均值后存入 default.downsampled_orders 中,default 這個 RP 中的數據是永久保存的
WHERE
查詢時指定查詢的限制條件,例如查詢最近1小時內 host_id=1 的機器的 cpu 數據。
SELECT value FROM cpu_load WHERE time > now() - 1h and host_id = 1
GROUP BY
類似於 SQL 中的語法,可以對細粒度數據進行聚合計算,例如查詢最近1小時內 host_id=1 的機器的 cpu 的數據,並且采樣為每5分鍾的平均值
SELECT mean(value) FROM cpu_load WHERE time > now() - 1h and host_id = 1 GROUP BY time(5m)
官方推薦硬件配置
單節點
| Load | Writes per second | Queries per second | Unique series |
|---|---|---|---|
| Low | < 5 thousand | < 5 | < 100 thousand |
| Moderate | < 100 thousand | < 25 | < 1 million |
| High | > 100 thousand | > 25 | > 1 million |
| Probably infeasible | > 500 thousand | > 100 | > 10 million |
- Low: CPU 2-4, RAM 2-4GB, IOPS 500
- Moderate: CPU 4-6, RAM 8-32GB, IOPS 500-1000
- High: CPU CPU 8+, RAM 32GB+, IOPS 1000+
- Probably infeasible: 可能單機無法支持,需要集群環境
集群
InfluxDB 從 0.12 版本開始將不再開源其 cluster 源碼,而是被用做提供商業服務。
如果考慮到以后的擴展,需要自己在前端做代理分片或者類似的開發工作。
已知七牛是采用了 InfluxDB 作為時間序列數據的存儲,自研了調度器以及高可用模塊,具有橫向擴展的能力。
總結
目前最火熱的時間序列數據庫項目,社區開發活躍,迭代更新較快,存儲引擎經常變化,網上的一些資料都比較過時,例如最新的 TSM 存儲引擎只能看到官方的文檔簡介,還沒有詳細的原理說明的文章。
就單機來說,在磁盤占用、cpu使用率、讀寫速度方面都讓人眼前一亮。如果數據量級不是非常大的情況下,單節點的 InfluxDB 就可以承載數十萬每秒的寫入,是一個比較合適的選擇。
另一方面,從 0.12 版本開始不再開源其集群代碼(雖然之前的集群部分就比較爛),如果考慮到之后進行擴展的話,需要進行二次開發
作者:fatedier 本文出處:http://blog.fatedier.com/2016/07/05/research-of-time-series-database-influxdb/ 文章版權歸本人所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則保留追究法律責任的權利
