HBase學習總結(5):HBase表設計,hbase表
一、如何開始模式設計
當我們說到模式(schema),要考慮以下內容:
(1)這個表應該有多少個列族?
(2)列族使用什麼資料?
(3)每個列族應該有多少列?
(4)列名應該是什嗎?(儘管列名不必在建表時定義,但是讀寫資料時是需要知道的。)
(5)單元存放什麼資料?
(6)每個單中繼存放區多少個時間版本?
(7)行鍵結構是什嗎?應該包括什麼資訊?
1.問題建模
一個特定列族的所有資料在HDFS上會有一個實體儲存體。這個實體儲存體可能由多個HFile組成,理想情況下可以通過合并得到一個HFile。一個列族的所有列在硬碟上存放在一起,使用這個特性可以把不同訪問模式的列放在不同列族,以便隔離它們。這也是HBase被稱為面向列族的儲存(column-family-oriented store)的原因。
在模式設計流程中儘早定義訪問模式,以便通過它們檢驗你的設計決定。
為了定義訪問模式,第一步最好定義想使用表來回答什麼問題。
2.需求定義:提前多做準備工作總是有好處的
列限定符可以按資料處理,就像值。這和關係型系統不同,關係型系統的列名是固定的並且需要在建表時預先定義。
HBase沒有跨行事務的概念,要避開在用戶端代碼裡需要事務邏輯的設計,因為這會讓你不得不維護複雜的用戶端。
3.均衡分布資料和負載的建模方法
HBase的運算速度涉及很多考量因素。具體包括:
(1)表中KeyValue條目數量(包括put的結果和delete留下的墓碑標記)。
(2)HFile裡資料區塊(HFile block)的數量。
(3)平均一個HFile裡KeyValue條目的數量。
(4)每行裡列的平均數量。
e代表任何指定時間在MemStore裡的條目數量,因為MemStore是使用跳錶(skip list)實現的,所以尋找行的時間複雜度是O(log e)。
寬表(wide table)的一行包括很多列。高表(tall table)是一種新模式,HFile裡的KeyValueObject Storage Service列族名字,使用短的列族名字在減少硬碟和網路I/O方面很有協助。
HBase語境中的熱點指的是負載極度集中在一小部分region上。因為負載沒有分散在整個叢集上,這是不合理的。服務這些region的幾台機器承擔了絕大部分工作,將成為整體效能的瓶頸。
4.目標資料訪問
HBase表裡只有鍵(KeyValue對象的Key部分,包括行鍵、列限定符和時間戳記)可以建立索引。訪問一個特定行的唯一辦法是通過行鍵。
在列限定符和時間戳記上建立索引,可以讓你在一行上不用掃描前面所有的列而直接跳到正確的列。
從表中擷取資料有兩種方式,即get和scan。如果需要一行,可以使用get調用,這種情況下必須提供行鍵;如果想執行一次掃描(scan),如果知道起始和停止鍵,可以選擇使用它們來限制掃描器對象掃描的行數。
根據指定的鍵的某個部分,可以限制讀取硬碟的資料量或者網路傳輸的資料量。指定行鍵則只返回需要的行,但是伺服器返回整行給用戶端。指定列族讓你進一步限制讀取行的什麼部分,因為如果行鍵跨多個列族,可以唯讀取HFile的一個子集。進一步指定列限定符和時間戳記,可以讓你減少返回用戶端的列數,因此節省了網路I/O。
把資料放入單元值和把它放入列限定符或行鍵將佔用相同的儲存空間,但是把資料從單元移到行鍵將可能得到更好的效能。
一些基礎知識:
(1) HBase表很靈活,可以用字元數組形式儲存任何東西。
(2) 在同一列族裡儲存相似訪問模式的所有資料。
(3) 索引建立在KeyValue對象的Key部分上,Key由行鍵、列限定符和時間戳記按次序組成。
(4) 高表可能支援你把運算複雜度降到O(1),但是要在原子性上付出代價。
(5) 設計HBase模式時進行反正常化處理是一種可行的辦法。
(6) 想想如何能夠在單個API調用裡而不是多個API調用裡完成訪問模式。HBase不支援跨行事務,要避免在用戶端代碼裡維護這種複雜的邏輯。
(7) 散列支援定長鍵和更好的資料分布,但是失去了排序的好處。
(8) 列限定符可以用來儲存資料,就像單元一樣。
(9) 因為可以把資料放入列限定符,所以它的長度影響儲存空間。當訪問資料時,它也影響了硬碟和網路I/O的開銷,所以盡量簡練。
(10) 列族名字的長度影響了通過網路傳回用戶端的資料大小(在KeyValue對象裡),所以盡量簡練。
二、反正常化
正常化是關係型資料庫世界的一種技術,其中每種重複資訊都會放進一個自己的表。這有兩個好處:當發生更新或刪除時,不用擔心更新指定資料所有副本的複雜性;通過儲存單一副本而不是多個副本,減少了佔用的儲存空間。需要查詢時,在SQL語句裡使用JOIN子句重新連接這個資料。
反正常化是一個相反概念。資料是重複的,存在多個地方。因為你不再需要開銷很大的JOIN子句,這使得查詢資料變得更容易、更快。
從效能觀點看,正常化為寫做最佳化,而反正常化為讀做最佳化。
三、相同表裡的混雜資料
儘可能分離不同的訪問模式。
四、行鍵設計原則
在設計HBase表時,行鍵是唯一重要的事情,應該基於預期的訪問模式來為行鍵建模。
行鍵決定了訪問HBase表時可以得到的效能。這個結論根植於兩個事實:region基於行鍵為一個區間的行提供服務,並且負責區間內每一行;HFile在硬碟上儲存有序的行。當region刷寫留在記憶體裡的行時產生了HFile。這些行已經排過序,也會有序地刷寫到硬碟上。HBase表的有序特性和底層儲存格式可以讓你根據如何設計行鍵以及把什麼放入列限定符來推理其效能表現。
關係型資料庫可以在多個列上建立索引,但HBase只能在鍵上建立索引,訪問資料的唯一辦法是使用行鍵。如果不知道想訪問的資料的行鍵,就必須掃描相當多的行。
五、I/O考慮
以下技巧針對訪問模式對設計行鍵進行最佳化。
1.為寫最佳化
應該如何把資料分散在多個region上呢?
(1)散列
如果你願意在行鍵裡放棄時間戳記資訊,使用未經處理資料的散列值作為行鍵是一種可能的解決方案。
散列演算法有一個非零碰撞機率。使用散列函數的方式也很重要。
(2)salting
在思考行鍵的構成時,salting是一種技巧。
2.為讀取最佳化
盡量把較少的HFile資料區塊讀入記憶體,來獲得要尋找的資料集。因為資料存放區在一起,每次讀取HFile資料區塊時可以比資料分散儲存時得到更多的資訊。
這裡行鍵的結構對於讀效能很重要。
3.基數和行鍵結構
有效行鍵設計不僅要考慮把什麼放入行鍵中,而且要考慮它們在行鍵裡的位置。
資訊在行鍵裡的位置和選擇放入什麼資訊同等重要。
六、從關係型到非關係型
從關係型資料庫知識映射到HBase沒有捷徑,它們是不同的思考方式。
關係型資料庫和HBase是不同的系統,它們擁有不同的設計特性,可以影響到應用系統的設計。
1.一些基本概念
關係型資料庫建模包括3個主要概念:
a.實體(entity)—映射到表(table)。
b.屬性(attribute)—映射到列(column)。
c.聯絡(relationship)—映射到外鍵(foreign-key)。
(1)實體
在關係型資料庫和HBase中,實體的容器(container)是表,表中每行代表實體的一個執行個體。使用者表中每行代表一個使用者。
(2)屬性
為了把屬性對應到HBase,必須區分至少兩種屬性類型:
a.識別屬性(identifying attribute):這種屬性可以唯一地精確識別出實體的一個執行個體(也就是一行)。關係型表裡,這種屬性構成表的主鍵(primary key)。在HBase中,這種屬性成為行鍵(rowkey)的一部分。
一個實體經常是由多個屬性識別出來的,這一點正好映射到關係型資料庫裡的複合鍵(compound keys)概念。
b.非識別屬性(non-identifying attribute):在HBase中,它們基本映射到列限定符。
(3)聯絡
邏輯關聯式模式使用兩種主要聯絡:一對多和多對多。在關係型資料庫中,把前者直接建模為外鍵(foreign key),把後者建模為串連表(junction table)。
HBase沒有內建的連接(join)或約束(constrain),幾乎不使用顯示聯絡。
2.嵌套實體
HBase的列(也叫做列限定符)不需要在設計時預先定義。它們可以是任何東西。HBase具有在一個父實體或主實體的行裡嵌套另一個實體的能力,但這遠遠不是一個靈活的模式行(flexible schema row)。
嵌套的實體是從關係型映射到非關係型的又一個工具。
如果你得到子實體的唯一方法是通過父實體,並且你希望在一個父實體的所有子實體上有事務級保護,這種技術是最正確的選擇。
七、列族進階配置
1.可配置的資料區塊大小
HFile資料區塊大小可以在列族層次設定。資料區塊索引儲存每個HFile資料區塊的起始鍵。資料區塊大小配置會影響資料區塊索引的大小。資料區塊越小,索引越大,因而佔用的記憶體空間越大。同時,因為載入進記憶體的資料區塊更小,隨機尋找效能更好。
2.資料區塊緩衝
把資料放進讀緩衝,但工作負載卻經常不能從中獲得效能提升。
3.激進緩衝
可以選擇一些列族,賦予它們在資料區塊緩衝裡有更高的優先順序(LRU緩衝)。
4.布隆過濾器
布隆過濾器允許對儲存在每個資料區塊的資料做一個反向測試。當某行被請求時,先檢查布隆過濾器,看看該行是否不在這個資料區塊中。
5.存留時間(TTL)
HBase可以讓你在數秒內在列族級設定一個TTL,早於指定TTL值的資料在下一次大合并時會被刪除。如果你在同一單元上有多個時間版本,早於設定TTL的版本會被刪除。
6.壓縮
HFile可以被壓縮並存放在HDFS上,HBase可以使用多種壓縮編碼,包括LZO、Snappy和GZIP。
注意,資料只在硬碟上是壓縮的,在記憶體裡或通過網路傳輸時是沒有壓縮的。
7.單元時間版本
在預設情況下,HBase每個單元維護3個時間版本,這個屬性是可以設定的。
同時也可以指定列族儲存的最少時間版本數。
八、過濾資料
過濾器也被稱為下推判斷器,支援你把資料過濾標準從用戶端下推到伺服器。
較為常用的過濾器包括:
1.行過濾器
這是一種預裝的比較過濾器,支援基於行鍵過濾資料。
2.首碼過濾器
這是行過濾器的一種特例,它基於行鍵的首碼值進行過濾。
3.限定符過濾器
它是一種類似於行過濾器的比較過濾器,不同之處是它用來匹配列限定符而不是行鍵。它使用與行過濾器相同的比較子和比較子類型。
4.值過濾器
它提供了與行過濾器或限定符過濾器一樣的功能,只是針對的是單元值。
5.時間戳記過濾器
它允許針對返回給用戶端的時間版本進行更細粒度的控制。
6.過濾器列表
組合使用多個過濾器經常是很有用的。
九、小結
模式設計的出發點是問題,而不是關係。
模式設計永遠不會結束。
資料規模是第一本質性的因素。
每個維度都是一個提升效能的機會。
本人公眾號:zhouzxi,請掃描以下二維碼:
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。