理解時序數據庫的時間線

在當今數據爆炸的時代,時序數據已經成爲企業和組織中不可或缺的一部分。它們包括了從傳感器、監控設備、日誌記錄系統和金融交易等多種來源的大量數據,這些數據按照時間順序排列,記錄了各種事件和活動的發生和變化。時序數據的分析和處理對於企業的業務決策和運營效率至關重要。爲了更好地管理和利用這些數據,人們發明了 ** 時序數據庫管理系統 (Time Series Database System,TSDB)**。

在時序數據庫系統中,時序數據通常被抽象和組織爲 ** 時間線 (time series)**,時序數據庫的設計與實現也是圍繞着時間線進行的,因此理解時間線是深入理解時序數據庫系統的前提。

在本文中,我將和大家一起學習一下時序數據庫中時間線的概念,並以 InfluxDB(2.x) 爲例探討時間線在該數據庫中的組織和呈現形式。

在學習時間線之前,我們先來重新認識一下時序數據。

  1. 什麼是時序數據

時序數據,亦稱時間序列數據,是指按時間順序記錄的、具有時間戳的數據點。這些數據點可能是連續的 (如下圖上部的 metrics),例如每秒記錄一次;也可能是不規律的,例如在特定事件發生時的記錄 (如下圖下部的 events):

圖來自 influxdb,tip: 看圖中小圈圈

時序數據在多個領域具有廣泛的應用,如金融市場的股票價格、氣候科學的氣象數據、工業設備的運行數據、物聯網數據以及車聯網數據等,如下圖(此圖來自網絡):

時序數據有着幾個鮮明的特點:

時序數據是與時間相關的數據,每個數據點都有一個時間戳或時間範圍來標識其產生或記錄的時間。

時序數據通常是大數據量的,需要處理大量的持續不斷的數據點。

從源頭流來的時序數據量往往是不間斷的。

可能會在不規則的時間間隔內突然傳來大量的數據。這在金融市場上非常常見,事件發生後交易量會出現峯值,而這是很難預測的。

時序數據常常需要實時處理分析,以便及時採取行動或在數據發生變化時發出警報。異常情況檢測就是一個很好的例子。

新的數據點會追加到已有數據的末尾,而不是或極少是修改或刪除已有的數據。並且絕大多數情況下,時序數據是按照時間順序排列的。

我們看到時序數據和傳統的 OLTP(聯機事務處理)數據具有很多不同的特點,這些不同決定了基於時序數據的數據庫管理系統所採用的數據模型、處理的數據規模、數據的訪問方式、數據的處理頻率、數據的處理方式都有很多不同。

那麼當前主流時序數據庫是如何存儲、處理和管理時序數據的呢?我們繼續向下看。

  1. 時間線:時序數據庫對時序數據的建模

初次瞭解和學習時序數據庫 (tsdb) 的時候,你都會學到一個叫 ** 時間線(Time Series)** 的術語,無論你學習的是 InfluxDB、Prometheus 還是 TDengine 亦或其他。

Influxdb 的聯合創始人 Paul Dix 對 tsdb 中時間線的理解如下:

Paul 認爲時間線是解釋和理解時序數據的一種方法。其實時間線就是時序數據庫界對時序數據的一種建模,時序數據庫就是圍繞時間線這個模型進行設計和實現的,當然不同的時序數據庫所建立的時間線模型略有差異,模型能力也有差別

有了時間線這個模型後,我們可以將時序數據庫重新定義爲:用於存儲時間線的系統

下面我們就以 Influxdb 2.x 爲例來看看一個真實的時序數據庫中的時間線模型。

2.1 InfluxDB 2.x 的 Line Protocol

提到時間線,就不能不提到 InfluxDB 用於寫入數據點 (data point) 的 Line Protocol[1],這是目前時序數據庫領域的一個流行的時序數據庫 ingest(數據攝取) 協議。通過 Line Protocol 我們能直觀地看到 influxdb 2.x 對時間線的建模形式。下面是 Line Protocol 手冊中定義的語法和一個示例:

// Syntax
<measurement>[,<tag_key>=<tag_value>[,<tag_key>=<tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]

// Example
myMeasurement,tag1=value1,tag2=value2 fieldKey="fieldValue" 1556813561098000000

下面 Paul Dix 一個 PPT 中的例子的圖以及 Line Protocol 手冊中的圖,都可以看的更直觀一些:

我們看到:在 InfluxDB 中,通過 Line Protocol 插入的一條時序數據包含四個部分:

時序數據的類別,如溫度、溼度等。measurement 類似於關係數據庫中的一個表名,每個時序數據點都歸到一個 measurement 中。這個部分是必選的。

時序數據點的標籤集合。標籤用於描述數據的屬性或特徵,比如產生的地點、設備的型號等。對每個時序數據點,InfluxDB 支持爲之打多個標籤 (tag),每個標籤是一個鍵值對,多個標籤用逗號分隔。不過,tag 這部分是可選字段,並且 tag 的鍵值對都是 string 類型。

field 部分是時序數據點的指標集合,即時序數據的有效載荷部分,這部分放置的是要得到的 field,一個鍵值對,包括指標名和對應的值。如果要攝入的是某地的天氣信息,這裏就可以用 temperature=35.3,humidity=0.7;如果採集的是某隻股票的股價,那麼這裏可以用 price=201。

field 部分是必選字段,至少應該有一個鍵值對。和 tag 不同,field 鍵值對的值部分支持數值、布爾值和字符串。

顧名思義,這部分是時間戳,是數據點的收集時間。Line Protocol 中這部分可空,一旦爲空,那麼數據點的時間戳就會被默認置爲當前時間。

那麼,InfluxDB 基於 Line Protocol 定義的時間線究竟是什麼呢?接下來我們就來看一下。

2.2 時間線與時間點

有了對 Line Protocol 各部分的認知,再來理解 InfluxDB 定義的時間線就容易多了。

InfluxDB 定義的時間線由兩部分組成,一部分是時間線 key,另外一部分則是時間線的 value 集合。

注:我們看到 tag name 和 tag value 都是時間線 key 的一部分,但 field 僅 name 是,這也是 tag 和 field 的重要差別之一。

看一個 Paul Dix 的 PPT 中的例子,下面是用 Line Protocol 攝取的數據:

weather,city=Denver,state=CO,zip=80222 temp=62.3,humidity=32
weather,city=Bellevue,state=WA,zip=98007 temp=50.7,humidity=76
weather,city=Brooklyn,state=NY,zip=11249 temp=58.2,humidity=55

我們來分析一下,這三條 Line Protocol 數據中究竟包含有幾條時間線!根據時間線 key 唯一標識一條時間線以及時間線 key 的定義,我們能得到六種 measurement+tags+field_name 的組合,即六條時間線:

weather,city=Denver,state=CO,zip=80222#temp
weather,city=Denver,state=CO,zip=80222#humidity
weather,city=Bellevue,state=WA,zip=98007#temp
weather,city=Bellevue,state=WA,zip=98007#humidity
weather,city=Brooklyn,state=NY,zip=11249#temp
weather,city=Brooklyn,state=NY,zip=11249#humidity

這樣來看,之前攝取的數據在每條時間線上只錄入了一個數據點 (即時間點)。以第一條時間線爲例,其攝入(ingest) 的數據點爲:

時間線key:weather,city=Denver,state=CO,zip=80222#temp 
時間線value:(62.3, t0) // t0表示攝入時的時間戳

爲了更好體現時間線與時間點的關係,我們再利用 Line Protocol 在上述時間線上加幾個數據點:

weather,city=Denver,state=CO,zip=80222 temp=64.3,humidity=42 // t1
weather,city=Denver,state=CO,zip=80222 temp=65.3,humidity=43 // t2
weather,city=Denver,state=CO,zip=80222 temp=64.9,humidity=45 // t3

這樣形成的時間線爲:

時間線key:weather,city=Denver,state=CO,zip=80222#temp 
時間線value集合:[(62.3, t0)(64.3, t1)(65.3, t2)(64.9, t3)]

我們針對這條時間線可以直觀地畫出 Denvor 的溫度趨勢圖 (x 軸爲時間,y 軸是 denvor 的溫度變化):

這樣看來,Line Protocol 一次可以在多個時間線上各自插入一個時間點。

注:以上是 influxdb 2.x 對時序數據的建模。influxdb 3.0,即 influxdb iox[2] 對 time series 做了重新建模,迴歸了 table 的方式:measurement <=> table,其餘標籤、字段、時間戳都變成了 column(列)。

InfluxDB 的時間線抽象非常重要,它對 influxdb 的存儲引擎、查詢引擎等的設計有着重要影響。關於時序數據庫還有一個重要的問題需要清楚認知,那就是基數 (Cardinality),下面我們就來說說 tsdb 的基數。

3 時序數據庫的基數

基數並非時序數據庫專有的概念,傳統關係型數據庫中就有基數的概念。《SQL 優化核心思想》[3] 的第一章第一節講的就是基數。書中給出的定義是:某個列唯一鍵 (distinct keys) 的數量叫作基數。書中還給出了一個比較好理解的例子。比如:性別列,其數值要麼是男,要麼是女,所以該列的基數爲 2。

那麼 InfluxDB 是如何定義一個時序數據庫相關的基數的呢?簡單來說就是唯一時間線的數量。如果一個數據庫只有一個 measurement,那麼定義該 measurement 的基數,就是這個 measurement 下的唯一時間線的數量,下面是一個例子:

measurement1:
 - 2個tag
  - tag1:有3個唯一值
  - tag2:有4個唯一值
 - 5個field

該 measurement1 的基數爲 3x4x5=60。

在 InfluxDB 2.x 版本中,高基數意味着時間線的膨脹,可能會影響讀寫性能。因爲高基數會增加索引大小,導致內存使用增加、查詢性能下降和更長的索引維護時間。同時,高基數還會導致寫入速度降低、查詢執行時間變長、磁盤空間使用增加和壓縮和數據維護操作變得更加複雜和耗時。爲了減輕高基數對 InfluxDB 讀寫性能的影響,可以採取一些措施,如仔細設計數據模型 (減少高基數維度)、使用連續查詢或任務進行預聚合、或使用剛剛發佈沒多久的、號稱支持無限時間線的 InfluxDB 3.0 等。

  1. 小結

時序數據在現實世界中具有廣泛的應用。時序數據庫,如 InfluxDB 2.x,採用時間線作爲基本的數據結構以高效地建模、查詢和管理時序數據。然而,高基數數據仍然是時序數據庫面臨的一個重要挑戰。理解時序數據庫中的時間線以及其優缺點,有助於我們更好地利用時序數據庫解決實際問題。

  1. 參考資料


Gopher Daily(Gopher 每日新聞) 歸檔倉庫 - https://github.com/bigwhite/gopherdaily

我的聯繫方式:

商務合作方式:撰稿、出書、培訓、在線課程、合夥創業、諮詢、廣告合作。

參考資料

[1] 

Line Protocol: https://docs.influxdata.com/influxdb/v2.6/reference/syntax/line-protocol/

[2] 

influxdb iox: https://github.com/influxdata/influxdb_iox

[3] 

《SQL 優化核心思想》: https://book.douban.com/subject/30214851/

[4] 

“Gopher 部落” 知識星球: https://wx.zsxq.com/dweb2/index/group/51284458844544

[5] 

鏈接地址: https://m.do.co/c/bff6eed92687

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/0pmJIXN-eIaXsrBU7wa-iA