<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      HBase如何合理設置客戶端Write Buffer

      作者: 大圓那些事 | 轉載請以超鏈接形式標明文章原始出處和作者信息
      網址: http://www.rzrgm.cn/panfeng412/archive/2012/10/16/how-to-use-hbase-client-write-buffer.html

      HBase客戶端API提供了Write Buffer的方式,即批量提交一批Put對象到HBase服務端。本文將結合HBase相關源碼,對其進行深入介紹,分析如何在實際項目中合理設置和使用它。

      1. 什么時候需要Write Buffer?

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

      • T1:RTT(Round-Trip Time),即網絡往返時延,它指從客戶端發(fā)送數據開始,到客戶端收到來自服務端的確認,總共經歷的時延,不包括數據傳輸的時間;
      • 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大小來使用該種模式。

      2. 如何配置使用Write Buffer?

      如果要啟動Write Buffer模式,則調用HTable的以下APIauto flush設置為false

      void setAutoFlush(boolean autoFlush)

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

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

      void setWriteBufferSize(long writeBufferSize) throws IOException

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

      <property>
      <name>hbase.client.write.buffer</name>
      <value>5242880</value>
      </property>

      該種模式下向服務端提交的時機分為顯式和隱式兩種情況:

      1)  顯式提交:用戶調用flushCommits()進行提交;

      2)  隱式提交:當Write Buffer滿了,客戶端會自動執(zhí)行提交;或者調用了HTableclose()方法時無條件執(zhí)行提交操作。

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

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

       

       

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

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

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

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

      下面我們通過對HBase的源碼分析來進一步驗證以上理論估算值:

      HBase客戶端執(zhí)行put操作后,會調用put.heapSize()累加當前客戶端buffer中的數據,滿足以下條件則調用flushCommits()將客戶端數據提交到服務端:

      1)每次put方法調用時可能傳入的是一個List<Put>,此時每隔DOPUT_WB_CHECK條(默認為10條),檢查當前緩存數據是否超過writeBufferSize,超過則強制執(zhí)行刷新;

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

      3)autoFlush被設置為false,但當前緩存數據已超過設定的writeBufferSize,則執(zhí)行刷新。

          private void doPut(final List<Put> puts) throws IOException {
              int n = 0;
              for (Put put : puts) {
                  validatePut(put);
                  writeBuffer.add(put);
                  currentWriteBufferSize += put.heapSize();
                  // we need to periodically see if the writebuffer is full instead 
                  // of waiting until the end of the List
                  n++;
                  if (n % DOPUT_WB_CHECK == 0
                          && currentWriteBufferSize > writeBufferSize) {
                      flushCommits();
                  }
              }
              if (autoFlush || currentWriteBufferSize > writeBufferSize) {
                  flushCommits();
              }
          }

      由上述代碼可見,通過put.heapSize()累加客戶端的緩存數據,作為判斷的依據;那么,我們可以編寫一個簡單的程序生成Put對象,調用其heapSize()方法,就能得到一行數據實際占用的客戶端緩存大小(該程序需要傳遞上述三個變量:N,L1,L2作為參數):

      import org.apache.hadoop.hbase.client.Put;
      import org.apache.hadoop.hbase.util.Bytes;
      
      public class PutHeapSize {
          /**
           * @param args
           */
          public static void main(String[] args) {
              if (args.length != 3) {
                  System.out.println("Invalid number of parameters: 3 parameters!");
                  System.exit(1);
              }
              int N = Integer.parseInt(args[0]);
              int L1 = Integer.parseInt(args[1]);
              int L2 = Integer.parseInt(args[2]);
              byte[] rowKey = new byte[L1];
              byte[] value = null;
              Put put = new Put(rowKey);
              for (int i = 0; i < N; i++) {
                  put.add(Bytes.toBytes("cf"), Bytes.toBytes("c" + i), value);
              }
              System.out.println("Put Size: " + (put.heapSize() + L2) + " bytes");
          }
      }

      該程序可以用來預估當前設置的write buffer可以一次性批量提交的記錄數:

      Puts Per Commit = Write Buffer Size / Put Size

      更進一步地,如果知道業(yè)務中的每秒產生的數據量,就可知道客戶端大概多長時間會隱式調用flushCommits()向服務端提交一次;同時也可反過來根據數據實時刷新頻率調整Write Buffer大小。

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

      首先,Write Buffer存在于客戶端的本地內存中,那么當客戶端運行出現問題時,會導致在Write Buffer中未提交的數據丟失;由于HBase服務端還未收到這些數據,因此也無法通過WAL日志等方式進行數據恢復。

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

      6. 如何預估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線程數。

       

      posted on 2012-10-16 22:17  大圓那些事  閱讀(6657)  評論(4)    收藏  舉報

      導航

      主站蜘蛛池模板: 亚洲日本中文字幕乱码中文| 国产精品无码素人福利不卡| 渭源县| 日韩中文字幕亚洲精品| 日区中文字幕一区二区| 亚洲欧美日韩精品久久亚洲区| 精品人妻中文字幕在线| 人妻在线中文字幕| 成人无码特黄特黄AV片在线| 国产精品久久久久aaaa| 日本一区二区三区专线| 五月天国产成人av免费观看| 日本怡春院一区二区三区| 免费拍拍拍网站| 92国产精品午夜福利免费| 日韩精品国内国产一区二| 永久免费AV无码网站YY| 精品国产中文字幕av| 最新精品露脸国产在线| 亚洲禁精品一区二区三区| 激情综合网五月婷婷| 综合色一色综合久久网| 国产人成亚洲第一网站在线播放 | 一区二区三区四区自拍视频| 国产精品美女AV免费观看| 欧美激情一区二区三区成人| 精品国产一区二区三区久| 国产三级精品片| 一本色道久久加勒比综合 | 南丰县| 免费天堂无码人妻成人av电影| 亚洲人成网站18禁止无码| 午夜免费无码福利视频麻豆| 亚洲精品综合久久国产二区 | 海阳市| 激情综合网激情五月激情| 一本精品99久久精品77| 国产suv精品一区二区883| 国产在线视频精品视频| 美女自卫慰黄网站| 久久久久青草线综合超碰|