【Hbase】初識HBase(一些HBase學習筆記)

0X01

HBase從Google的bigtable論文發展而來,遵循着Key/value鍵值對、列存儲模型。

0X02 行健-Rowkey

Rowkey,一些地方翻譯爲行健,在HBase中用來唯一標識表中一行記錄,不存在兩行Rowkey一致的記錄,且只能通過Rowkey進行行的查詢,不存在其他列作爲查詢/過濾條件的方式(可以通過對其他列值和對應的rowkey建一個索引表進行二級查詢來實現)。
Rowkey在內部是以一個字節數組的方式進行存儲,每一行數據根據rowkey的字段排序順序進行排列存儲。
Rowkey行鍵的設計十分重要:因爲每一行的查找離不開對行健的檢索,而插入數據時需根據行健值進行尋址,故行健的設計影響行的存儲和查詢速度。當行健設計沒有考慮足夠多的情況時,可能會出現多行記錄的Rowkey一致的情況,一般情況下HBase會將此種情況視爲同一行的不同(時間)版本來存儲記錄,若重複記錄數超過最大保存版本數時,會使得有用的數據丟失。最直接的解決辦法就是通過修改每列保存的最大版本數來防止數據丟失,但此種辦法並不萬全。一是每一列重複版本數(因爲HBase是列存儲結構,所以版本是針對每一列的,並不是針對一行,故當我們查詢某一行時,系統默認給出每一列最新版本的值,有的列版本可能是1有的可能是3有的可能是…)是多少不能準確預估,二是由於表記錄是根據行健的值的字典排列順序分配存儲位置的,大量相同的行健或者具有相同的行健前綴的情況,比如用戶數據都是以“user”爲前綴,則會導致大量記錄擠壓在某一個節點上,造成I/O壓力,有違分佈式的初衷。
實踐見真知:爲了便於查詢訂單信息,工程師在HBase中構建了訂單信息庫,一開始採用了“訂單號+時間”的行健組合方式,由於訂單號爲順序產生的id,一開始插入數據時,數據會一直往某一或者某幾個節點寫入,這幾個節點的Region分裂情況十分頻繁,而其他節點則比較空閒,運營時間一長就會出現節點宕機甚至由一個節點引起的整個集羣雪崩式宕機的情況。解決方案:“hash(訂單號)+創建時間”。單純以訂單號或者訂單創建時間作爲前綴都不好,使用hash(訂單號)的方式可以得到打散Rowkey分佈的效果,加上創建時間是爲了滿足通過創建時間來查詢,若訂單號出現重號也能提高唯一性,如果有需要通過其他列值來查詢,可以採用“hash(訂單id)+列1+列2…”的方式,但要注意Rowkey過長的問題,Rowkey過長也會制衡行的寫入和掃描效率。

0X03 分區-Region

Region,即表的物理分區,HBase中一個表會有一個到多個Region,通常一個集羣內每個Region的大小是固定的,便於內部根據當前寫入位置所在的Region的大小來決定是否一分爲二(分裂),是均衡負載的基本單元,每個Region存儲着Rowkey排序連續的一批數據且分佈在指定一個RegionServer上。
稀疏矩陣,HBase表中行是原子的可以加鎖,但是每一行擁有的列修飾符、列數量不盡相同,每行不需要執行嚴格的列定義,即所謂“Schema-less”。因爲HBase中不會存儲空值,所以當某一行某列爲空時,元數據不會記錄該列,從而形成稀疏矩陣。

0X04 列簇/列族-ColumnFamily

ColumnFamily,列簇/列族,一個或者多個列組成一個列族(下稱CF),因CF需要在建表時定義好且無法在建表後修改,故每行會有相同的CF定義、每個表至少擁有一個CF,但每個CF中實際擁有的列因行而異(即稀疏矩陣)。
列修飾符,列不需要提前聲明,只需要在插入數據時指定數據值對應的列修飾符即可,同時需要指定該列所屬的CF(空值不做插入操作),故CF和列修飾符是一對多關係,HBase內部通過CF找到列,同一CF下所有列數據物理上會存儲到一起,同一CF下的列也是順序排列的。
關於建表時CF指定多少的問題。HBase表設計時CF量不宜過多,需要從物理存儲、I/O方式來說明(以下說明參考自博客 https://my.oschina.net/nk2011/blog/796715) :一個HBase表含有一個到多個Region,每個Region含有一個到多個HBaseStore存儲塊,每個HBaseStore自帶一個元數據記錄和多個數據文件StoreFile/HFile,通常一個CF會對應一個HBaseStrore,Region大小達到閥值會自動分裂,一個表存在多列簇時:
A.一個Region中含有多個HBaseStore,如果每個CF中數據量分佈不均勻,如CF1爲100w,CF2爲2w,則單個Region中的CF2佔比不高,隨着表數據量增長Region不斷分裂,如若需要批量查詢CF2的數據時,可能需要跨越(比CF1)更多個Region去查詢,增加了尋址壓力,降低查詢效率;
B.多個CF的情況下,每個Region下需要記錄多個元數據,由於元數據是實時加載到內存的,這樣會增加節點RegionServer的內存壓力;
C.HBase以Region爲單位進行緩存刷新和壓縮操作,CF越多,需要對單個Region的刷新和壓縮操作次數越多,增加I/O壓力。

0X05 版本

同一cell(定位數據的最小單位)根據插入的時間先後,可以保存多個版本的值(歷史軌跡的留存),可通過對應的列修飾符指定需要保存的版本上限數,一般保留5個歷史版本,可通過指定版本號查詢歷史記錄。如果查詢時沒指定所要查詢的版本號,HBase默認返回最新的版本。RDBMS中的表是二維的,而在bigdata存儲模型上,可以看作是三維的(行+列+時間)。
至此,我們已經可以清晰看到,在HBase某個表中,通過行(Rowkey行鍵)、CF列簇、列修飾符和版本號才能唯一確定一個cell中的data(四維結構)。Cell是最小確定的數據單元,cell中的數據不需要指定對應的數據類型,統一以字節碼的形式存儲。

0X06其他

Enable修飾符,修飾某一表,使之有效可用可訪問。
HBase中不能使用join操作,一般通過設置大寬表來實現數據串聯。
通常在hadoop存儲中,對數據離線批處理是有利的,但在實時查詢時顯得臃腫。在HBase中通過Key-Value鍵值對來支持實時查詢,而通過Map-Reduce來支持批處理。
End

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章