天天看點

OpenTSDB的彙總和預聚合(Rollup And Pre-Aggregates)(二)

寫在前面

這是有關于OpenTSDB支援的有關配置,和預先設定聚合,不過這方面的應用還是太少,有待補充。

原位址:http://opentsdb.net/docs/build/html/user_guide/rollups.html

預聚集

雖然彙總有助于進行廣泛的時間跨度查詢,但如果度量标準具有高基數(即給定度量标準的唯一時間序列數),則仍會遇到小範圍的查詢性能問題。在上面的示例中,我們有4個Web伺服器。但是我們說我們有10,000台伺服器。擷取接口流量的總和或平均值可能相當慢。如果使用者經常取由大型成套這樣的組(或有些人認為它作為空間集合)的話很有道理存儲彙總和查詢代替,取多少資料較少。

與彙總不同,預聚合隻需要一條額外的資訊:

  • 聚合函數 - 對基礎值執行了哪些算術以獲得新值。例如

    sum

    ,添加所有時間序列或

    max

    存儲最大的時間序列。

在OpenTSDB中,預聚合與具有特殊标記的其他時間序列不同。預設标記鍵是

_aggregate

(可配置通過

tsd.rollups.agg_tag_key

)。然後,用于生成資料的聚合函數以大寫形式存儲在标記值中。讓我們看一個例子:

預聚合示例

鑒于示例設定在頂部,我們可能希望按colo(資料中心)檢視總接口流量。在這種情況下,我們可以彙總

SUM

COUNT

彙總類似。結果将是四個新的時間序列與中繼資料,如:

Series ID Metric Tag 1 Tag 2
ts1' system.if.bytes.out colo=lga _aggregate=SUM
ts2' system.if.bytes.out colo=lga _aggregate=COUNT
ts3' system.if.bytes.out colo=sjc _aggregate=SUM
ts4' system.if.bytes.out colo=sjc _aggregate=SUM

請注意,這些時間序列已删除了

host

和的标記

interface

。這是因為,聚集過程中,取得了多個不同的值,

host

并且

interface

已經結束了到這個新的系列,使其不再有意義,讓他們為标簽。另請注意,我們

_aggregate

在存儲的資料中注入了新标記。查詢現在可以通過指定

_aggregate

值來通路此資料。

注意

啟用彙總後,如果您計劃使用預聚合,則可能希望通過TSDB自動注入來幫助區分原始資料和預聚合

_aggregate=RAW

。隻需将

tsd.rollups.tag_raw

設定配置為true即可。

現在為結果資料:

Series ID 12:00 12:15 12:30 12:45 13:00 13:15 13:30 13:45
ts1' 8 6 5 -1 6 -4 6 3
ts2' 2 2 2 2 2 1 2 2
ts3' 9 5 3 1 14 8 4 9
ts4' 1 2 2 2 2 2 2 2

由于我們通過聚合(分組

colo

)執行組,是以我們從原始資料集中擷取每個時間戳的值。在這種情況下,我們不會進行下采樣或執行彙總。

警告

與彙總一樣,在編寫預聚合時,最好避免使用平均值,中值或偏差等函數。隻需存儲金額和計數

累積預聚合

雖然預聚合肯定有助于高基數名額,但使用者可能仍然想要求廣泛的時間跨度但遇到慢查詢。值得慶幸的是,您可以像原始資料一樣彙總預聚合。隻需生成預聚合,然後使用上面的資訊将其彙總。

生成彙總和預聚合

目前,TSD不會為您生成彙總或預先彙總的資料。其主要原因是OpenTSDB旨在處理大量的時間序列資料,是以各個TSD專注于盡可能快地将資料存入存儲。

問題

由于TSD的(基本上)無狀态特性,它們可能不具有可用于執行預聚合的全套資料。例如,我們的樣本

ts1

資料可能會在寫入

TSD_A

ts2

寫入

TSD_B

。如果不從存儲中讀取資料,也不能執行适當的分組。我們也不知道我們應該在什麼時候進行預聚合。我們可以等待1分鐘并預先彙總資料,但會錯過那一分鐘後發生的任何事情。或者我們可以等待一個小時,對預聚合的查詢将不會包含最後一小時的資料。如果資料進入後期會發生什麼?

此外,對于彙總,根據使用者如何将資料寫入TSD,

ts1

我們可能會收到

12:15

資料點,

TSD_A

12:30

值會到達,

TSD_B

是以整個小時都不需要資料。時間視窗限制也适用于彙總。

解決方案

使用彙總和預聚合需要進行一些分析并在各種權衡之間進行選擇。由于一些OpenTSDB使用者已經有了計算此類資料的方法,我們隻需提供API來存儲和查詢。但是,這裡有一些關于如何自己計算這些的技巧。

批量處理

其他時間序列資料庫通常使用的一種方法是在延遲一段時間後從資料庫中讀取資料,計算pre-aggs和彙總,然後編寫它們。這是解決問題的最簡單方法,适用于小規模。但是仍然存在一些問題:

  • 随着資料的增長,生成彙總的查詢也會增長到查詢負載影響寫入和使用者查詢性能的程度。在HBase下啟用資料壓縮時,OpenTSDB會遇到同樣的問題。
  • 此外,随着資料的增長,更多資料意味着批處理時間更長,必須在多個從業人員之間進行分片,這可能會很難協調和排除故障。
  • 除非采用某種跟蹤方法來觸發舊資料的新批處理,否則可能無法彙總延遲或曆史資料。

一些改進批處理的方法包括:

  • 從複制系統讀取,例如,如果您設定HBase複制,您可以讓使用者查詢主系統和從複制存儲讀取的聚合。
  • 從備用商店閱讀。一個示例是将所有資料鏡像到另一個存儲(例如HDFS),并針對該資料運作批處理作業。

排隊TSD

某些資料庫使用的另一個選項是将程序記憶體中的所有資料排隊,并在經過配置的時間視窗後寫入結果。但由于TSD是無狀态的,并且通常使用者在其TSD之前放置負載平衡器,是以單個TSD可能無法獲得要計算的彙總或預聚合的全貌(如上所述)。要使此方法起作用,上遊收集器必須将計算所需的所有資料路由到特定TSD。這不是一項艱巨的任務,但面臨的問題包括:

  • 有足夠的RAM或磁盤空間來為每個TSD本地假脫機資料。
  • 如果TSD程序終止,您将丢失聚合的資料,或者必須從存儲中引導。
  • 無論何時進行聚合計算,原始資料的總寫入吞吐量都會受到影響。
  • 您仍然有遲到/曆史資料問題。
  • 由于TSDB是基于JVM的,是以将所有資料儲存在RAM中然後運作GC會受到影響。很多。(假脫機到磁盤更好,但是你會遇到IO問題)

一般來說,排在作家身上是一個壞主意。避免疼痛。

流處理

處理彙總和預聚合的更好方法是将資料路由到流處理系統,在該處理系統中可以近乎實時地處理資料并将其寫入TSD。它類似于TSD上的排隊選項,但使用無數流處理架構之一(Storm,Flink,Spark等)來處理消息路由和記憶體存儲。然後,您隻需編寫一些代碼來計算聚合,并在視窗通過後将資料吐出。

這是許多下一代監控解決方案所使用的解決方案,例如雅虎的解決方案。雅虎正緻力于為需要大規模監控的其他人開源他們的流處理系統,并将其整齊地插入TSDB。

雖然流處理更好,但仍然有問題需要處理,例如:

  • 足夠的資源讓流勞工完成他們的工作。
  • 死流工作者需要從存儲啟動。
  • 必須處理延遲/曆史資料。

分享

如果您有用于計算聚合的工作代碼,請與OpenTSDB組共享。如果您的解決方案是開源的,我們可以将其合并到OpenTSDB生态系統中。

組态

對于Opentsdb 2.4,彙總配置由opentsdb.conf密鑰引用

tsd.rollups.config

。此鍵的值必須是除了換行符的報價轉義JSON字元串,或者最好是包含配置的JSON檔案的路徑。檔案名必須以

.json

in 結尾

rollup_config.json

JSON配置應如下所示:

{ 
      “aggregationIds” : { 
              “sum” : 0 ,
              “count” : 1 ,
              “min” : 2 ,
              “max” : 3 
      },
      “interval” : [{ 
              “table” : “tsdb” ,
              “preAggregationTable” : “ tsdb-preagg“ ,
              ”interval“ : ”1m“ ,
              ”rowSpan“ : ”1h“ ,
              ”defaultInterval“ : true 
      }, { 
              ”table“ : ”tsdb-rollup-1h“ ,
              ”preAggregationTable“: “tsdb-rollup-preagg-1h” ,
              “interval” : “1h” ,
              “rowSpan” : “1d” 
      }] 
}      

兩個頂級字段包括:

  • aggregationIds - OpenTSDB聚合函數名稱到用于壓縮存儲的數字辨別符的映射。
  • interval - 包含表名和區間定義的一個或多個區間定義的清單。

aggregationIds

聚合ID映射用于通過使用數字ID預先填充每種類型的彙總資料而不是拼寫出完整聚合函數來減少存儲。例如,如果我們

COUNT:

為每個值(或壓縮列)的每個值加上6個位元組的字首,我們可以使用ID進行儲存。

ID必須是0到127之間的整數。這意味着我們每個時間間隔最多可以存儲128個不同的彙總。在映射中可以僅提供每個數值的一個ID,并且可以僅給出每種類型的一個聚合函數。如果函數名稱未映射到OpenTSDB支援的聚合函數,則啟動時将抛出異常。同樣,必須至少給出一個聚合才能啟動TSD。

警告

一旦開始寫入資料,就無法更改聚合ID。如果更改映射,則可能會傳回不正确的資料,或者查詢和寫入可能會失敗。您總是可以在将來添加函數,但永遠不會更改映射。

間隔

每個區間對象都定義了表路由,以便彙總和查詢彙總和預聚合資料。間隔有兩種類型:

  • 預設 - 這是由定義的預設原始資料OpenTSDB表

    "defaultInterval":true

    。對于現有安裝,這将是

    tsdb

    表或其中定義的任何内容

    tsd.storage.hbase.data_table

    。間隔和跨度被忽略,預設為OpenTSDB 1小時行寬,并以給定的分辨率和時間戳存儲資料。每個TSD和配置一次隻能配置一個預設值。
  • 彙總間隔 -

    "defaultInterval":false

    未設定或未設定預設間隔的任何間隔。這些是彙總表,其中值被捕捉到間隔邊界。

應定義以下字段:

名稱 資料類型 是否必須 描述
table String 非預先聚合資料的基礎或彙總表。對于預設表,應該是

tsdb

或者寫入現有原始資料表。對于彙總資料,它必須是與原始資料不同的表。
tsdb-rollup-1h
preAggregationTable String 應該寫入預聚合和(可選)彙總資料的表。這可能與

table

值相同。
tsdb-rollup-preagg-1h
interval String 格式中資料點之間的預期間隔

<interval><units>

。例如,如果每小時計算彙總,則間隔應為

1h

。如果每10分鐘計算一次,請将其設定為

10m

。對于預設表,将忽略此值。
1H
ROWSPAN String 存儲中每行的寬度。此值必須大于更大

interval

和界定的數量和是那麼我們将不得不每行24個值。

interval``s that will fit in each row. E.g. if the interval is ``1h``rowSpan``1d

1D
defaultInterval bool 配置的時間間隔是否為原始 non-rolled 資料的預設值。 true

在存儲中,彙總的寫入類似于原始資料,因為每行都有一個基本時間戳,每個資料點都是該基準時間的偏移量。每個偏移量都是基準時間的增量,而不是實際偏移量。例如,如果一行存儲1天的1小時資料,則最多可存在24個偏移。偏移

将映射到行的午夜,偏移5将映射到上午6點。因為彙總偏移量是以14位編碼的,如果一行中存儲的間隔太多而無法容納在14位内,則在啟動TSD時會引發錯誤。

警告

将資料寫入TSD後,請勿更改間隔寬度或行間距以進行彙總間隔。這将導緻垃圾資料和可能的查詢失敗。

OpenTSDB系列

總結目錄https://blog.csdn.net/jyj1100/article/details/83450282

繼續閱讀