表結構設計之 高表 與 寬表 選擇
HBase 中的表可以設計為高表
(tall-narrow table
) 和 寬表(flat-wide table)。
高表 : 列少而行多。
寬表 : 行少而列多。
根據之前介紹的 KeyValue 信息的篩選粒度信息,用戶應當盡量將需要查詢的維度或信息存儲在行鍵中,因為他的篩選數據的效率最高。此外,HBase只能按行分片,因此高表更有優勢。設想用戶將一個電子郵件都存儲在一行中。這在大部分情況下都是合適的,但是也有人的收件箱中有大量的郵件。 大到一行數據就超過了最大 HFile 的限制,此時這個 HFile 無法拆分,同時也導致 region無法再合適的位置進行拆分。解決此問題的最好辦法是把一個用戶的每個電子郵件都存在單獨的一行中,而行鍵可以是用戶 userId 和消息 mesageId 的組合。

郵件系統。 用 userid + messageId(uuid)
因為 HBase 的行級原子性 可以根據用戶是否批量修改 VALUE 內容
如果一個首檢想中的數據現在分布在多行中,所以高表不可能在一次簡單的操作中修改一個收件箱的全局屬性, 如果用戶不需要一次修改整個收件箱中所有郵件的消息,高表設計就非常合適。 如果用戶有這種修改全局的需求,寬表將更加適合。因為HBase 能保證數據操作的行級原子性。
表結構設計之 數據塊大小 選擇( 65535 )
數據塊小—索引大—占用更大的內存。 (同時加載進內存的數據塊越小,
隨機查找性能
就更好)
相反如果需要更好的
序列掃描
性能,那么一次性加載更多的HFile數據進入內存更為合理。這意味着應該講
數據塊設置為更大的值。相應的,索引變小
,將在隨機讀性能上付出更多的代價。
HFile 數據塊大小可以在列族層次設置。這個數據塊不同於之前談到的HDFS數據塊,默認值是65535字節,或65KB。數據塊索引存儲每個HFile數據塊的起始鍵。數據塊大小的設置影響數據塊索引的大小。
hbase(main):> create 'mytable',{NAME => 'colfaml',BLOCKSIZE => '65535'}
表結構
設計之
數據塊緩存 ( OPEN )
把數據放入緩存,並不是一定能夠提升性能。如果一個表的列族只被順序化掃描訪問 或 很少被訪問,則get scan操作花費時間長是可以接受的。 這種情況下可以選擇關閉列族的緩存。
如果執行多次順序化掃描(多次使用緩存)並且可能會濫用魂村, 從而把應該放進緩存獲得性能提升的數據給排擠出去。如果關閉緩存,可以避免上述情況,而且可以讓出更多緩存給其他表和同一表的其他列族使用。
數據塊緩存默認是打開的。可以新建或更改表時關閉數據塊緩存屬性:
hbase(main):> create 'mytable', {NAME => 'colfam1', BLOCKCACHE => 'false' }
IN_MEMORY 參數的默認值是 false ,該值表示 HBase 除了在數據塊緩存中保存這個列族相比其他列族更激進之外,並不提供其他額外保證。該參數在實際應用中設置為 true,此時訪問性能不會變化太大。 設置IN_MEMORY:
hbase(main):> create 'mytable', {NAME => 'colfam1', IN_MEMORY => 'true'}
表結構
設計之
布隆過濾器(NONE)
布隆過濾器可以應用在塊上,檢查行鍵,也可以應用在行內的單元格上,當訪問某列表示服時先使用同樣的反向檢測
布隆過濾器允許對存儲在每個數據塊的數據做一個反向檢測。查詢行時,先查詢布隆過濾器。(Bloom Filter)。看看該行是否不存在這個數據塊, 要么返回該行不存在。要么返回不知道。
如果想要判斷一個元素是不是在一個集合里,一般想到的是將所有元素保存起來,然后通過比較確定。
鏈表
,樹等等數據結構都是這種思路. 但是隨着集合中元素的增加,我們需要的存儲空間越來越大,檢索速度也越來越慢(O(n),O(logn))。不過世界上還有一種叫作散列表(又叫
哈希表
,Hash table)的數據結構。它可以通過一個
Hash函數
將一個元素映射成一個位陣列(Bit array)中的一個點。這樣一來,我們只要看看這個點是不是1就可以知道集合中有沒有它了。這就是布隆過濾器的基本思想。
Hash
面臨的問題就是沖突。假設Hash函數是良好的,如果我們的位陣列長度為m個點,那么如果我們想將沖突率降低到例如 1%, 這個散列表就只能容納m / 100個元素。顯然這就不叫空間效率了(Space-efficient)了。解決方法也簡單,就是使用多個Hash,如果它們有一個說元素不在集合中,那肯定就不在。如果它們都說在,雖然也有一定可能性它們在說謊,不過直覺上判斷這種事情的
概率
是比較低的。
存儲這個額外的索引層需要占用額外的空間,占用的大小隨着索引對象數據增長而增長。所以行級布隆過濾器比列標識符級布隆過濾器占用空間要小。當空間不是問題時,他們可以壓榨整個系統的性能潛力
可以在列族上打布隆過濾器,代碼:
hbase(main) > create 'mytable' , {NAME=>'colfam1', BLOOMFILTER => 'ROWCOL' }
NONE 布隆過濾器默認參數 。
ROW
表示
行級布隆過濾器(檢查rowkey存不存在);
ROWCOL
表示
列標識符級布隆過濾器(檢查 rowkey 和 列限定符存不存在)。
·
為什么用布隆過濾器。 以及數據未被刷入HFile時在MemStore中。

表結構
設計之
數據壓縮
(NONE)
數據壓縮有助於節省磁盤空間,但是讀寫數據時壓縮和解壓縮會提高CPU使用率。除非確定壓縮不會提升系統的性能,否則推薦打開表的壓縮。
只有在數據不能被壓縮,或者因為某些原因服務器的 CPU 利用率有限制的情況下,有可能需要關閉壓縮特性。
HBase使用的壓縮編碼: SNAPPY擁有 BSD(BSD-licensed)許可,所以它更容易和 Hadoop 及 HBase 發行版捆綁在一起。 LZO 和 SNAPPY 的壓縮比例和壓縮 / 解壓速度差不多。
創建表時可以在列族上打開壓縮:
hbase(main)> create 'mytable' , {NAME => 'colfaml' , COMPRESSION => 'SNAPPY'}
數據只在硬盤上是壓縮的,在內存中(
MemStore 或 BlockCache
)或在網絡傳輸時是沒有壓縮的。
數據的壓縮編碼不能經常改變,如果需要改變某個列族的壓縮編碼,直接更改表定義,設定新的壓縮編碼,當Region合並時,生成的 HFile 全部會采用新的編碼壓縮。這個過程不需要創建新的表和復制數據。
表結構
設計之
單元時間版本( 3 Version ) .生存空間(Time To
Live) TTL默認68年值
如果只需要一個版本,在創建表時可以直接將 VERSION 的參數設置為1。時間版本也是列族級的。
hbase(main) > create 'mytable' , { NAME => 'colfaml', VERSION => 1}
可以在同一個建表語句中為列族設置版本 和 生命周期
hbase(main) > create 'mytable' , { NAME => 'colfaml' , VERSION => 1, TTL => '18000'} // TTL 值默認是永久保存,(2147483647)單位是秒。 此數校驗為 68 年
可以指定列族存儲的最少時間版本數。
hbase(main) > create 'mytable' , { NAME => 'colfaml' , VERSION => 5, MIN_VERSION => '1' }
TTL 生存時間,用於設置單元格的生存周期。 如果單元格過期,則會將其刪除。
早於指定時間的數據會在下一次大合並時將其刪除。
God has given me a gift. Only one. I am the most complete fighter in the world. My whole life, I have trained. I must prove I am worthy of someting.
rocky_24