天天看點

Hbase用戶端優化

Scan Caching

scanner一次緩存多少資料來scan(從服務端一次抓多少資料回來scan)。

預設值是 1,一次隻取一條。

Scan Attribute Selection

scan時建議指定需要的Column Family,減少通信量,否則scan操作預設會傳回整個row的所有資料(所有Coulmn Family)。

Close ResultScanners

通過scan取完資料後,記得要關閉ResultScanner,否則RegionServer可能會出現問題(對應的Server資源無法釋放)。

Optimal Loading of Row Keys

當你scan一張表的時候,傳回結果隻需要row key(不需要CF, qualifier,values,timestaps)時,你可以在scan執行個體中添加一個filterList,并設定 MUST_PASS_ALL操作,filterList中add FirstKeyOnlyFilter或KeyOnlyFilter。這樣可以減少網絡通信量

Turn off WAL on Puts

當Put某些非重要資料時,你可以設定writeToWAL(false),來進一步提高寫性能。writeToWAL(false)會在Put時放棄寫WAL log。風險是,當RegionServer當機時,可能你剛才Put的那些資料會丢失,且無法恢複

啟用Bloom Filter

Bloom Filter通過空間換時間,提高讀操作性能

什麼時候需要Write Buffer?

預設情況下,一次Put操作即要與Region Server執行一次RPC操作,其執行過程可以被拆分為以下三個部分:

T1:RTT(Round-Trip Time),即網絡往返時延,它指從用戶端發送資料開始,到用戶端收到來自服務端的确認,總共經曆的時延,不包括資料傳輸的時間;

T2:資料傳輸時間,即Put所操作的資料在用戶端與服務端之間傳輸所消耗的時間開銷,當資料量大的時候,T2的開銷不容忽略;

T3:服務端處理時間,對于Put操作,即寫入WAL日志(如果設定了WAL辨別為true)、更新MemStore等。

其中,T2和T3都是不可避免的時間開銷,那麼能不能減少T1呢?假設我們将多次Put操作打包起來一次性送出到服務端,則可以将T1部分的總時間從T1 * N降低為T1,其中T1為一次RTT時間,N為Put的記錄條數。

正是出于上述考慮,HBase為使用者提供了用戶端緩存批量送出的方式(即Write Buffer)。假設RTT的時間較長,如1ms,則該種方式能夠顯著提高整個叢集的寫入性能。

那麼,什麼場景下适用于該種模式呢?下面簡單分析一下:

如果Put送出的是小資料(如KB級别甚至更小)記錄,那麼T2很小,是以,通過該種模式減少T1的開銷,能夠明顯提高寫入性能。

如果Put送出的是大資料(如MB級别)記錄,那麼T2可能已經遠大于T1,此時T1與T2相比可以被忽略,是以,使用該種模式并不能得到很好的性能提升,不建議通過增大Write Buffer大小來使用該種模式。

如何配置使用Write Buffer?

如果要啟動Write Buffer模式,則調用HTable的以下API将auto flush設定為false:

void setAutoFlush(boolean autoFlush)

預設配置下,Write Buffer大小為2MB,可以根據應用實際情況,通過以下任意方式進行自定義:

1)  調用HTable接口設定,僅對該HTable對象起作用:

void setWriteBufferSize(long writeBufferSize) throws IOException

2)  在hbase-site.xml中配置,所有HTable都生效(下面設定為5MB):

hbase.client.write.buffer

5242880

該種模式下向服務端送出的時機分為顯式和隐式兩種情況:

1)  顯式送出:使用者調用flushCommits()進行送出;

2)  隐式送出:當Write Buffer滿了,用戶端會自動執行送出;或者調用了HTable的close()方法時無條件執行送出操作。

Write Buffer有什麼潛在的問題?

首先,Write Buffer存在于用戶端的本地記憶體中,那麼當用戶端運作出現問題時,會導緻在Write Buffer中未送出的資料丢失;由于HBase服務端還未收到這些資料,是以也無法通過WAL日志等方式進行資料恢複。

其次,Write Buffer方式本身會占用用戶端和HBase服務端的記憶體開銷,具體見下節的詳細分析。

如何預估Write Buffer占用的記憶體?

用戶端通過Write Buffer方式送出的話,會導緻用戶端和服務端均有一定的額外記憶體開銷,Write Buffer Size越大,則占用的記憶體越大。用戶端占用的記憶體開銷可以粗略地使用以下公式預估:

hbase.client.write.buffer * number of HTable object for writing

而對于服務端來說,可以使用以下公式預估占用的Region Server總記憶體開銷:

hbase.client.write.buffer hbase.regionserver.handler.count number of region server

其中,hbase.regionserver.handler.count為每個Region Server上配置的RPC Handler線程數。

繼續閱讀