隨着大數據的愈來愈普及,HBase也變得愈來愈流行。使用HBase並不困難,可是如何用好HBase,這確是一個難點。爲了合理地使用HBase,儘量發揮HBase的功能,咱們須要根據不一樣的場景對HBase進行不一樣地優化以最大程度上提高系統的性能。本文重點介紹列族設計有關的優化。咱們先來了解下HBase列族具備哪些屬性配置。算法
每一個列族能夠單獨設置行版本數,默認是3。這個設置很重要,由於HBase是不會去覆蓋一個值的,它只會在後面追加寫,用時間戳(版本號)來區分,過早的版本會在執行Major Compaction
時刪除。這個版本的值能夠根據具體的場景來增長或減小。緩存
不推薦將版本最大值設置成一個很高的水平,除非老數據對你也很是重要。過多的版本,會致使存儲文件變大,以致於影響查詢效率。bash
每一個列族能夠設置最小版本數,最小版本數缺省值是0,表示禁用該特性。最小版本數參數和存活時間是一塊兒使用的,容許配置「如保存最後T秒有價值的數據,最多N個版本,但最少M個版本」(M是最小版本,M<N)。該參數僅在存活時間對列族啓用,且必須小於行版本數。app
HBase支持配置版本數據的存活時間(TTL),TTL設置了一個基於時間戳的臨界值,HBase會自動檢查TTL值是否達到上限,若是TTL達到上限,則該數據會在Major Compaction過程中被刪除。負載均衡
hbase默認的塊大小是64kb,不一樣於HDFS默認64MB的塊大小。緣由是hbase須要支持隨機訪問,一旦找到了行鍵所在的塊,接下來就會定位對應的單元格。使用64kb的塊掃描的速度顯然優於64MB大小的塊。性能
對於不一樣的業務數據,塊大小的合理設置對讀寫性能有很大的影響。若是業務請求以Get請求爲主,能夠考慮將塊大小設置較小;若是以Scan請求爲主,能夠將塊大小調大;默認的64K塊大小是在Scan和Get之間取得的一個平衡。測試
注意:大數據
默認塊大小適用於多種數據使用模式,調整塊大小是比較高級的操做。配置錯誤將對性能產生負面影響。所以建議在調整以後進行測試,根據測試結果決定是否能夠線上使用。優化
默認是true。緩存是內存存儲,hbase使用塊緩存將最近使用的塊加載到內存中。塊緩存會根據最近最久未使用(LRU)」的規則刪除數據塊。spa
若是你的使用場景是常常順序訪問或者不多被訪問,能夠關閉列族的緩存。列族緩存默認是打開的。
HBase能夠選擇一個列族賦予更高的優先級緩存,激進緩存(表示優先級更高),IN_MEMORY
默認是false。若是設置爲true,hbase會嘗試將整個列族保存在內存中,只有在須要保存是纔會持久化寫入磁盤。可是在運行時hbase會嘗試將整張表加載到內存裏。
這個參數一般適合較小的列族。
HBase在寫入數據塊到HDFS以前會首先對數據進行壓縮,再落盤,從而減小磁盤空間使用量。而在讀數據的時候首先從HDFS中加載出block塊以後進行解壓縮,而後再緩存到BlockCache,最後返回給用戶。
使用壓縮其實就是使用CPU資源換取磁盤空間資源。
HBase支持三種壓縮方式:LZO、Snappy和GZIP。
默認爲NONE,不適用壓縮,
壓縮算法 | 壓縮比率 | 壓縮速度 | 解壓速度 |
---|---|---|---|
GZIP | 13.4% | 21 MB/s | 118 MB/s |
LZO | 20.5% | 135 MB/s | 410 MB/s |
Snappy | 22.2% | 172 MB/s | 409 MB/s |
其中:
GZIP的壓縮率最高,可是其實CPU密集型的,對CPU的消耗比其餘算法要多,壓縮和解壓速度也慢;
LZO的壓縮率居中,比GZIP要低一些,可是壓縮和解壓速度明顯要比GZIP快不少,其中解壓速度快的更多;
Snappy的壓縮率最低,而壓縮和解壓速度要稍微比LZO要快一些。
綜合來看,Snappy的壓縮率最低,可是編解碼速率最高,對CPU的消耗也最小,目前通常建議使用Snappy。
HBase提供了跨級羣同步的功能,本地集羣的數據更新能夠及時同步到其餘集羣。複製範圍(replication scope)的參數默認爲0,表示複製功能處於關閉狀態。
在默認狀況下,HBase表在剛剛被建立的時候,只有1個分區(Region),當一個Region的大小達到閾值(經過hbase.hregion.max.filesize
參數控制),Region會進行split,分裂成2個Region。可是在進行split的時候,會消耗大量的資源,頻繁的split會對HBase的性能形成巨大的影響。
HBase提供了預分區的功能,用戶能夠在建立表的時候對錶按照必定的規則提早進行分區。這樣是進行HBase數據讀寫的時候,會按照Region分區狀況,在集羣內作數據的負載均衡。
經常使用分區方法:
create 'table','cf', SPLITS => ['1', '2', '3', '4', '5', '6', '7', '8', '9']create 'table','cf', { NUMREGIONS => 8 , SPLITALGO => 'UniformSplit' }create 'table','cf', { NUMREGIONS => 10, SPLITALGO => 'HexStringSplit' } 複製代碼
BloomFilter主要用來過濾不存在待檢索RowKey或者Row-Col的HFile文件,避免無用的IO操做。它會告訴你在這個HFile文件中是否可能存在待檢索的KV,若是不存在,就能夠不用消耗IO打開文件進行seek。經過設置BloomFilter能夠提高隨機讀寫的性能。
BloomFilter是一個列族級別的配置屬性,若是在表中設置了BloomFilter,那麼HBase會在生成StoreFile時包含一份BloomFilter結構的數據,稱其爲MetaBlock
和DataBlock
(真實KeyValue數據)一塊兒由LRUBlockCache維護。因此開啓BloomFilter會有必定的存儲即內存Cache的開銷。
BloomFilter取值有兩個,row
和rowcol
,須要根據業務來肯定具體使用哪一種。
若是業務大多數隨機查詢時僅僅使用row做爲查詢條件,BloomFilter必定要設置爲row;
若是大多數隨機查詢使用row+cf做爲查詢條件,BloomFilter須要設置爲rowcol;
若是不肯定查詢類型,建議設置爲row。
不要在一張表中定義太多的列族。目前HBase並不能很好的處理2~3以上的列族,flush
和compaction
操做是針對一個Region的。
當一個列族操做大量數據的時候會引起一個flush,它鄰近的列族也會因關聯效應被觸發flush,儘管它沒有操做多少數據。compaction操做是根據一個列族下的所有文件的數量觸發的,而不是根據文件大小觸發的。
當不少的列族在flush和compaction時,會形成不少沒用的IO負載。
儘可能在模式中只針對一個列族進行操做。將使用率相近的列歸爲一個列族,這樣每次訪問就只用訪問一個列族,既能提高查詢效率,也能保持儘量少的訪問不一樣的磁盤文件。
若是一個表存在多個列族,要注意列族之間基數(如行數)相差不要太大。例如列族A有100萬行,列族B有10億行,按照RowKey切分後,列族A可能被分散到不少不少Region(及RegionServer),這致使掃描列族A十分低效。
列族名和列名越短越好,冗長的名字雖然可讀性好,可是更短的名字在HBase中更好。
一個具體的值由存儲該值的行鍵、對應的列(列族:列
)以及該值的時間戳決定。HBase中索引是爲了加速隨機訪問的速度,索引的建立是基於「行鍵+列族:列+時間戳+值
」的,若是行鍵和列族的大小過大,甚至超過值自己的大小,那麼將會增長索引的大小。而且在HBase中數據記錄每每很是之多,重複的行鍵、列將不但使索引的大小過大,也將加劇系統的負擔
根據HBase列族的這些屬性配置,結合咱們的使用場景,HBase列族能夠進行以下優化:
列族不宜過多,將相關性很強的key-value都放在同一個列族下,;
儘可能最小化行鍵和列族的大小;
提早預估數據量,再根據Rowkey規則,提早規劃好Region分區,在建立表的時候進行預分區;
在業務上沒有特別要求的狀況下,只使用一個版本,即最大版本和最小版本同樣,均爲1;
根據業務需求合理設置好失效時間(存儲的時間越短越好);
根據查詢條件,設置合理的BloomFilter配置;
合理設計RowKey,能夠參考《一篇文章帶你快速搞懂HBase RowKey設計》。