餓了麼 Influxdb 實踐之路

餓了麼 Influxdb 實踐之路


前言

Influxdbhttps://github.com/influxdata/influxdb)是一個基於 golang 編寫,沒有額外依賴的開源時序數據庫,用於記錄 metrics、events,進行數據分析。這篇文章談論的 influxdb 版本在1.2.0以上。mysql

這篇文章只談論 influxdb 在監控中的數據存儲應用,不會談論 influxdb 提供的整套監控方案。本文主要談論五個方面:時序數據庫選型、influxdb 基本概念、存儲引擎、實踐、數據聚合。git

選型

Influxdb vs Prometheus

  1. influxdb 集成已有的概念,好比查詢語法相似 sql,引擎從 LSM 優化而來,學習成本相對低。github

  2. influxdb 支持的類型有 float,integers,strings,booleans,prometheus 目前只支持 float。golang

  3. influxdb 的時間精度是納秒,prometheus 的則是毫秒。sql

  4. influxdb 僅僅是個數據庫,而 prometheus 提供的是整套監控解決方案,固然 influxdb 也提供了整套監控解決方案。shell

  5. influxdb 支持的 math function 比較少,prometheus 相對來講更多,influxdb 就目前使用上已經知足功能。數據庫

  6. 2015年 prometheus 還在開發階段,相對來講 influxdb 更加穩定。後端

  7. influxdb 支持 event log,prometheus 不支持。緩存

  8. 更詳細的對比請參考:對比(https://db-engines.com/en/system/Graphite%3BInfluxDB%3BPrometheus)。架構

咱們其實僅僅須要的是一個數據庫,其餘組件都是本身開發的,並且存儲的數據類型不只僅是數字,所以選擇了 influxdb。但願上面的比較對你們有幫助。

Influxdb 基本概念

Database

數據庫是個邏輯容器,包含了 measurement、retention policies、continuous queries、time series data,相似於 mysql 的 database。

Measurement

描述了相關數據的存儲結構,相似於 mysql 的 table,可是不須要建立,寫入數據的時候自動建立。關於 schema 的設計建議參考:設計建議https://docs.influxdata.com/influxdb/v1.2/concepts/schema_and_data_layout/)。

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(https://docs.influxdata.com/influxdb/v1.2/query_language/continuous_queries/)。

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 存儲引擎解析(http://blog.fatedier.com/2016/08/05/detailed-in-influxdb-tsm-storage-engine-one/

實踐

項目介紹

gateway(https://github.com/pingliu/influxdb-gateway)用於檢測和壓縮influxdb的數據,用於跨機房傳輸,採用udp接受數據。

influxdb-relay(https://github.com/influxdata/influxdb-relay)是官方提供的高可用方案,可是它只提供簡單的寫入功能。

influxdb-proxy(https://github.com/shell909090/influx-proxy)是用於替代 influxdb-relay 的高可用方案。

前期架構圖

blob.png

使用問題

influxdb-relay 是官方提供的高可用方案,可是它只提供簡單的寫入功能。在初期使用時,並無多大的問題,隨着 influxdb 在公司的推廣,接入方愈來愈多,意味着查詢方愈來愈多,這就帶來了如下問題:

  1. grafana 須要配置不少個數據源。

  2. 用戶不能根據 measurement 來訂閱數據。

  3. 數據庫掛掉,就須要修改 grafana 的數據源。

  4. 維護困難,好比須要新增數據庫,用戶須要配置多個數據源,不能統一接入點。

  5. 用戶查詢直連數據庫,用戶select *數據庫直接 OOM,數據庫會重啓。

  6. relay提供的重寫功能,數據是保留在內存中,一旦 influxdb 掛掉,就會致使relay機器內存瘋漲。

踩過的坑

  1. max-row-limit不爲0,會致使 influxdb OOM。目前這個問題已經修復,可是 grafana 展現時會存在問題,配置時請設置爲0。

  2. 配置查詢限制參數時,會致使一些奇怪的問題,官方是不限制,請保留默認配置。

  3. 沒有制定 schema 規範,接入方把 field寫成 tag 了,致使內存瘋漲,最後 OOM。理解 series 的概念很重要。

  4. 寫入超時時間默認是10s,有時候數據寫入了但返回 500。能夠將這個時間設置成大點。

優化後的架構圖

blob.png

influxdb-proxy 是爲了解決上面的使用問題而開發出來的。具備如下功能:

  1. 同時支持寫和查詢功能,統一接入點,相似cluster。

  2. 支持重寫功能,寫入失敗時寫入文件,後端恢復時再寫入。

  3. 限制部分查詢命令和所有刪除操做。

  4. 以 measurement 爲粒度區分數據,支持按需訂閱。

  5. measurement 優先精確匹配,而後前綴匹配。

  6. 提供數據統計,好比 qps,耗時等等。

數據聚合

CQ

influxdb 提供數據聚合的功能,就是上面基本概念裏提到的 Continuous Query。預先定義好cq,就能夠按期根據不一樣的tag進行聚合數據。目前它有個設計問題:cq 是順序執行的,cq 越多,數據延遲越高,通常延遲在幾分鐘內。若是須要更實時的聚合,cq 不能知足,須要引入其餘工具,好比spark。關於 cq 的語法請參考:語法(https://docs.influxdata.com/influxdb/v1.2/query_language/continuous_queries/)。

Spark

通過內部調研,發現 spark+kafka 是個更好的聚合方案。spark支持流式處理且支持 sql 功能,咱們只須要將cq改爲sql就行。目前這個處於嘗試階段,已經上線部分功能。目前的處理流程以下:

blob.png

總結

上文講的整套架構已經支撐起餓了麼2萬臺機器的監控,目前每秒寫入的點數是300k。後端 influxdb 的機器數量是20臺左右,維護成本基本趨於零。咱們的焦點目前已經從 influxdb 轉移到數據聚合和分析上。

相關文章
相關標籤/搜索