1. 程式人生 > >influxdb資料寫入

influxdb資料寫入

1、influxDB寫入總體框架

資料寫入很多時候是批量寫入,很少只是寫入少量的一個數據的情況,當然寫一個數據的過程其實和批量寫入過程是類似的,這裡講解一下批量寫入的過程
在這裡插入圖片描述
批量資料進入到influxDB之後總體會經過三個步驟的處理:
(1)批量時序資料shard路由:influxDB首先會將這些資料根據shard的不同分成不同的分組,每個分組的時序資料會發送到對應的shard。
(2)倒排索引引擎構建倒排索引:InfluxDB中shard由兩個LSM引擎構成-倒排索引引擎和TSM引擎。時序資料首先會經過倒排索引引擎構建倒排索引。
(3)TSM引擎持久化時序資料:倒排索引構建成功之後時序資料會進入TSM Engine。TSM Engine處理流程:先將寫入請求追加寫入WAL日誌,再寫入cache,滿足特定條件就將cache中的時序資料執行flush操作落盤形成TSM File

2、批量時序資料shard路由

influxdb sharding策略實際上有兩層:Range Sharding和Hash Sharding。在influxdb裡面有shard group和shard的概念,具體的講真正按照時間分片的是shard Group,對於單節點的influxdb,一個shard group下面只有一個shard,對於叢集型別的,一個shard group下面會有多個shard,在對映到shard group的層級,使用的是Range sharding,就是時間對映,然後在叢集中,再通過hash(series)對映到對應的shard,這個就是hash sharding。相同shard group,同一個series的資料一定在同一個shard裡面,

3、倒排索引引擎構建倒排索引

倒排索引的作用是為了在給定某個或者某幾個tag的情況下,資料庫可以快速搜尋到對應的key(masurement + tags + field key)。倒排索引引擎使用的也是LSM引擎(LSM寫效能友好的特點適用於influxdb寫多讀少的特性,所以無論是倒排索引引擎還是資料引擎都使用lsm引擎自然無可厚非),所以工作機制自然就是:首先將資料追加寫入WAL再寫入Cache就可以返回給使用者寫入成功,WAL可以保證即使發生異常宕機也可以恢復出cache中丟失的資料。一旦滿足特定條件系統會將cache中的時序資料執行flush操作落盤形成檔案。檔案數量超過一定閾值系統會將這些檔案合併形成一個大檔案。具體的倒排索引流程比較複雜,先不做細緻討論。

4、時序資料寫入流程

(1)WAL追加寫入:經過兩步,第一步把資料格式化為WAL單個條目物件的格式,第二部經過snappy壓縮持久化到wal檔案
單個條目檔案結構參見:http://leanote.com/blog/post/5afe6e9fab64410945000d99
(2)寫入cache
第一步:資料格式化。格式化為一個Map<key,List<timeStamp|value>>
第二步:時序資料點寫入cache。influxDb中cache是一個crude hash ring,這裡的ring是由256個partition構成,每個partition負責儲存一部分時序資料Key對應的值,寫入資料的時候首先會根據key hash一次,hash到對應的partition。為什麼這麼處理,個人認為有點像Java中ConcurrentHashMap的思路,將一個大HashMap切分成多個小HashMap,每個HashMap內部在寫的時候需要加鎖。這樣處理可以減小鎖粒度,提高寫效能。

(3)flush to tmsFile
觸發時機:Cache執行flush有兩個觸發條件,一是當cache大小超過一定閾值,可以通過引數’cache-snapshot-memory-size’配置,預設是25M大小;二是超過一定時間閾值沒有資料寫入WAL也會觸發flush,預設時間閾值是10分鐘,可以通過引數’cache-snapshot-write-cold-duration’配置


基本流程:其實TSM file我們知道基本結構分為四個部分–header、block、index、footer,對於header資料是很好設定的,footer資料存放的是index的起始位置,那麼先要搞定index才行。所以我們關鍵要做的是對block和index的賦值

  • 構建Series Data Block: 首先會在記憶體中構建series data block:順序遍歷記憶體Map中的時序資料,分別對時序資料的時間列和數值列進行相應的編碼,按照Series Data Block的格式進行組織,當Block大小超過一定閾值就構建成功,並記錄這個Block內時間列的最小時間MinTime以及最大時間MaxTime構建好之後寫入檔案,返回Block在檔案中的偏移量Offset以及總大小Size
  • 構建檔案級別B+索引:在記憶體中利用上面返回的Offset、Size、MinTime、MaxTime構建一個IndexEntry物件,寫入到記憶體中的Series Index Block物件

這樣,每構建一個Series Data Block並寫入檔案之後都會在記憶體中順序構建一個Index Entry,寫入記憶體Series Index Block物件。一旦一個key對應的所有時序資料都持久化完成,一個Series Index Block就構建完成,構建完成之後填充Index Block Meta資訊,接著新建一個新的Series Index Block開始構建下一個Key對應的資料索引資訊

對於Block Index,為了快速定位到對應key在哪一個Block Index,influxdb還引入了間接索引offsets,offsets是一個數組,存放了對應key在index表中的位置,這些元素是按照key進行字典排序的,所以給出一個key的時候,可以通過二分查詢,快速找到block index的位置,在block index裡面,每一個index entry可以根據時間戳進行第二次二分查詢,最後就可以找到對應block的位置

資料壓縮

資料寫入到wal和tsm檔案之後,會按照一定的編碼進行compaction,具體壓縮細節這裡不做討論