2016-08-10 66 views
1

我試圖在Java中爲hbase創建一個通用方法。在hbase中高效發送多個獲取請求

我現在有一個寫它接受3個參數

  • 一個Range(掃描表)
  • 一個Column(回)...和
  • 一個Condition(即browser==Chrome

因此,一個語句(if寫在一個SQLish語言)可以像

SELECT OS FROM TABLE WHERE BROWSER==CHROME IN RANGE (5 WEEKS AGO -> 2 WEEKS AGO) 

現在,我知道我沒有正確使用HBase(對rowkey等使用常見列查詢),但爲了實驗的目的,我想嘗試一下,以幫助我學習。

所以我做的第一件事就是在Scan上設置一個Range。 (5周到2周前),因爲rowkeytimestamp,這是非常有效的。

然後我設置SingleColumnValueFilterbrowser = Chrome)(的範圍濾波器後,這是相當快)

然後我存儲所有的rowkeys(從掃描)轉換成array

對於每個rowkey(在數組中)我執行GET操作以獲得相應的OS

我試過使用MultiGet,這加快了這個過程。

然後我嘗試使用正常的GET請求,每個請求產生一個新的線程,所有的線程都同時運行,這減少了一半的查詢時間!但仍然不夠快。

我已經考慮限制使用單個連接到數據庫的線程數。即每個連接100個線程。

鑑於我的情況,執行這些GET s的最有效方法是什麼?或者我完全錯誤地接近它?

任何幫助非常感謝。

EDIT(這是我的螺紋GET嘗試)

List<String> newresults = Collections.synchronizedList(new ArrayList<String>()); 

for (String rowkey : result) { 
    spawnGetThread(rowkey, colname); 
} 

public void spawnGetThread(String rk, String cn) { 
    new Thread(new Runnable() { 
     public void run() { 

      String rt = ""; 
      Get get = new Get(Bytes.toBytes(rk)); 
      get.addColumn(COL_FAM, cn); 
      try { 
       Result getResult = tb.get(get); 
       rt = (Bytes.toString(getResult.value())); 
      } catch (IOException e) { 
      } 
      newresults.add(rt); 
     } 
    }).start(); 
} 
+0

此外,請參閱此問題http://stackoverflow.com/questions/26880169/timestamp-based-scans-in-hbase可能會有所幫助 –

回答

3

考慮到我的情況下,什麼是執行 這些得到最有效的方式,還是我完全接近它是否有誤?

我建議以下方式

得到的是好的,如果你知道哪些rowkeys可以acccess前期。

在這種情況下,您可以使用下面的方法,它將返回Result數組。

/** 
    * Method getDetailRecords. 
    * 
    * @param listOfRowKeys List<String> 
    * @return Result[] 
    * @throws IOException 
    */ 
    private Result[] getDetailRecords(final List<String> listOfRowKeys) throws IOException { 
     final HTableInterface table = HBaseConnection.getHTable(TBL_DETAIL); 
     final List<Get> listOFGets = new ArrayList<Get>(); 
     Result[] results = null; 
     try { 
      for (final String rowkey : listOfRowKeys) {// prepare batch of get with row keys 
    // System.err.println("get 'yourtablename', '" + saltIndexPrefix + rowkey + "'"); 
       final Get get = new Get(Bytes.toBytes(saltedRowKey(rowkey))); 
       get.addColumn(COLUMN_FAMILY, Bytes.toBytes(yourcolumnname)); 
       listOFGets.add(get); 
      } 
      results = table.get(listOFGets); 

     } finally { 
      table.close(); 
     } 
     return results; 
    } 

附加說明:Rowfilters總是快於列值的過濾器(它全表掃描)..

建議要經過HBase的最權威指南 - >Client API: Advanced Features

+0

請通過我的另一個答案http://stackoverflow.com/questions/ 37899344 /查詢-HBase的-有效/ 37908912# 37908912如果您使用的掃描模糊過濾器速度很快,但您需要確保chrome是rowkey的一部分。意味着您可以添加瀏覽器類型或Enum並將其添加到rowkey中,以便模糊行篩選器在行之間跳轉並找出您需要的行。 –

+0

不幸的是我的列值不會是相同的長度,所以'FuzzyRowFilter'是不可能的。除非我可以重新定義數據到恆定的長度並且映射到真正的值......然而,對於多個GET請求,產生新線程會顯着加快進程,似乎異步方式比上述方式更快。這有什麼問題嗎?可以改進嗎? –

+0

「異步方式」你的意思是說異步hbase?如果是的話,主要用於水槽。如果你在異步hbase中做了一些事情,你可以共享你最近的代碼片段嗎?這聽起來有點奇怪。 –