influxdb原理

  • 參考

  • LSM樹

    更通俗的講,LSM樹原理就是把一棵大樹拆分成N棵小樹,它首先寫入內存中,隨着小樹越來越大,內存中的小樹會批量flush到磁盤中獨立的文件中以提高IO性能,而爲了提高讀性能磁盤中的樹定期可以做merge操作,合併成一棵大樹。

    • MemTable

      • MemTable 對應的就是 WAL 文件,是該文件內容在內存中的存儲結構,通常用 SkipList 來實現。MemTable 提供了 k-v 數據的寫入、刪除以及讀取的操作接口。其內部將 k-v 對按照 key 值有序存儲,這樣方便之後快速序列化到 SSTable 文件中,仍然保持數據的有序性。
    • Immutable Memtable

      • 顧名思義,Immutable Memtable 就是在內存中只讀的 MemTable,由於內存是有限的,通常我們會設置一個閥值,當 MemTable 佔用的內存達到閥值後就自動轉換爲 Immutable Memtable,Immutable Memtable 和 MemTable 的區別就是它是隻讀的,系統此時會生成新的 MemTable 供寫操作繼續寫入。之所以要使用 Immutable Memtable,就是爲了避免將 MemTable 中的內容序列化到磁盤中時會阻塞寫操作。
    • SSTable

      • SSTable 就是 MemTable 中的數據在磁盤上的有序存儲,其內部數據是根據 key 從小到大排列的。通常爲了加快查找的速度,需要在 SSTable 中加入數據索引,可以快讀定位到指定的 k-v 數據。
  • TSM(Time-Structured Merge Tree)

    • InfluxDB底層的存儲引擎經歷了從LevelDB到BlotDB,再到選擇自研TSM的過程,整個選擇轉變的思考可以在其官網文檔裏看到。整個思考過程很值得借鑑,對技術選型和轉變的思考總是比平白的描述某個產品特性讓人印象深刻的多。

    • 它的整個存儲引擎選型轉變的過程,第一階段是LevelDB,選型LevelDB的主要原因是其底層數據結構採用LSM,對寫入很友好,能夠提供很高的寫入吞吐量,比較符合時序數據的特性。在LevelDB內,數據是採用KeyValue的方式存儲且按Key排序,InfluxDB使用的Key設計是SeriesKey+Timestamp的組合,所以相同SeriesKey的數據是按timestamp來排序存儲的,能夠提供很高效的按時間範圍的掃描。

    • 不過使用LevelDB的一個最大的問題是,InfluxDB支持歷史數據自動刪除(Retention Policy),在時序數據場景下數據自動刪除通常是大塊的連續時間段的歷史數據刪除。LevelDB不支持Range delete也不支持TTL(time to live),所以要刪除只能是一個一個key的刪除,會造成大量的刪除流量壓力,且在LSM這種數據結構下,真正的物理刪除不是即時的,在compaction時纔會生效。

  • 時序數據庫結構

  • OpenTSDB/HBase

    OpenTSDB基於HBase存儲時序數據,在HBase層面設計RowKey規則爲:metric+timestamp+datasource(tags)

    • 問題一:存在很多無用的字段。一個KeyValue中只有rowkey是有用的,其他字段諸如columnfamily、column、timestamp以及keytype從理論上來講都沒有任何實際意義,但在HBase的存儲體系裏都必須存在,因而耗費了很大的存儲成本。

    • 問題二:數據源和採集指標冗餘。KeyValue中rowkey等於metric+timestamp+datasource,試想同一個數據源的同一個採集指標,隨着時間的流逝不斷吐出採集數據,這些數據理論上共用同一個數據源(datasource)和採集指標(metric),但在HBase的這套存儲體系下,共用是無法體現的,因此存在大量的數據冗餘,主要是數據源冗餘以及採集指標冗餘。

    • 問題三:無法有效的壓縮。HBase提供了塊級別的壓縮算法-snappy、gzip等,這些通用壓縮算法並沒有針對時序數據進行設置,壓縮效率比較低。HBase同樣提供了一些編碼算法,比如FastDiff等等,可以起到一定的壓縮效果,但是效果並不佳。效果不佳的主要原因是HBase沒有數據類型的概念,沒有schema的概念,不能針對特定數據類型進行特定編碼,只能選擇通用的編碼,效果可想而知。

    • 問題四:不能完全保證多維查詢能力。HBase本身沒有schema,目前沒有實現倒排索引機制,所有查詢必須指定metric、timestamp以及完整的tags或者前綴tags進行查詢,對於後綴維度查詢也勉爲其難。

  • influxdb

    相比OpenTSDB以及Druid,可能很多童鞋對InfluxDB並不特別熟悉,然而在時序數據庫排行榜單上InfluxDB卻是遙遙領先。InfluxDB是一款專業的時序數據庫,只存儲時序數據,因此在數據模型的存儲上可以針對時序數據做非常多的優化工作。

    爲了保證寫入的高效,InfluxDB也採用LSM結構,數據先寫入內存,當內存容量達到一定閾值之後flush到文件 InfluxDB在時序數據模型設計方面提出了一個非常重要的概念:seriesKey,seriesKey實際上就是measurement+datasource(tags).時序數據寫入內存之後按照seriesKey進行組織:

    • 內存中實際上就是一個Map:<SeriesKey+fieldKey, List<Timestamp|Value>>,Map中一個SeriesKey+fieldKey對應一個List,List中存儲時間線數據。數據進來之後根據measurement+datasource(tags)拼成SeriesKey,加上fieldKey,再將Timestamp|Value組合值寫入時間線數據List中。內存中的數據flush的文件後,同樣會將同一個SeriesKey中的時間線數據寫入同一個Block塊內,即一個Block塊內的數據都屬於同一個數據源下的同一個field。

    • 將datasource(tags)和metric拼成SeriesKey,不是也不能實現多維查找。確實是這樣,不過InfluxDB內部實現了倒排索引機制,即實現了tag到SeriesKey的映射關係,如果用戶想根據某個tag查找的話,首先根據tag在倒排索引中找到對應的SeriesKey,再根據SeriesKey定位具體的時間線數據。InfluxDB的這種存儲引擎稱爲TSM,全稱爲Timestamp-Structure Merge Tree,基本原理類似於LSM。後期筆者將會對InfluxDB的數據寫入、文件格式、倒排索引以及數據讀取進行專題介紹。

  • InfluxDB 數據模型

    • Measurement:從原理上講更像SQL中表的概念

    • Tags:維度列

      在InfluxDB中,表中Tags組合會被作爲記錄的主鍵,因此主鍵並不唯一,比如上表中第一行和第三行記錄的主鍵都爲’location=1,scientist=langstroth’。所有時序查詢最終都會基於主鍵查詢之後再經過時間戳過濾完成。

    • Fields:數值列。數值列存放用戶的時序數據

    • Point:類似SQL中一行記錄,而並不是一個點。

  • InfluxDB 系統架構

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