這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
前言
Influxdb是一個基於golang編寫,沒有額外依賴的開源時序資料庫,用於記錄metrics、events,進行資料分析。這篇文章談論的influxdb版本在1.2.0以上。這篇文章只談論influxdb在監控中的資料存放區應用,不會談論influxdb提供的整套監控方案。本文主要談論五個方面:時序資料庫選型、influxdb基本概念、儲存引擎、實踐、資料彙總。
選型
Influxdb vs Prometheus
influxdb整合已有的概念,比如查詢文法類似sql,引擎從LSM最佳化而來,學習成本相對低。
influxdb支援的類型有float,integers,strings,booleans,prometheus目前只支援float。
influxdb的時間精度是納秒,prometheus的則是毫秒。
influxdb僅僅是個資料庫,而prometheus提供的是整套監控解決方案,當然influxdb也提供了整套監控解決方案。
influxdb支援的math function比較少,prometheus相對來說更多,influxdb就目前使用上已經滿足功能。
2015年prometheus還在開發階段,相對來說influxdb更加穩定。
influxdb支援event log,prometheus不支援。
更詳細的對比請參考:對比。
我們其實僅僅需要的是一個資料庫,其他組件都是自己開發的,而且儲存的資料類型不僅僅是數字,因此選擇了influxdb。希望上面的比較對大家有協助。
Influxdb基本概念
Database
資料庫是個邏輯容器,包含了measurement、retention policies、continuous queries、time series data,類似於mysql的database。
Measurement
描述了相關資料的儲存結構,類似於mysql的table,但是不需要建立,寫入資料的時候自動建立。關於schema的設計建議參考:設計建議。
Line Protocol
Line Protocol定義了influxdb的資料寫入格式,如下:
weather,location=us,server=host1 temperature=82 1465839830100400200 | -------------------- -------------- | | | | | | | | |+-----------+--------+-+---------+-+---------+|measurement_name|,tag_set| |field_set| |timestamp|+-----------+--------+-+---------+-+---------+
Tag
上面的location和server就是tag key,us和host1是tag value,tag是可選的。不過寫入資料時最好加上tag,因為它可以被索引。tag的類型只能是字串。
Field
上面的temperature是field key,82是field value。field value會用於展示,value支援的類型有floats,integers,strings,booleans。
Timestamp
格式是:RFC3339 UTC。預設精確到納秒,可選。
Series
measurement, tag set, retention policy相同的資料集合算做一個 series。理解這個概念至關重要,因為這些資料存放區在記憶體中,如果series太多,會導致OOM。
Retention Policy
保留原則包括設定資料儲存的時間以及在叢集中的副本個數。預設配置是:RP是autogen,保留時間是永久,副本為1。這些配置在建立資料庫時可以修改。
Continuous Query
CQ是預先配置好的一些查詢命令,定期自動執行這些命令並將查詢結果寫入指定的measurement中,這個功能主要用於資料彙總。具體參考:CQ。
Shard
儲存一定時間間隔的資料,每個目錄對應一個shard,目錄的名字就是shard id。每一個shard都有自己的cache、wal、tsm file以及compactor,目的就是通過時間來快速定位到要查詢資料的相關資源,加速查詢的過程,並且也讓之後的大量刪除資料的操作變得非常簡單且高效。
儲存引擎
概述
TSM Tree是在LSM Tree的基礎上稍作修改最佳化而來。它主要包含四個部分:cache、wal、tsm file、compactor。
Cache
插入資料時,先往cache中寫入再寫入wal中,可以認為cache是wal檔案中的資料在記憶體中的緩衝。
WAL
預寫記錄檔,對比mysql的binlog。其作用就是為了持久化資料,當系統崩潰後可以通過wal檔案恢複cache。
TSM File
每個tsm檔案的大小上限是2GB。當達到cache-snapshot-memory-size
,cache-max-memory-size
的限制時會觸發將cache寫入tsm檔案。
Compactor
主要進行兩種操作,一種是cache資料達到閥值後,進行快照,產生一個新的tsm檔案。另外一種就是合并當前的tsm檔案,將多個小的tsm檔案合并成一個,減少檔案的數量,並且進行一些資料刪除操作。 這些操作都在後台自動完成。
目錄結構
InfluxDB的資料存放區有三個目錄,分別是meta、wal、data。meta用於儲存資料庫的一些中繼資料,meta目錄下有一個meta.db檔案。wal目錄存放預寫記錄檔檔案,以.wal結尾。data目錄存放實際儲存的資料檔案,以.tsm結尾。基本結構如下:
-- wal -- test -- autogen -- 1 -- _00001.wal -- 2 -- _00002.wal-- data -- test -- autogen -- 1 -- 000000001-000000001.tsm -- 2 -- 000000001-000000010.tsm-- meta -- meta.db
其中 test是資料庫名稱,autogen是儲存策略名稱,再下一層目錄中的以數字命名的目錄是 shard 的 ID 值,比如 autogen儲存策略下有兩個 shard,ID 分別為 1 和 2,shard儲存了某一個時間段範圍內的資料。再下一級的目錄則為具體的檔案,分別是 .wal
和 .tsm
結尾的檔案。
更詳細的參考
InfluxDB詳解之TSM儲存引擎解析
實踐
項目介紹
gateway用於檢測和壓縮influxdb的資料,用於跨機房傳輸,採用udp接受資料。
influxdb-relay是官方提供的高可用方案,但是它只提供簡單的寫入功能。
influxdb-proxy是用於替代influxdb-relay的高可用方案。
前期架構圖
使用問題
influxdb-relay是官方提供的高可用方案,但是它只提供簡單的寫入功能。在初期使用時,並沒有多大的問題,隨著influxdb在公司的推廣,接入方越來越多,意味著查詢方越來越多,這就帶來了以下問題:
grafana需要配置很多個資料來源。
使用者不能根據measurement來訂閱資料。
資料庫掛掉,就需要修改grafana的資料來源。
維護困難,比如需要新增資料庫,使用者需要配置多個資料來源,不能統一存取點。
使用者查詢直連資料庫,使用者select *
資料庫直接OOM,資料庫會重啟。
relay提供的重寫功能,資料是保留在記憶體中,一旦influxdb掛掉,就會導致relay機器記憶體瘋漲。
踩過的坑
max-row-limit
不為0,會導致influxdb OOM。目前這個問題已經修複,但是grafana展示時會存在問題,配置時請設定為0。
配置查詢限制參數時,會導致一些奇怪的問題,官方是不限制,請保留預設配置。
沒有制定schema規範,接入方把field寫成tag了,導致記憶體瘋漲,最後OOM。理解series的概念很重要。
寫入逾時時間預設是10s,有時候資料寫入了但返回500。可以將這個時間設定成大點。
最佳化後的架構圖
influxdb-proxy是為瞭解決上面的使用問題而開發出來的。具有以下功能:
同時支援寫和查詢功能,統一存取點,類似cluster。
支援重寫功能,寫入失敗時寫入檔案,後端恢複時再寫入。
限制部分查詢命令和全部刪除操作。
以measurement為粒度區分資料,支援按需訂閱。
measurement優先精確匹配,然後首碼匹配。
提供資料統計,比如qps,耗時等等。
資料彙總
CQ
influxdb提供資料彙總的功能,就是上面基本概念裡提到的Continuous Query。預先定義好cq,就可以定期根據不同的tag進行彙總資料。目前它有個設計問題:cq是順序執行的,cq越多,資料延遲越高,一般延遲在幾分鐘內。如果需要更即時的彙總,cq不能滿足,需要引入其他工具,比如spark。關於cq的文法請參考:文法。
Spark
經過內部調研,發現spark+kafka是個更好的彙總方案。spark支援串流且支援sql功能,我們只需要將cq改成sql就行。目前這個處於嘗試階段,已經上線部分功能。目前的處理流程如下:
總結
上文講的整套架構已經支撐起餓了麼2萬台機器的監控,目前每秒寫入的點數是300k。後端influxdb的機器數量是20台左右,維護成本基本趨於零。我們的焦點目前已經從influxdb轉移到資料彙總和分析上。
實錄:《劉平:餓了麼 Influxdb 實戰解析》