天天看點

OpenTSDB原理系列-資料表設計Annotation資料

上一篇文章《OpenTSDB原理系列-中繼資料模型》講到了OpenTSDB的基礎概念,以及中繼資料模型,這篇文章介紹OpenTSDB的HBase資料表設計。OpenTSDB共涉及兩種類型的資料:Metrics資料以及Annotation(注釋)資料,在将這些資料存到HBase表中時,針對RowKey, Qualifier以及Value資訊都做了特殊設計,進而使得存儲更加高效。

Metrics RowKey設計

metrics資料的HBase RowKey中包含主要組成部分為:鹽值(Salt)、metrics名稱、時間戳、tagKey、tagValue等部分。上篇文章已經講到,為了統一各個值的長度以及節省空間,對metrics名稱、tagKey和tagValue配置設定了UID資訊。是以,在HBase RowKey中實際寫入的metrics UID、tagKey UID和tagValue UID。

HBase RowKey的資料模型如下圖所示:

OpenTSDB原理系列-資料表設計Annotation資料
  • SALT:建議開啟SALT功能,可以有效提高性能。SALT資料的長度是變長的:如果SALT的值值少于256,那麼隻用一個位元組表示即可;如果需要設定更大的SALT值,也會相應地占用更多的空間。
  • Metric ID:metrics名經過編碼後,每個Metric ID的長度為三個位元組。
  • Timestamp:這裡是整點小時時間戳。
  • tagKey UID & tagValue UID:tagKey和tagValue經過編碼後,每個tagKey UID和tagValue UID的長度都為三個位元組。tagKey UID和tagValue UID必須成對出現,最少必須存在1對,最多存在8對。

Metrics Qualifier設計

Qualifier用于儲存一個或多個DataPoint中的時間戳、資料類型、資料長度等資訊。

由于時間戳中的小時級别的資訊已經儲存在RowKey中了,是以Qualifier隻需要儲存一個小時中具體某秒或某毫秒的資訊即可,這樣可以減少資料占用的空間。

一個小時中的某一秒(少于3600)最多需要2個位元組即可表示,而某一毫秒(少于3600000)最多需要4個位元組才可以表示。為了節省空間,OpenTSDB沒有使用統一的長度,而是對特定的類型采用特性的編碼方法。Qualifer的資料模型主要分為如下三種情況:秒、毫秒、秒和毫秒混合。

秒類型

當OpenTSDB接收到一個新的DataPoint的時候,如果請求中的時間戳是秒,那麼就會插入一個如下模型的資料。

判斷請求中的時間戳為秒或毫秒的方法是基于時間戳數值的大小,如果時間戳的值的超過無符号整數的最大值(即4個位元組的長度),那麼該時間戳是毫秒,否則為秒。

OpenTSDB原理系列-資料表設計Annotation資料
  • Value長度:Value的實際長度是Qualifier的最後3個bit的值加1,即(qualifier & 0x07) + 1。表示該時間戳對應的值的位元組數。是以,值的位元組數的範圍是1到8個位元組。
  • Value類型:Value的類型由Qualifier的倒數第4個bit表示,即(qualifier & 0x08)。如果值為1,表示Value的類型為float;如果值為0,表示Value的類型為long。
  • 時間戳:時間戳的值由Qualifier的第1到第12個bit表示,即(qualifier & 0xFFF0) >>>4。由于秒級的時間戳最大值不會大于3600,是以qualifer的第1個bit肯定不會是1。

毫秒類型

當OpenTSDB接收到一個新的DataPoint的時候,如果請求中的時間戳是毫秒,那麼就會插入一個如下模型的資料。

OpenTSDB原理系列-資料表設計Annotation資料
  • Value長度:與秒類型相同。
  • Value類型:與秒類型相同。
  • 時間戳: 時間戳的值由Qualifier的第5到第26個bit表示,即(qualifier & 0x0FFFFFC0) >>>6。
  • 标志位:标志位由Qualifier的前4個bit表示。當該Qualifier表示毫秒級資料時,必須全為1,即(qualifier[0] & 0xF0) == 0xF0。
  • 第27到28個bit未使用。

混合類型

當同一小時的資料發生合并後,就會形成混合類型的Qualifier。

合并的方法很簡單,就是按照時間戳順序進行排序後,從小到大依次拼接秒類型和毫秒類型的Qualifier即可。

OpenTSDB原理系列-資料表設計Annotation資料
  • 秒類型和毫秒類型的數量沒有限制,并且可以任意組合。
  • 不存在相同時間戳的資料,包括秒和毫秒的表示方式。
  • 周遊混合類型中的所有DataPoint的方法是:
    • 從左到右,先判斷前4個bit是否為0xF
    • 如果是,則目前DataPoint是毫秒型的,讀取4個位元組形成一個毫秒型的DataPoint
    • 如果否,則目前DataPoint是秒型的,讀取2個位元組形成一個秒型的DataPoint
    • 以此疊代即可周遊所有的DataPoint

Metrics Value設計

HBase Value部分用于儲存一個或多個DataPoint的具體某個時間戳對應的值。

由于在Qualifier中已經儲存了DataPoint Value的類型和DataPoint Value的長度,是以無論是秒級還是毫秒級的值,都可以用相同的表示方法,而混合類型就是多個DataPoint Value的拼接。

HBase Value按照長度可以分為如下幾種類型:

單位元組

當DataPoint Value為long型,且大于等于-128(Byte.MIN_VALUE),且少于或等于127(Byte.MAX_VALUE)的時候,使用1個位元組存儲。

兩位元組

當DataPoint Value為long型,且大于等于-32768(Short.MIN_VALUE),且少于或等于32767(Short.MAX_VALUE)的時候,使用2個位元組存儲。

四位元組

當DataPoint Value為long型,且大于等于0x80000000(Integer.MIN_VALUE),且少于或等于0x7FFFFFFF(Integer.MAX_VALUE)的時候,使用4個位元組存儲。

八位元組

當DataPoint Value為long型,且不是上面三種類型的時候,使用8個位元組存儲。

當DataPoint Value為float型的時候,使用8個位元組表示。

多位元組

按照時間戳的順序,把多個Value拼接起來的資料模型如下:

OpenTSDB原理系列-資料表設計Annotation資料
  • 每個格子表示一個DataPoint Value的值,這個DataPoint Value的長度可能是1或2或4或8個位元組。
  • DataPoint Value的順序與Qualifier中時間戳的順序一一對應。
  • 混合标志:如果最後1個位元組為0x01,表示存在秒級類型和毫秒級類型混合的情況。

Annotation資料

Annotation用于描述某一個時間點發生的事件,Annotation的資料為字元串類型,這與數字類型的metrics資料并不同。

注意:
  1. Annotation資料隻支援秒級時間戳的資料。
  2. Annotation資料不會合并。

Annotation RowKey設計

RowKey的資料模型如下圖:

OpenTSDB原理系列-資料表設計Annotation資料
  • SALT/ Timestamp/Metric UID/ tagKey UID /tagValue UID的意義與metrics RowKey中的意義相同。
  • 把[Metric UID/ tagKey UID /tagValue UID]部分統稱為TSUID。實際上,讀寫注釋資料的時候,需要指定的是TSUID,而不是像metrics資料中那樣分開指定的。

Annotation Qualifier設計

由于注釋資料隻支援秒級類型的資料,同時注釋類型的資料不支援合并,是以Qualifier的設計相對metrics資料簡單一些。Qualifier定義如下:

OpenTSDB原理系列-資料表設計Annotation資料
  • 與metrics資料的Qualifier相比,注釋資料的HBase Qualifer的長度是3個位元組。
  • 标志位:使用第1個位元組表示,而且值必須為0x01。即(qualifier & 0xFF0000)>>>16 == 0x01。
  • 時間戳:使用第2到第3個位元組表示。即時間戳的值為(qualifier & 0x00FFFF)。

Annotation Value設計

注釋資料中的Value儲存的是字元串類型的資料,整個HBase Value部分就是注釋資料的值。

Append模式

當OpenTSDB啟動APPEND模式後,每個插入的新DataPoint,都會以HBase的append的方式寫入。

注意:
  1. 由于使用了HBase的append的接口,每次插入一個新資料,都需要對同一小時的資料都執行一次讀取和插入的操作;另外多線程對同一小時的資料進行更新的時候,是不能并發的。這樣就大大限制了資料寫入的速度了,一般情況下不建議使用這種模式。
  2. append的資料其實就是合并過的資料了,是以不會參與OpenTSDB的Compaction流程。

Append模式RowKey設計

Append模式的RowKey設計與普通模式下寫入的metrics資料的RowKey是相同的。

Append模式Qualifier設計

Append模式下,由于同1小時的資料中不存在多個Qualifier,是以隻需要使用一個固定的Qualifier即可。

OpenTSDB原理系列-資料表設計Annotation資料
  • Append模式的Qualifier使用3個位元組表示
  • 标志位: 由第1個位元組表示,而且值必須為0x05。即(qualifier & 0xFF0000)>>>16 == 0x05
  • 固定部分:由第2到第3個位元組表示,這部分的值固定為0x0000,是以,Append模式的Qualifier固定為0x050000

Append模式Value設計

Append模式下, Value部分既要儲存時間戳,數值類型和數值長度,也要儲存對應的數值。

Value的資料結構如下:

OpenTSDB原理系列-資料表設計Annotation資料
  • 上圖每一個方塊表示的Qualifier與Value的定義,與普通寫入模式下的定義相同
  • 周遊Value中的所有DataPoint的方法是:
    • 從左到右,先判斷前4個bit是否為0xF
    • 如果是,則目前DataPoint是毫秒型的讀取4個位元組形成一個毫秒型的Qualifier,從Qualifier中獲得Value的長度,然後再讀取對應長度的位元組數
    • 如果否,則目前DataPoint是秒型的,讀取2個位元組形成一個秒型的Qualifier,從Qualifier中獲得Value的長度,然後再讀取對應長度的位元組數;
    • 依此疊代即可周遊所有的DataPoint。

本文首發于:NoSQL漫談(nosqlnotes.com)

歡迎掃描關注公衆号"NoSQL漫談":

OpenTSDB原理系列-資料表設計Annotation資料

繼續閱讀