HBase表的設計(一)之表模式的設計

2022-04-19 14:26:13 字數 2543 閱讀 7960

模式影響到表結構和如何讀寫表,所以說把這些放到寬泛的模式設計中變得尤為重要。

hbase底層物理儲存是基於hdfs,在hdfs上是以hfile的形式進行儲存的:

乙個特定的列族的所有資料在hdfs上會有乙個物理儲存,這個物理儲存區可能會有多個hfile組成,理論上可以通過合併來得到乙個hfile,乙個列族的所有列在硬碟上是存放在一起的,使用這個特性,可以把不同模式的列放在不同的列族,以便隔離他們。這也是hbase面相列族儲存的原因。

hbase中所謂的寬表,指的是表中行少而列多,也就是說一行當中包含有很多的列,但是表整體行很少,比如一張表中行健一共有100個,但是每個行健所包含的列有1000個,這種就是所謂的寬表。

hbase中所謂的高表,恰好與寬表相反,行多,列少。比如一張表中行有100萬條,而每行對應的列卻又10個,這既是所謂的高表。

為了便於描述,先定義以下變數:

先定義針對指定行健查詢相關hfile資料塊需要的時間。無論是在單行上執行get(),還是為一次掃瞄查詢起始鍵,都會有這個動作。

第一步、客戶端需要先找到正確的hregionserver和region。需要花費3次固定運算找到正確的region,1、查詢zk,2、查詢-root-,3、查詢.meta.這是一次o(1)的運算。

在指定region上,行在讀的過程中可能存在於兩個地方,如果還沒有刷寫到磁碟就位於memstore,如果已經刷鞋,則位於乙個hfile中。假定只有乙個hfile,這一行要麼在檔案中,要麼還沒刷寫,在memstore中。

如果用e代表在任意合理的時間在memstore的條目數量。

如果一行在memstore中,因為memstore是用跳表實現的。所以查詢行的時間複雜度是o(log e)。

如果一行已經刷到磁碟上了,那麼就需要先找到正確的hfile資料塊。資料塊索引是排過序的,所以查詢正確的資料塊是一次時間複雜度為o(log b)的運算。查詢行裡的keyvalue物件是在資料塊裡的一次線性掃瞄操作。在找到第乙個keyvalue物件之後,隨後查詢剩下的物件就是一次線性掃瞄。

假設行裡的單元都在同乙個資料塊中,掃瞄的時間複雜度是o(e/b)。

如果行裡的單元不在同乙個資料塊中,這種掃瞄需要訪問多個連續的資料塊裡的資料,所以這時的運算有讀取的行數決定,時間複雜度是o(c)。

也就是說這種掃瞄的時間複雜度是o(max(c,e/b))

所以在訪問hbase中的資料時,決定性因素是掃瞄hfile資料塊找到相關keyvalue物件所花費的時間。如果是寬行的話,掃瞄過程中會增加處理整行的開銷。以上的這些分析都是基於在知道行健的情況下。

如果不知道行健的話,就需要掃瞄整個區間(有可能是整張表)來查詢你關心的行,而這個時間複雜度是o(n)

這裡沒有討論關於硬碟尋道的開銷。如果需要從hfile裡讀取的資料已經被載入進資料快取中,前面的分析是正確的。因為行健是所有這些索引的決定性因素,所以結論是:訪問寬行要比訪問窄行開銷大。

hbase的rowkey在設計的時候我們一般都要對其進行雜湊處理,這樣做有以下幾個好處:

熱點:負載極度集中在一小部分的region上。因為負載沒有分散的整個集群上,這是不合理的。服務這些region的幾台機器承擔了絕大部分的工作,將成為整體效能的拼勁。

對rowkey雜湊,雖然在所有region上實現了乙個均勻的分部,但是這樣的話就會失去資料的順序。換句話說,就是不能在掃瞄乙個小的時間範圍。要麼掃瞄整個表(scan),要麼獲取指定的行(get()或get(list))

雜湊函式是把程式設計的巨長數值對映到定長的小數值上的一種函式。雜湊演算法有很多種,md5就是其中的一種,也是比較常用的一種。md5對任何資料進行雜湊運算生成乙個128位(16位元組)的雜湊值。這是一種流行的雜湊函式,通常生產中,我是對rowkey進行16位的md5操作。

之前談到關於hbase的高表與寬表,高表有利於快速得到正確的行。而寬表則有利於進行批量寫操作。

對於hbase中的索引來說,只有鍵才可以建立索引(keyvalue物件的key部分,包括行健,列限定符和時間戳),可以將其看作是關係型資料庫的主鍵,但是不能夠改變構成主鍵的列,這裡的鍵是由3個元素復合而成的(行健,列限定符和時間戳)。

在列限定符和時間戳上建立索引,可以在一行上不用掃瞄前面所有的列而直接跳到正確的列。取回的keyvalue物件基本上來自於hfile的一行。

從表中獲取資料的方式有兩種,get和scan。如果只是需要獲取指定的某行或這個某幾行,也就是說在明確知道行健的情況下,建議使用get或get的方式進行獲取。

如果知道起始鍵和停止鍵,則可以使用scan的方式來限制掃瞄器掃瞄的的行數進行獲取資料。

在get物件中,可以指定列族和列限定符。當指定列族之後,可以限制客戶端只訪問指定列族的hfile;當時指定列限定符之後不會限制從硬碟中讀出的hfile,只是可以限制網路上傳回給客戶端的東西。如果給定的region上乙個列族存在多個hfile。要查詢get()呼叫裡指定的行的內容,不管有多少個hfile包含與請求有關的資料,都要訪問所有的hfile。但是get裡盡可能的明確查詢內容是有必要的,因為不必在網路上傳回客戶端不需要的資料。唯一的開銷也就是regionserver上可能的硬碟io,同樣,如果get中指定時間戳的話,可以避免讀取早於時間戳的hfile。

Hbase之表的設計

最近,由於專案的需要開始接觸hbase,發現如果想要很好的利用hbase儲存和維護利用自己的海量資料,表的設計至關重要,乙個好的表結構可以從本質上提高操作速度,直接決定了使用者的get put delete等各種操作的效率。下面我就先介紹一下hbase的基本表的構成。hbase的表是key valu...

Database之HBase表設計

1.表的設計 1.1 pre creating regions 預設情況下,在建立hbase表的時候會自動建立乙個region分割槽,當匯入資料的時候,所有的hbase客戶端都向這乙個region 寫資料,直到這 個region足夠大了才進行切分。一種可以加快批量寫入速度的方法是通過預先建立一些空的...

hbase表的設計原則

1 列族的數量及列族的勢 建議將hbase列族的數量設定的越少越好.對於兩個或兩個以上的列族hbase並不能處理的很好。這是因為hbase的flushing和壓縮是基於region的。當乙個列族所儲存的資料達到flushing的閾值時,該表中所有列族將同時進行flushing操作。這將帶來不必要的i...