從OpenTsdb來分析rowkey設計

2021-09-02 12:25:27 字數 3079 閱讀 8221

討論此問題前,先理解乙個問題。

關於hbase熱點問題

當處理由連續事件得到的資料時,即時間上連續的資料。這些資料可能來自於某個感測器網路、**交易或者乙個監控系統。它們顯著的特點就是rowkey中含有事件發生時間。帶來的乙個問題便是hbase對於row的不均衡分布,它們被儲存在乙個唯一的rowkey區間中,被稱為region,區間的範圍被稱為start key和end key。

對於單調遞增的時間型別資料,很容易被雜湊到同乙個region中,這樣它們會被儲存在同乙個伺服器上,從而所有的訪問和更新操作都會集中到這一台伺服器上,從而在集群中形成乙個hotspot,從而不能將集群的整體效能發揮出來。

要解決這個問題是非常容易的,只需要將所有的資料雜湊到全部的region上即可。這是可以做到的,比如,在rowkey前面加上乙個非執行緒序列。

opentsdb 資料庫設計

我們來看一下它的建表語句

tsdb_table=$

uid_table=$

create '$uid_table',

,create '$tsdb_table',

表 tsdb包含乙個列族「t」,tsdb-uid包含兩個列族 id和name,在hbase中列族名字越短越有利於儲存,因為它占用的位元組數越短。

tsdb 有標籤的概念:我理解為就是指標,例如mysql.bytes_sent就是乙個指標,每個指標在tsdb表中有乙個唯一的標識unique id 簡稱uid.

tsdb_uid是 tsdb 的輔助表,用於查詢uid對應的指標或者指標對應的uid

新增乙個指標,會在這個表中增加兩行記錄,一行rowkey是指標名,id是uid,另外一行rowkey是uid,name是指標名.

在tsdb_uid表中列族 id 和name 都分別包含三列

metrics 指標名或者指標uid

tagk 標籤名或者標籤名uid

tagv 標籤值或者標籤值uid

id 列族:用來將字串對映到uid

name 列族:用來將乙個uid對映到乙個字串

例如 我要儲存 host=web、user=admin、project=uc 的web訪問量(web.pv)

[img]

tsdb表中其實 僅用到和rowkey 列族t是沒有用到的,知識因為hbase規定必須至少有乙個列族。tsdb表的rowkey設計很值得我們去了解。

[table]

|監控指標uid(3byte)|部分時間戳(4byte)|標籤1名uid(3byte)|標籤1值uid(3byte)|....|

[/table]

在opentsdb中,所有資料儲存在tsdb的表中,這是為了充分利用hbase有序和region分布式的特點。所有的值都儲存在列族t中。

rowkey為[...],

這樣設計的目的是:opentsdb以監控指標為中心的查詢進行優化,所以監控指標uid排在最前面,在同乙個監控指標中,按時間戳進行排序,行健裡時間戳儲存四捨五入到60分鐘,所以1個小時內統一監控指標的資料會儲存在一起。

opentsdb的tsdb啟動之後,會監控指定的socket埠(預設為4242),接收到監控資料,包括指標、時間戳、資料、tag標籤,tag標籤包括tag名稱id和tag值id。例如:

繼續用上面的例子

web.pv 1292148123 42 host=web user=admin project=uc

對於指標web.pv的id為:[0, 0, 1],host標籤名稱的id為:[0, 0, 2], web標籤值的id為:[0, 0, 3], 標籤名稱user的id為:[0, 0, 4] admin標籤值的id為:[0, 0, 5],標籤名稱project的id為:[0, 0, 6] uc標籤值的id為:[0, 0, 7],他們組成rowkey:

[color=red]

[0,0,1, 77,4,-99,32, 0,0,2, 0,0,3, 0,0,4, 0,0,5, 0,0,6, 0,0,7]

metricid timestamp tagk1 tagv1 tagk2 tagv2 tagk3 tagv3

[/color]

[b]可以看到,對於metric + tags相同的資料都會連續存放,且metic相同的資料也會連續存放,這樣對於scan以及做aggregation都非常有幫助[/b]

對於時間戳為1292148123的資料點來說,其轉換為以小時為單位的基準時間(去掉小時後的秒)為129214800,偏移為123,轉換為二進位制為1111011,因為該值為整數且長度為8位(對應為2byte,故最後3bit為100),故其對應的列族名為:0000011110110100,將其轉換為十六進製制為07b4

[b]opentsdb兩種查詢資料下hbase表設計優勢的體現:[/b]

1:自動補全功能

[color=red]了解此功能前首先了解一下hbase 的block cache 功能[/color]

hbase上regionserver的記憶體分為兩個部分,一部分作為memstore,主要用來寫;另外一部分作為blockcache,主要用於讀。

寫請求會先寫入memstore,regionserver會給每個region提供乙個memstore,當memstore滿64mb以後,會啟動 flush重新整理到磁碟。當memstore的總大小超過限制時(heapsize * hbase.regionserver.global.memstore.upperlimit * 0.9),會強行啟動flush程序,從最大的memstore開始flush直到低於限制。

讀請求先到memstore中查資料,查不到就到blockcache中查,再查不到就會到磁碟上讀,並把讀的結果放入blockcache。由於blockcache採用的是lru策略,因此blockcache達到上限(heapsize * hfile.block.cache.size * 0.85)後,會啟動淘汰機制,淘汰掉最老的一批資料。

hbase 在每張表的rowkey上建立索引,定位起始位置會非常快,然後通過block cache 查詢資料,連續的資料例如 mysql_*** 會連續存放在一起,scan tsdb_uid 表的 name_uid對映記錄即可快速查詢。

2:讀取時間序列資料

使用一種建立在行健上的正規表示式

可以試著讀一下源**。

分析 OpenTSDB資料的儲存

下面結合例子看看opentsdb儲存的一些核心概念 1 metric 即平時我們所說的監控項。譬如上面的 cpu 使用率。2 tags 就是一些標籤,在 opentsdb 裡面,tags 由 tagk 和 tagv 組成,即 tagk takv。標籤是用來描述metric的,譬如上面為了標記是伺服器...

從mykernel來分析linux系統的啟動過程

您只要在mymain.c基礎上繼續寫程序描述pcb和程序鍊錶管理等 在myinterrupt.c的基礎上完成程序切換 乙個可執行的小os kernel就完成了。孟老師在課程公告中對mykernel做了簡明的講解 理解和執行mykernel,它是提供初始化好的cpu從my start kernel開始...

從JMM資料原子操作來分析volatile

併發程式設計的三個性質 原子性,可見性,有序性 兩線程同時對i做i 執行緒1往記憶體寫經過匯流排時被執行緒2感知到了,執行緒2做i 的操作已經做完了,然而因為感知到i變了,做i無效化重新讀,所以執行緒2做的那次i 的操作執行了但是沒起作用 在討論原子性操作時,我們經常會聽到乙個說法 任意單個vola...