我們通過行鍵訪問HBase。盡管使用掃描過濾器可以一次性指明大量的鍵,但是HBase僅僅能夠根據行鍵識別出一行。
優秀的行鍵設計可以保證良好的HBase性能。
1、行鍵存在於HBase中的每一個單元格中。如果行鍵越長,用於存儲單元格的I/O開銷就會越大。通常我們采用MD5加密的定長鍵來代替行鍵。
2、對於組合式行鍵,每個組件的排序順序取決於訪問模式
如果是一個以主機名和事件類型存儲的日志數據庫,可能的鍵值選取方法有以下幾種:
[主機名][事件類型][時間戳] :適用於訪問模式使用主機名和事件類型查詢日志的方式。
[事件類型][時間戳][主機名] : 適用於訪問模式使用事件類型和時間戳查詢日志的方式。
[事件類型][反轉時間戳][主機名] : 反轉時間戳的值是Long.MAX_VALUE減去時間戳,這樣可以確保最近發生的時間排在前面。適用於按照事件發生順序進行處理的場合。
-
單調遞增的行鍵/時序數據
在一個集群中,一個導入數據的進程一動不動,所有的client都在等待一個region(就是一個節點),過了一會后,變成了下一個region...如果使用了單調遞增或者時序的key就會造成這樣的問題。使用了順序的key會將本沒有順序的數據變得有順序,把負載壓在一台機器上。所以要盡量避免時間戳或者(e.g. 1, 2, 3)這樣的key。
-
盡量最小化行名和列名的字段大小
在HBase中,值是作為一個單元(Cell)保存在系統的中的,要定位一個單元,需要行,列名和時間戳。通常情況下,如果你的行和列的名字要是太大(甚至比value的大小還要大)的話,你可能會遇到一些有趣的情況。在HBase的存儲文件中,有一個索引用來方便值的隨機訪問,但是訪問一個單元的坐標要是太大的話,會占用很大的內存,這個索引會被用盡。所以要想解決,可以設置一個更大的塊大小,當然也可以使用更小的列名。壓縮也能得到更大指數。大部分時候,小的低效不會影響很大。不幸的是,這里會是個問題。無論是列族,屬性和行鍵都會在數據中重復上億次。所以我們設計habse時候盡量遵循以下幾點:
一. 盡量使列族名小,最好一個字符
二. 雖然詳細屬性名易讀,最好還是用短屬性名 (e.g., "via") 保存到HBase.不建議使用詳細屬性名
三. 讓行鍵短到可讀即可,這樣對獲取數據有用(e.g., Get vs. Scan)。 短鍵對訪問數據無用,並不比長鍵對get/scan更好。設計行鍵需要權衡。
四. long 類型有 8 字節. 8字節內可以保存無符號數字到18,446,744,073,709,551,615. 如果用字符串保存--假設一個字節一個字符--,需要將近3倍的字節數。
-
倒序時間戳
一個數據庫處理的通常問題是找到最近版本的值。采用倒序時間戳作為鍵的一部分可以對此特定情況有很大幫助。也在Tom White的Hadoop書籍的HBase 章節能找到: The Definitive Guide (O'Reilly), 該技術包含追加(Long.MAX_VALUE - timestamp) 到key的后面,如 [key][reverse_timestamp].表內[key]的最近的值可以用[key]進行 Scan 找到並獲取第一個記錄。由於 HBase 行鍵是排序的,該鍵排在任何比它老的行鍵的前面,所以必然是第一個。
-
行鍵永遠不變
行鍵不能改變。唯一可以“改變”的方式是刪除然后再插入。這是一個網上常問問題,所以要注意開始就要讓行鍵正確