Hbase高级应用:建表高级属性、行键设计、设计原则、热点问题
Hbase建表高級屬性
1、BLOOMFILTER
默認是NONE 是否使用布隆過慮及使用何種方式?
布隆過濾可以每列族單獨啟用。?
使用?HColumnDescriptor.setBloomFilterType(NONE | ROW | ROWCOL)?對列族單獨啟用布隆。
- Default = ROW 對行進行布隆過濾。
- 對 ROW,行鍵的哈希在每次插入行時將被添加到布隆。
- 對 ROWCOL,行鍵 + 列族 + 列族修飾的哈希將在每次插入行時添加到布隆?
使用方法: create ‘table’,{BLOOMFILTER =>’ROW’}?
啟用布隆過濾可以節省讀磁盤過程,可以有助于降低讀取延遲
2、VERSIONS
默認是1 這個參數的意思是數據保留1個 版本,如果認為我們的老版本數據對我們毫無價值不需要保留這么多,且更新頻繁,那將此參數設為1 能節約2/3的空間。?
使用方法:?create 'table',{VERSIONS=>'2'}
附:MIN_VERSIONS => ‘0’是說在compact操作執行之后,至少要保留的版本
3、COMPRESSION
默認值是NONE 即不使用壓縮?
這個參數意思是該列族是否采用壓縮,采用什么壓縮算法?
使用方法:?create 'table',{NAME=>'info',COMPRESSION=>'SNAPPY'}?
建議采用SNAPPY壓縮算法?
HBase中,在Snappy發布之前(Google 2011年對外發布Snappy),采用的LZO算法,目標是達到盡可能快的壓縮和解壓速度,同時減少對CPU的消耗;?
在Snappy發布之后,建議采用Snappy算法(參考《HBase: The Definitive Guide》),具體可以根據實際情況對LZO和Snappy做過更詳細的對比測試后再做選擇。
| GZIP | 13.4% | 21 MB/s | 118 MB/s |
| LZO | 20.5% | 135 MB/s | 410 MB/s |
| Zippy/Snappy | 22.2% | 172 MB/s | 409 MB/s |
如果建表之初沒有壓縮,后來想要加入壓縮算法,可以通過alter修改schema
4、alter
使用方法:?
如 修改壓縮算法
但是需要執行major_compact 'table'?命令之后 才會做實際的操作。
5、TTL
默認是 2147483647 即:Integer.MAX_VALUE 值大概是68年?
這個參數是說明該列族數據的存活時間,單位是s?
這個參數可以根據具體的需求對數據設定存活時間,超過存過時間的數據將在表中不在顯示,待下次major compact的時候再徹底刪除數據.?
注意的是TTL設定之后 MIN_VERSIONS=>’0’ 這樣設置之后,TTL時間戳過期后,將全部徹底刪除該family下所有的數據,如果MIN_VERSIONS 不等于0那將保留最新的MIN_VERSIONS個版本的數據,其它的全部刪除,比如MIN_VERSIONS=>’1’ 屆時將保留一個最新版本的數據,其它版本的數據將不再保存。
6、describe ‘table’
這個命令查看了create table 的各項參數或者是默認值。
7、disable_all ‘toplist.*’
disable_all 支持正則表達式,并列出當前匹配的表的如下:?
toplist_a_total_1001?
toplist_a_total_1002?
toplist_a_total_1008?
toplist_a_total_1009?
toplist_a_total_1019?
toplist_a_total_1035?
…?
Disable the above 25 tables (y/n)? 并給出確認提示.
8、drop_all
這個命令和disable_all的使用方式是一樣的
9、hbase 表預分區—-手動分區
默認情況下,在創建HBase表的時候會自動創建一個region分區,當導入數據的時候,所有的HBase客戶端都向這一個region寫數據,直到這個region足夠大了才進行切分。一種可以加快批量寫入速度的方法是通過預先創建一些空的regions,這樣當數據寫入HBase時,會按照region分區情況,在集群內做數據的負載均衡。?
命令方式:
也可以使用api的方式:
bin/hbase org.apache.hadoop.hbase.util.RegionSplitter test_table HexStringSplit -c 15 -f info參數:
- test_table是表名
- HexStringSplit 是split 方式
- -c 是分15個region
- -f 是family
可在Web上查看結果,如圖:?
這樣就可以將表預先分為15個區,減少數據達到storefile 大小的時候自動分區的時間消耗,并且還有以一個優勢,就是合理設計rowkey 能讓各個region 的并發請求平均分配(趨于均勻) 使IO 效率達到最高,但是預分區需要將filesize 設置一個較大的值,hbase.hregion.max.filesize 這個值默認是10G 也就是說單個region 默認大小是10G,?
這個參數的默認值在0.90 到0.92到0.94.3各版本的變化:256M–1G–10G?
但是如果MapReduce Input類型為TableInputFormat 使用hbase作為輸入的時候,就要注意了,每個region一個map,如果數據小于10G 那只會啟用一個map 造成很大的資源浪費,這時候可以考慮適當調小該參數的值,或者采用預分配region的方式,并將檢測如果達到這個值,再手動分配region。
?
行鍵設計
表結構設計
1、列族數量的設定
以用戶信息為例,可以將必須的基本信息存放在一個列族,而一些附加的額外信息可以放在另一列族;
2、行鍵的設計
語音詳單:?
13877889988-20150625?
13877889988-20150625?
13877889988-20150626?
13877889988-20150626?
—-將需要批量查詢的數據盡可能連續存放?
CMS系統—多條件查詢?
盡可能將查詢條件關鍵詞拼裝到rowkey中,查詢頻率最高的條件盡量往前靠?
20150230-zhangsan-category…?
20150230-lisi-category…?
Category+20150230 20150230-zhangsan-category?
(每一個條件的值長度不同,可以通過做定長映射來提高效率)
?
Hbase的設計原則
HBase是三維有序存儲的,通過rowkey(行鍵),column key(column family和qualifier)和TimeStamp(時間戳)這個三個維度可以對HBase中的數據進行快速定位。
HBase中rowkey可以唯一標識一行記錄,有以下3種查詢方式:
- 通過get方式,指定rowkey獲取唯一一條記錄
- 通過scan方式,設置startRow和stopRow參數進行范圍匹配
- 全表掃描,即直接掃描整張表中所有行記錄
1、rowkey長度原則
rowkey是一個二進制碼流,可以是任意字符串,最大長度64kb,實際應用中一般為10-100bytes,以byte[]形式保存,一般設計成定長。?
建議越短越好,不要超過16個字節,原因如下:
- 數據的持久化文件HFile中是按照KeyValue存儲的,如果rowkey過長,比如超過100字節,1000w行數據,光rowkey就要占用100*1000w=10億個字節,將近1G數據,這樣會極大影響HFile的存儲效率;
- MemStore將緩存部分數據到內存,如果rowkey字段過長,內存的有效利用率就會降低,系統不能緩存更多的數據,這樣會降低檢索效率。
2、rowkey散列原則
如果rowkey按照時間戳的方式遞增,不要將時間放在二進制碼的前面,建議將rowkey的高位作為散列字段,由程序隨機生成,低位放時間字段,這樣將提高數據均衡分布在每個RegionServer,以實現負載均衡的幾率。如果沒有散列字段,首字段直接是時間信息,所有的數據都會集中在一個RegionServer上,這樣在數據檢索的時候負載會集中在個別的RegionServer上,造成熱點問題,會降低查詢效率。
3、rowkey唯一原則
必須在設計上保證其唯一性,rowkey是按照字典順序排序存儲的,因此,設計rowkey的時候,要充分利用這個排序的特點,將經常讀取的數據存儲到一塊,將最近可能會被訪問的數據放到一塊。
?
熱點問題
HBase中的行是按照rowkey的字典順序排序的,這種設計優化了scan操作,可以將相關的行以及會被一起讀取的行存取在臨近位置,便于scan。然而糟糕的rowkey設計是熱點的源頭。
熱點發生在大量的client直接訪問集群的一個或極少數個節點(訪問可能是讀,寫或者其他操作)。大量訪問會使熱點region所在的單個機器超出自身承受能力,引起性能下降甚至region不可用,這也會影響同一個RegionServer上的其他region,由于主機無法服務其他region的請求。
設計良好的數據訪問模式以使集群被充分,均衡的利用。為了避免寫熱點,設計rowkey使得不同行在同一個region,但是在更多數據情況下,數據應該被寫入集群的多個region,而不是一個。
下面是一些常見的避免熱點的方法以及它們的優缺點
1、加鹽
這里所說的加鹽不是密碼學中的加鹽,而是在rowkey的前面增加隨機數,具體就是給rowkey分配一個隨機前綴以使得它和之前的rowkey的開頭不同。分配的前綴種類數量應該和你想使用數據分散到不同的region的數量一致。加鹽之后的rowkey就會根據隨機生成的前綴分散到各個region上以避免熱點。
2、哈希
哈希會使同一行永遠用一個前綴加鹽。哈希也可以使負載分散到整個集群,但是讀卻是可以預測的。使用確定的哈希可以讓客戶端重構完整的rowkey,可以使用get操作準確獲取某一個行數據。
3、反轉
第三種防止熱點的方法是反轉固定長度或者數字格式的rowkey。這樣可以使得rowkey中經常改變的部分(最沒有意義的部分)放在前面。這樣可以有效的隨機rowkey,但是犧牲了rowkey的有序性。
反轉rowkey的例子以手機號為rowkey,可以將手機號反轉后的字符串作為rowkey,這樣的就避免了以手機號那樣比較固定開頭導致熱點問題。
4、時間戳反轉
一個常見的數據處理問題是快速獲取數據的最近版本,使用反轉的時間戳作為rowkey的一部分對這個問題十分有用,可以用 Long.Max_Value - timestamp 追加到key的末尾,例如 [key][reverse_timestamp] , [key] 的最新值可以通過scan [key]獲得[key]的第一條記錄,因為HBase中rowkey是有序的,第一條記錄是最后錄入的數據。
比如需要保存一個用戶的操作記錄,按照操作時間倒序排序,在設計rowkey的時候,可以這樣設計:?
[userId反轉][Long.Max_Value - timestamp],在查詢用戶的所有操作記錄數據的時候,直接指定反轉后的userId,startRow是[userId反轉][000000000000],stopRow是[userId反轉][Long.Max_Value - timestamp]
如果需要查詢某段時間的操作記錄,startRow是[user反轉][Long.Max_Value - 起始時間],stopRow是[userId反轉][Long.Max_Value - 結束時間]
注意:?
盡量減少行和列的大小在HBase中,value永遠和它的key一起傳輸的。當具體的值在系統間傳輸時,它的rowkey,列名,時間戳也會一起傳輸。如果你的rowkey和列名很大,甚至可以和具體的值相比較,那么你將會遇到一些有趣的問題。HBase storefiles中的索引(有助于隨機訪問)最終占據了HBase分配的大量內存,因為具體的值和它的key很大。可以增加block大小使得storefiles索引再更大的時間間隔增加,或者修改表的模式以減小rowkey和列名的大小。壓縮也有助于更大的索引。?
列族盡可能越短越好,最好是一個字符。?
冗長的屬性名雖然可讀性好,但是更短的屬性名存儲在HBase中會更好。
總結
以上是生活随笔為你收集整理的Hbase高级应用:建表高级属性、行键设计、设计原则、热点问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hbase寻址机制
- 下一篇: Spark算子:RDD创建操作