帶你快速上手HBase | HBase讀寫性能優化

一個系統上線以後,開發和調優將會一直伴隨在系統的整個生命週期中,HBase也不例外。今天咱們要學習如何進行HBase讀寫性能調優,以獲取最大的讀寫效率。算法

HBase寫入優化

客戶端優化

批量寫

採用批量寫,能夠減小客戶端到RegionServer之間的RPC的次數,提升寫入性能。批量寫請求要麼所有成功返回,要麼拋出異常。數據庫

HTable.put(List<Put>);複製代碼

異步批量提交

若是業務能夠接受異常狀況下丟失少許數據,可使用異步批量提交方式提交請求。緩存

用戶提交寫請求以後,數據會先寫入客戶端緩存,並返回用戶寫入成功(此時數據併爲提交到RegionServer),當客戶端緩存達到閾值(默認2M,可經過hbase.client.write.buffer配置)時纔會批量提交給RegionServer。須要注意的是,在某些狀況下客戶端異常的狀況下緩存數據有可能丟失。性能優化

HTable.setWriteBufferSize(writeBufferSize); // 設置緩存大小HTable.setAutoFlush(false);複製代碼

多線程併發寫

客戶端開啓多個HTable寫線程,每一個寫線程負責一個HTable對象的flush操做,這樣結合定時flush和寫buffer,能夠即保證在數據量小的時候,數據能夠在較短期內被flush,同時又保證在數據量大的時候,寫buffer一滿就即便進行flush。bash

使用BulkLoad寫入

在HBase中數據都是以HFile形式保存在HDFS中的,當有大量數據須要寫入到HBase的時候,能夠採用BulkLoad方式完成。服務器

使用MapReduce或者Spark直接生成HFile格式的數據文件,而後再經過RegionServer將HFile數據文件移動到相應的Region上去。網絡

寫數據表設計調優

COMPRESSION

配置數據的壓縮算法,這裏的壓縮是HFile中block級別的壓縮。對於能夠壓縮的數據,配置壓縮算法能夠有效減小磁盤的IO,從而達到提升性能的目的。可是並非全部數據均可以進行有效壓縮,如圖片,由於圖片通常是已經壓縮後的數據,因此壓縮效果有限。經常使用的壓縮算法是SNAPPY,由於它有較好的壓縮和解壓速度和能夠接受的壓縮率。多線程

IN_MEMORY

配置表的數據優先緩存在內存中,這樣能夠有效提高讀取的性能。適合小表,並且須要頻繁進行讀取操做的。併發

預分區

在HBase中數據是分佈在各個Region中的,每一個Region都負責一個起始RowKey和結束Rowkey的範圍,在向HBase中寫數據的時候,會根據RowKey請求到對應的Region上,若是寫請求都集中在某一個Region或某幾個Region上的時候,性能確定不如寫請求均勻分佈在各個Region上好。默認狀況下,建立的HBase的只有一個Region分區,會隨着數據量的變大,進行split,拆分紅多個Region,最開始的性能確定會很很差異步

建議在設計HBase的的時候,進行預分區,並設計一個良好的Rowkey生成規則(關於RowKey設計,能夠參考《一篇文章帶你快速搞懂HBase RowKey設計》),儘可能將數據分散到各個Region上,那樣在進行HBase的讀寫的時候,對性能會有很好的改善。

合理設置WAL存儲級別

數據在寫入HBase的時候,先寫WAL,再寫入緩存。一般狀況下寫緩存延遲很低,WAL機制一方面是爲了確保數據即便寫入緩存後數據丟失也能夠經過WAL恢復,另外一方面是爲了集羣之間的複製。默認WAL機制是開啓的,而且使用的是同步機制寫WAL。

若是業務不特別關心異常狀況下部分數據的丟失,而更關心數據寫入吞吐量,可考慮關閉WAL寫,這樣能夠提高2~3倍數據寫入的吞吐量。

若是業務不能接受不寫WAL,可是能夠接受WAL異步寫入,這樣能夠帶了1~2倍性能提高。

HBase中能夠經過設置WAL的持久化等級決定是否開啓WAL機制、以及HLog的落盤方式。

WAL的持久化等級分爲以下四個等級:

  1. SKIP_WAL:只寫緩存,不寫HLog日誌。這種方式由於只寫內存,所以能夠極大的提高寫入性能,可是數據有丟失的風險。在實際應用過程當中並不建議設置此等級,除非確認不要求數據的可靠性。

  2. ASYNC_WAL:異步將數據寫入HLog日誌中。

  3. SYNC_WAL:同步將數據寫入日誌文件中,須要注意的是數據只是被寫入文件系統中,並無真正落盤,默認。

  4. FSYNC_WAL:同步將數據寫入日誌文件並強制落盤。最嚴格的日誌寫入等級,能夠保證數據不會丟失,可是性能相對比較差。

一樣,除了在建立表的時候直接設置WAL存儲級別,也能夠經過客戶端設置WAL持久化等級,代碼:

put.setDurability(Durability.SYNC_WAL);複製代碼

HBase讀取優化

客戶端優化

批量get請求

使用批量請求,能夠減小RPC的次數,顯著提升吞吐量。須要注意的是,批量get請求要麼成功返回全部請求數據,要麼拋出異常。

Result[] re= table.get(List<Get> gets);複製代碼

合理何止scan緩存大小

一次scan可能會返回大量數據,可是實際客戶端發起一次scan請求,並不會將全部數據一次性加載到本地,而是分紅屢次RPC請求進行加載,這樣設計一方面是由於大量數據請求可能會致使網絡帶寬嚴重消耗進而影響其餘業務,另外一方面是有可能由於數據量太大致使客戶端發生OOM。因此採用先加載一部分數據到本地,而後進行遍歷,每次加載一部分數據,如此往復,直至全部數據加載完成。數據加載到本地就存放在scan緩存中,默認100。

增大scan的緩存,可讓客戶端減小一次scan的RPC次數,從而從總體上提高數據讀取的效率。

scan.setCaching(int caching); //大scan能夠設置爲1000複製代碼

指定請求列族或者列名

HBase是列族數據庫,同一列族的數據存儲在一塊,不一樣列族是分開存儲的,若是一個表由多個列族,只是根據RowKey而不指定列族進行檢索的話,不一樣列族的數據須要獨立進行檢索,性能必然會比指定列族的查詢差的多。

此外指定請求的列的話,不須要將整個列族的全部列的數據返回,這樣就減小了網路IO。

scan.addColumn();複製代碼

設置只讀Rowkey過濾器

在只須要Rowkey數據時,能夠爲Scan添加一個只讀取Rowkey的filter(FirstKeyOnlyFilterKeyOnlyFilter)。

關閉ResultScanner

在使用table.getScanner以後,記得關閉,不然它會和服務器端一直保持鏈接,資源沒法釋放,從而致使服務端的某些資源不可用。

scanner.close();複製代碼

離線計算訪問HBase建議禁用緩存

當離線訪問HBase時,每每會對HBase表進行掃描,此時讀取的數據沒有必要存放在BlockCache中,不然會下降掃描的效率。

scan.setBlockCache(false);複製代碼

建議在對HBase表進行掃描時禁用緩存。

對於頻繁查詢HBase的應用場景不須要禁用緩存,而且能夠考慮在應用程序和HBase之間加一層緩存系統(如Redis),先查詢緩存,緩存沒有命中再去查詢HBase。

讀數據表設計調優

COMPRESSION

寫性能優化COMPRESSION
部分。

BLOCKSIZE

配置HFile中block塊的大小,不一樣的block大小,能夠影響HBase讀寫數據的效率。越大的block塊,配置壓縮算法,壓縮的效率就越好;可是因爲HBase的讀取數據時以block塊爲單位的,因此越大的block塊,對於隨機讀的狀況,性能可能會比較差,若是要提高寫入的性能,通常擴大到128kb或者256kb,能夠提高寫數據的效率,也不會影響太大的隨機讀性能。

DATA_BLOCK_ENCODING

配置HFile中block塊的編碼方法。當一行數據中存在多個列時,通常能夠配置爲"FAST_DIFF",能夠有效的節省數據存儲的空間,從而提高性能。

BloomFilter

優化原理:BloomFilter主要用來過濾不存在待檢索RowKey或者Row-Col的HFile文件,避免無用的IO操做。它會告訴你在這個HFile文件中是否可能存在待檢索的KeyValue,若是不存在,就能夠不用小號IO打開文件進行seek。經過設置BloomFilter能夠提高讀寫的性能。

BloomFilter是一個列族級別的配置屬性,若是列族設置了BloomFilter,那麼HBase會在生成StoreFile時包含一份BloomFilter的結構的數據,稱爲MetaBlock(一旦寫入就沒法更新)。MetaBlock和DataBlock(真實的KeyValue數據)一塊兒由LRUBlockCache維護,因此開啓了BloomFilter會有必定的存儲即內存cache開銷。

HBase利用BloomFilter能夠節省必須讀磁盤過程,能夠提升隨機讀(get)的性能,可是對於順序讀(scan)而言,設置BloomFilter是沒有做用的(0.92版本之後,若是設置了BloomFilter爲ROWCOL,對於執行了qualifier的scan有必定的優化)

BloomFilter取值有兩個,ROW和ROWCOL,須要根據業務來肯定具體使用哪一種。

  • 若是業務大多數隨機查詢僅僅使用row做爲查詢條件,BloomFilter必定要設置爲ROW。

  • 若是大多數隨機查詢使用row+col做爲查詢條件,BloomFilter須要設置爲ROWCOL。

  • 若是不肯定業務查詢類型,設置爲ROW。‘

預分區

寫性能優化預分區
部分。

HBase服務端調優

GC_OPTS

HBase是利用內存完成讀寫操做。提升HBase內存能夠有效提升HBase性能。GC_OPTS主要須要調整HeapSize和NewSize的大小。調整HeapSize大小的時候,建議將Xms和Xmx設置成相同的值,這樣能夠避免JVM動態調整HeapSize大小的時候影響性能。調整NewSize大小的時候,建議把其設置爲HeapSize大小的1/9。

當HBase集羣規模越大,Region數量越多時,能夠適當調大HMaster的GC_OPTS參數

RegionServer須要比HMaster更大的內存,在內存充足的狀況下,HeapSize能夠相對設置大一些。

HMaster的HeapSize爲4G的時候,HBase集羣能夠支持100000個Region的規模。根據經驗值,單個RegionServer的HeapSize不建議超過20GB。

# HMaster、RegionServer GC_OPTS配置以下:HMaster: -Xms2G -Xmx2G -XX:NewSize=256M -XX:MaxNewSize=256M RegionServer: -Xms4G -Xmx4G -XX:NewSize=512M -XX:MaxNewSize=512M複製代碼

RegionServer併發請求處理數量

hbase.regionserver.handler.count表示RegionServer在同一時刻可以併發處理多少請求。若是設置太高會致使激烈的線程競爭,若是設置太小,請求將會在RegionServer長時間等待,下降處理能力。應該根據資源狀況,適當增長處理線程數。

建議根據CPU的使用狀況,能夠設置爲100至300之間的值。

控制MemStore的大小

hbase.hregion.memstore.flush.size默認值128M,單位字節,一旦有MemStore超過該值將被flush,若是regionserver的jvm內存比較充足(16G以上),能夠調整爲256M。在內存足夠put負載大狀況下能夠調整增大。

BlockCache優化

BlockCache做爲讀緩存,合理設置對於提升讀性能很是重要。默認狀況下,BlockCache和MemStore的配置各佔40%,能夠根據集羣業務進行修正,好比讀多寫少業務能夠將BlockCache佔比調大。另外BlockCache的策略也很重要,不一樣策略對讀性能來講影響並不大,可是對GC的影響 卻很顯著。

HBase緩存區大小,主要影響查詢性能。根據查詢模式以及查詢記錄分佈狀況來決定緩存區的大小。若是採用隨機查詢使得緩存區的命中率較低,能夠適當下降緩存大小。

hfile.block.cache.size,默認0.4,用來提升讀性能hbase.regionserver.global.memstore.size,默認0.4,用來提升寫性能複製代碼

控制HFile個數

MemStore在flush以前,會進行StoreFile的文件數量校驗(經過hbase.hstore.blockingStoreFiles參數配置),若是大於設定值,系統將會強制執行Compaction操做進行文件合併,在合併的過程當中會阻塞MemStore的數據寫入,等待其餘線程將StoreFile進行合併。一般狀況下發生在數據寫入很快的狀況下。

hbase.hstore.compactionThreshold表示啓動Compaction的最低閾值,該值不能太大,不然會積累太多文件,通常建議設置爲5~8左右。

hbase.hstore.blockingStoreFiles默認設置爲7,能夠適當調大一些。

Split優化

hbase.hregion.max.filesize表示HBase中Region的文件總大小的最大值。當Region中的文件大於該參數時,將會致使Region分裂。

  • 若是該參數設置太小時,可能會致使Split操做頻繁

  • 若是該參數設置過大時,會致使Compaction操做須要處理的文件個數增大,影響Compaction執行效率

Compaction優化

hbase.hstore.compaction.min當一個Store中文件超過該值時,會進行Compaction,適當增大該值,能夠減小文件被重複執行Compaction。可是若是過大,會致使Store中文件數過多而影響讀取的性能。

hbase.hstore.compaction.max控制一次Compaction操做時的文件數據量的最大值。

hbase.hstore.compaction.max.size若是一個HFile文件的大小大於該值,那麼在Minor Compaction操做中不會選擇這個文件進行Compaction操做,除非進行Major Compaction操做。這個值能夠防止較大的HFile參與Compaction操做。在禁止Major Compaction後,一個Store中可能存在幾個HFile,而不會合併成爲一個HFile,這樣不會對數據讀取形成太大的性能影響。

原則是:儘可能要減少Compaction的次數和Compaction的執行時間

總結

在HBase使用過程當中,要想獲取好的讀寫性能,能夠從如下幾個方面進行優化:

  1. 一個優秀的HBase表列族設置方案,能夠參考《帶你快速上手HBase | HBase列族優化

  2. 一個優秀的HBase RowKey設計方案,能夠參考《一篇文章帶你快速搞懂HBase RowKey設計

  3. 讀寫時客戶端相關配置

  4. HBase服務器優化

相關文章
相關標籤/搜索