自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

HBase如何合理設(shè)置客戶端Write Buffer

數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù)
本文將結(jié)合HBase相關(guān)源碼,對(duì)其進(jìn)行深入介紹,分析如何在實(shí)際項(xiàng)目中合理設(shè)置和使用它。

 HBase客戶端API提供了Write Buffer的方式,即批量提交一批Put對(duì)象到HBase服務(wù)端。

1. 什么時(shí)候需要Write Buffer?

默認(rèn)情況下,一次Put操作即要與Region Server執(zhí)行一次RPC操作,其執(zhí)行過(guò)程可以被拆分為以下三個(gè)部分:

T1:RTT(Round-Trip Time),即網(wǎng)絡(luò)往返時(shí)延,它指從客戶端發(fā)送數(shù)據(jù)開始,到客戶端收到來(lái)自服務(wù)端的確認(rèn),總共經(jīng)歷的時(shí)延,不包括數(shù)據(jù)傳輸?shù)臅r(shí)間;

T2:數(shù)據(jù)傳輸時(shí)間,即Put所操作的數(shù)據(jù)在客戶端與服務(wù)端之間傳輸所消耗的時(shí)間開銷,當(dāng)數(shù)據(jù)量大的時(shí)候,T2的時(shí)間開銷不容忽略;

T3:服務(wù)端處理時(shí)間,對(duì)于Put操作,即寫入WAL日志(如果設(shè)置了WAL標(biāo)識(shí)為true)、更新MemStore等。

其中,T2和T3都是不可避免的時(shí)間開銷,那么能不能減少T1呢?假設(shè)我們將多次Put操作打包起來(lái)一次性提交到服務(wù)端,則可以將T1部分的總時(shí)間從T1 * N降低為T1,其中T1指的是單次RTT時(shí)間,N為Put的記錄條數(shù)。

正是出于上述考慮,HBase為用戶提供了客戶端緩存批量提交的方式(即Write Buffer)。假設(shè)RTT的時(shí)間較長(zhǎng),如1ms,則該種方式能夠顯著提高整個(gè)集群的寫入性能。

那么,什么場(chǎng)景下適用于該種模式呢?下面簡(jiǎn)單分析一下:

如果Put提交的是小數(shù)據(jù)(如KB級(jí)別甚至更小)記錄,那么T2很小,因此,通過(guò)該種模式減少T1的開銷,能夠明顯提高寫入性能。

如果Put提交的是大數(shù)據(jù)(如MB級(jí)別)記錄,那么T2可能已經(jīng)遠(yuǎn)大于T1,此時(shí)T1與T2相比可以被忽略,因此,使用該種模式并不能得到很好的性能提升,不建議通過(guò)增大Write Buffer大小來(lái)使用該種模式。

2. 如何配置使用Write Buffer?

如果要啟動(dòng)Write Buffer模式,則調(diào)用HTable的以下API將auto flush設(shè)置為false:

  1. void setAutoFlush(boolean autoFlush) 

默認(rèn)配置下,Write Buffer大小為2MB,可以根據(jù)應(yīng)用實(shí)際情況,通過(guò)以下任意方式進(jìn)行自定義:

1)  調(diào)用HTable接口設(shè)置,僅對(duì)該HTable對(duì)象起作用:

  1. void setWriteBufferSize(long writeBufferSize) throws IOException 

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

  1. <property> 
  2. <name>hbase.client.write.buffer</name> 
  3. <value>5242880</value> 
  4. </property> 

該種模式下向服務(wù)端提交的時(shí)機(jī)分為顯式和隱式兩種情況:

1)  顯式提交:用戶調(diào)用flushCommits()進(jìn)行提交;

2)  隱式提交:當(dāng)Write Buffer滿了,客戶端會(huì)自動(dòng)執(zhí)行提交;或者調(diào)用了HTable的close()方法時(shí)無(wú)條件執(zhí)行提交操作。

3. 如何確定每次flushCommits()時(shí)實(shí)際的RPC次數(shù)?

客戶端提交后,所有的Put操作可能涉及不同的行,然后客戶端負(fù)責(zé)將這些Put對(duì)象根據(jù)row key按照 region server分組,再按region server打包后提交到region server,每個(gè)region server做一次RPC請(qǐng)求。如下圖所示:

4. 如何確定每次flushCommits()時(shí)提交的記錄條數(shù)?

下面我們先從HBase存儲(chǔ)原理層面“粗略”分析下HBase中的一條Put記錄格式:

HBase中Put對(duì)象的大小主要由若干個(gè)KeyValue對(duì)的大小決定(Put繼承自org/apache/hadoop/hbase/client/Mutation.java,具體見Mutation的代碼所示),而KeyValue類中自帶的字段占用約50~60 bytes(參考源碼:org/apache/hadoop/hbase/KeyValue.java),那么客戶端Put一行數(shù)據(jù)時(shí),假設(shè)column qualifier個(gè)數(shù)為N,row key長(zhǎng)度為L(zhǎng)1 bytes,value總長(zhǎng)度為L(zhǎng)2 bytes,則該P(yáng)ut對(duì)象占用大小可按以下公式預(yù)估:

Put Size = ((50~60) + L1) * N + L2) bytes

下面我們通過(guò)對(duì)HBase的源碼分析來(lái)進(jìn)一步驗(yàn)證以上理論估算值:

HBase客戶端執(zhí)行put操作后,會(huì)調(diào)用put.heapSize()累加當(dāng)前客戶端buffer中的數(shù)據(jù),滿足以下條件則調(diào)用flushCommits()將客戶端數(shù)據(jù)提交到服務(wù)端:

1)每次put方法調(diào)用時(shí)可能傳入的是一個(gè)List<Put>,此時(shí)每隔DOPUT_WB_CHECK條(默認(rèn)為10條),檢查當(dāng)前緩存數(shù)據(jù)是否超過(guò)writeBufferSize,超過(guò)則強(qiáng)制執(zhí)行刷新;

2)autoFlush被設(shè)置為true,此次put方法調(diào)用后執(zhí)行一次刷新;

3)autoFlush被設(shè)置為false,但當(dāng)前緩存數(shù)據(jù)已超過(guò)設(shè)定的writeBufferSize,則執(zhí)行刷新。

  1. private void doPut(final List<Put> puts) throws IOException { 
  2.        int n = 0; 
  3.        for (Put put : puts) { 
  4.            validatePut(put); 
  5.            writeBuffer.add(put); 
  6.            currentWriteBufferSize += put.heapSize(); 
  7.            // we need to periodically see if the writebuffer is full instead  
  8.            // of waiting until the end of the List 
  9.            n++; 
  10.            if (n % DOPUT_WB_CHECK == 0 
  11.                    && currentWriteBufferSize > writeBufferSize) { 
  12.                flushCommits(); 
  13.            } 
  14.        } 
  15.        if (autoFlush || currentWriteBufferSize > writeBufferSize) { 
  16.            flushCommits(); 
  17.        } 
  18.    } 

由上述代碼可見,通過(guò)put.heapSize()累加客戶端的緩存數(shù)據(jù),作為判斷的依據(jù);那么,我們可以編寫一個(gè)簡(jiǎn)單的程序生成Put對(duì)象,調(diào)用其heapSize()方法,就能得到一行數(shù)據(jù)實(shí)際占用的客戶端緩存大?。ㄔ摮绦蛐枰獋鬟f上述三個(gè)變量:N,L1,L2作為參數(shù)):

  1. import org.apache.hadoop.hbase.client.Put; 
  2. import org.apache.hadoop.hbase.util.Bytes; 
  3.  
  4. public class PutHeapSize { 
  5.     /** 
  6.      * @param args 
  7.      */ 
  8.     public static void main(String[] args) { 
  9.         if (args.length != 3) { 
  10.             System.out.println("Invalid number of parameters: 3 parameters!"); 
  11.             System.exit(1); 
  12.         } 
  13.         int N = Integer.parseInt(args[0]); 
  14.         int L1 = Integer.parseInt(args[1]); 
  15.         int L2 = Integer.parseInt(args[2]); 
  16.         byte[] rowKey = new byte[L1]; 
  17.         byte[] value = null
  18.         Put put = new Put(rowKey); 
  19.         for (int i = 0; i < N; i++) { 
  20.             put.add(Bytes.toBytes("cf"), Bytes.toBytes("c" + i), value); 
  21.         } 
  22.         System.out.println("Put Size: " + (put.heapSize() + L2) + " bytes"); 
  23.     } 

該程序可以用來(lái)預(yù)估當(dāng)前設(shè)置的write buffer可以一次性批量提交的記錄數(shù):


  1. Puts Per Commit = Write Buffer Size / Put Size 

更進(jìn)一步地,如果知道業(yè)務(wù)中的每秒產(chǎn)生的數(shù)據(jù)量,就可知道客戶端大概多長(zhǎng)時(shí)間會(huì)隱式調(diào)用flushCommits()向服務(wù)端提交一次;同時(shí)也可反過(guò)來(lái)根據(jù)數(shù)據(jù)實(shí)時(shí)刷新頻率調(diào)整Write Buffer大小。

5. Write Buffer有什么潛在的問題?

首先,Write Buffer存在于客戶端的本地內(nèi)存中,那么當(dāng)客戶端運(yùn)行出現(xiàn)問題時(shí),會(huì)導(dǎo)致在Write Buffer中未提交的數(shù)據(jù)丟失;由于HBase服務(wù)端還未收到這些數(shù)據(jù),因此也無(wú)法通過(guò)WAL日志等方式進(jìn)行數(shù)據(jù)恢復(fù)。

其次,Write Buffer方式本身會(huì)占用客戶端和HBase服務(wù)端的內(nèi)存開銷,具體見下節(jié)的詳細(xì)分析。

6. 如何預(yù)估Write Buffer占用的內(nèi)存?

客戶端通過(guò)Write Buffer方式提交的話,會(huì)導(dǎo)致客戶端和服務(wù)端均有一定的額外內(nèi)存開銷,Write Buffer Size越大,則占用的內(nèi)存越大??蛻舳苏加玫膬?nèi)存開銷可以粗略使用以下公式預(yù)估:


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

而對(duì)于服務(wù)端來(lái)說(shuō),可以使用以下公式預(yù)估占用的Region Server總內(nèi)存開銷:


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

其中,hbase.regionserver.handler.count為每個(gè)Region Server上配置的RPC Handler線程數(shù)。

原文鏈接:http://www.cnblogs.com/panfeng412/archive/2012/10/16/how-to-use-hbase-client-write-buffer.html

【編輯推薦】

  1. 讓數(shù)據(jù)庫(kù)變快的10個(gè)建議
  2. 利用Java進(jìn)行MySql數(shù)據(jù)庫(kù)的導(dǎo)入和導(dǎo)出
  3. 20個(gè)數(shù)據(jù)庫(kù)設(shè)計(jì)最佳實(shí)踐
  4. 超越MySQL 對(duì)流行數(shù)據(jù)庫(kù)進(jìn)行分支
  5. 迎接大數(shù)據(jù)時(shí)代,高手較量數(shù)據(jù)庫(kù)遷移實(shí)戰(zhàn)方案

責(zé)任編輯:彭凡 來(lái)源: 博客園
相關(guān)推薦

2011-08-15 14:09:59

JavaHBase

2011-03-29 16:07:32

CACTISNMP

2010-07-27 15:59:04

NFS Server

2010-07-22 12:24:31

Telnet客戶端

2013-03-13 10:51:44

瘦客戶端VDI

2010-12-31 14:23:57

Exchange Se

2011-08-17 10:10:59

2021-09-22 15:46:29

虛擬桌面瘦客戶端胖客戶端

2010-12-17 10:16:33

OpenVAS

2010-05-31 10:11:32

瘦客戶端

2011-10-26 13:17:05

2009-12-08 16:47:06

WCF IP

2011-03-02 14:36:24

Filezilla客戶端

2010-12-21 11:03:15

獲取客戶端證書

2011-03-24 13:00:31

配置nagios客戶端

2009-05-07 15:52:26

SQL ServerSET選項(xiàng)客戶端管理

2011-03-21 14:53:36

Nagios監(jiān)控Linux

2009-03-04 10:27:50

客戶端組件桌面虛擬化Xendesktop

2011-04-06 14:24:20

Nagios監(jiān)控Linux

2013-05-09 09:33:59

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)