十分鐘看懂時序資料庫I 儲存篇

2021-09-23 04:38:18 字數 4378 閱讀 2062

本文會從時序資料庫的基本概念、使用場景、解決的問題一一展開,最後會從如何解決時序資料儲存這一技術問題入手進行深入分析。

背景

什麼是時序資料庫

先來介紹什麼是時序資料。時序資料是基於時間的一系列的資料。在有時間的座標中將這些資料點連成線,往過去看可以做成多緯度報表,揭示其趨勢性、規律性、異常性;往未來看可以做大資料分析,機器學習,實現**和預警。

時序資料庫就是存放時序資料的資料庫,並且需要支援時序資料的快速寫入、持久化、多緯度的聚合查詢等基本功能。

對比傳統資料庫僅僅記錄了資料的當前值,時序資料庫則記錄了所有的歷史資料。同時時序資料的查詢也總是會帶上時間作為過濾條件。

時序資料示例

北上廣三地2023年氣溫變化圖

北上廣三地當前溫度實時展現

下面介紹下時序資料庫的一些基本概念(不同的時序資料庫稱呼略有不同)。

如下圖,度量為wind,每乙個資料點都具有乙個timestamp,兩個field:direction和speed,兩個tag:sensor、city。它的第一行和第三行,存放的都是sensor號碼為95d8-7913的裝置,屬性城市是上海。隨著時間的變化,風向和風速都發生了改變,風向從23.4變成23.2;而風速從3.4變成了3.3。

時序資料庫基本概念圖

時序資料庫的場景

所有有時序資料產生,並且需要展現其歷史趨勢、週期規律、異常性的,進一步對未來做出**分析的,都是時序資料庫適合的場景。

時序資料庫遇到的挑戰

很多人可能認為在傳統關係型資料庫上加上時間戳一列就能作為時序資料庫。資料量少的時候確實也沒問題,但少量資料是展現的緯度有限,細節少,可置信低,更加不能用來做大資料分析。很明顯時序資料庫是為了解決海量資料場景而設計的。

可以看到時序資料庫需要解決以下幾個問題:

這些問題不是用一篇文章就能含蓋的,同時每個問題都可以從多個角度去優化解決。在這裡只從資料儲存這個角度來嘗試回答如何解決大資料量的寫入和讀取。

資料的儲存

資料的儲存可以分為兩個問題,單機上儲存和分布式儲存。

如果只是儲存起來,直接寫成日誌就行。但因為後續還要快速的查詢,所以需要考慮儲存的結構。

傳統資料庫儲存採用的都是b tree,這是由於其在查詢和順序插入時有利於減少尋道次數的組織形式。我們知道磁碟尋道時間是非常慢的,一般在10ms左右。磁碟的隨機讀寫慢就慢在尋道上面。對於隨機寫入b tree會消耗大量的時間在磁碟尋道上,導致速度很慢。我們知道ssd具有更快的尋道時間,但並沒有從根本上解決這個問題。

對於90%以上場景都是寫入的時序資料庫,b tree很明顯是不合適的。

業界主流都是採用lsm tree替換b tree,比如hbase, cassandra等nosql中。這裡我們詳細介紹一下。

lsm tree包括記憶體裡的資料結構和磁碟上的檔案兩部分。分別對應hbase裡的memstore和hlog;對應cassandra裡的memtable和sstable。

lsm tree操作流程如下:

資料寫入和更新時首先寫入位於記憶體裡的資料結構。為了避免資料丟失也會先寫到wal檔案中。

記憶體裡的資料結構會定時或者達到固定大小會刷到磁碟。這些磁碟上的檔案不會被修改。

隨著磁碟上積累的檔案越來越多,會定時的進行合併操作,消除冗餘資料,減少檔案數量。

hbase lsm tree結構介紹

可以看到lsm tree核心思想就是通過記憶體寫和後續磁碟的順序寫入獲得更高的寫入效能,避免了隨機寫入。但同時也犧牲了讀取效能,因為同乙個key的值可能存在於多個hfile中。為了獲取更好的讀取效能,可以通過bloom filter和compaction得到,這裡限於篇幅就不詳細展開。

分布式儲存

時序資料庫面向的是海量資料的寫入儲存讀取,單機是無法解決問題的。所以需要採用多機儲存,也就是分布式儲存。

分布式儲存首先要考慮的是如何將資料分布到多台機器上面,也就是 分片(sharding)問題。下面我們就時序資料庫分片問題展開介紹。分片問題由分片方法的選擇和分片的設計組成。

分片方法

分片設計

分片設計簡單來說就是以什麼做分片,這是非常有技巧的,會直接影響寫入讀取的效能。

結合時序資料庫的特點,根據metric+tags分片是比較好的一種方式,因為往往會按照乙個時間範圍查詢,這樣相同metric和tags的資料會分配到一台機器上連續存放,順序的磁碟讀取是很快的。再結合上面講到的單機儲存內容,可以做到快速查詢。

進一步我們考慮時序資料時間範圍很長的情況,需要根據時間範圍再將分成幾段,分別儲存到不同的機器上,這樣對於大範圍時序資料就可以支援併發查詢,優化查詢速度。

如下圖,第一行和第三行都是同樣的tag(sensor=95d8-7913;city=上海),所以分配到同樣的分片,而第五行雖然也是同樣的tag,但是根據時間範圍再分段,被分到了不同的分片。第

二、四、六行屬於同樣的tag(sensor=f3cc-20f3;city=北京)也是一樣的道理。

時序資料分片說明

真實案例

下面我以一批開源時序資料庫作為說明。

非常優秀的時序資料庫,但只有單機版是免費開源的,集群版本是要收費的。從單機版本中可以一窺其儲存方案:在單機上influxdb採取類似於lsm tree的儲存結構tsm;而分片的方案influxdb先通過+(事實上還要加上retentionpolicy)確定shardgroup,再通過+的hash code確定到具體的shard。

這裡timestamp預設情況下是7天對齊,也就是說7天的時序資料會在乙個shard中。

influxdb tsm結構圖

底層使用cassandra作為分布式儲存引擎,如上文提到單機上採用的是lsm tree。

cassandra有兩級索引:partition key和clustering key。其中partition key是其分片id,使用的是一致性雜湊;而clustering key在乙個partition key中保證有序。

kairosdb利用cassandra的特性,將 ++《資料型別》+作為partition key,資料點時間在timestamp上的偏移作為clustering key,其有序性方便做基於時間範圍的查詢。

partition key中的timestamp是3周對齊的,也就是說21天的時序資料會在乙個clustering key下。3周的毫秒數是18億正好小於cassandra每行列數20億的限制。

底層使用hbase作為其分布式儲存引擎,採用的也是lsm tree。

hbase採用範圍劃分的分片方式。使用row key做分片,保證其全域性有序。每個row key下可以有多個column family。每個column family下可以有多個column。

上圖是opentsdb的row key組織方式。不同於別的時序資料庫,由於hbase的row key全域性有序,所以增加了可選的salt以達到更好的資料分布,避免熱點產生。再由與timestamp間的偏移和資料型別組成column qualifier。

他的timestamp是小時對齊的,也就是說乙個row key下最多儲存乙個小時的資料。並且需要將構成row key的metric和tags都轉成對應的uid來減少儲存空間,避免hfile索引太大。下圖是真實的row key示例。

open tsdb的row key示例

結束語

可以看到各分布式時序資料庫雖然儲存方案都略有不同,但本質上是一致的,由於時序資料寫多讀少的場景,在單機上採用更加適合大吞吐量寫入的單機儲存結構,而在分布式方案上根據時序資料的特點來精心設計,目標就是設計的分片方案能方便時序資料的寫入和讀取,同時使資料分布更加均勻,盡量避免熱點的產生。

資料儲存是時序資料庫設計中很小的一塊內容,但也能管中窺豹,看到時序資料庫從設計之初就要考慮時序資料的特點。後續我們會從其他的角度進行討論。

原文發布時間為:2023年5月8日 

十分鐘看懂時序資料庫(IV) 分級儲存

本文將介紹通過對資料進行分級儲存,從使用不同儲存介質,以及減少資料的副本數的方面,介紹如何在保證時序資料的查詢效能的前提下,降低時序資料的儲存成本。1.分級儲存 分級儲存,就是按某一特徵,將資料劃分為不同的級別,每個級別的資料儲存在不同成本的儲存介質上。為什麼需要對資料進行分級儲存?為什麼不把所有的...

十分鐘看懂時序資料庫(III) 壓縮

壓縮對於時序資料庫是至關重要的。因為時序資料庫面對的物聯網場景每天都會產生上億條資料。眾所周知,在大資料時代的今天資料的重要性是不言而喻的,資料就是公司的未來。但如果無法對這些時序資料進行很好的管理和壓縮,那將給客戶帶來非常高的成本壓力。如前文提到的,工業物聯網環境監控方向的客戶,一年產生1p的資料...

十分鐘看懂時序資料庫(III) 壓縮

壓縮對於時序資料庫是至關重要的。因為時序資料庫面對的物聯網場景每天都會產生上億條資料。眾所周知,在大資料時代的今天資料的重要性是不言而喻的,資料就是公司的未來。但如果無法對這些時序資料進行很好的管理和壓縮,那將給客戶帶來非常高的成本壓力。如前文提到的,工業物聯網環境監控方向的客戶,一年產生1p的資料...