2013-04-04 115 views
3

我想在cassandra中插入約5000萬行(〜30列),目前只有1個節點。向cassandra插入大量數據

我從另一個數據源查詢我的數據並存儲在一個表對象中。我迭代通過分別解析每一行然後將其添加到增變器。目前,我一次插入100行,100萬行需要40分鐘!我如何加快這個過程? (我也嘗試過client.batch_mutate(),但它似乎有重置連接錯誤塊數大小的插入數千)2)。

通過搜索我看到多線程可能有所幫助。但我找不到任何例子,有人可以鏈接我嗎?謝謝 !!

我當前的代碼:

 List<String> colNames = new ArrayList<String>(); 
     List<String> colValues = new ArrayList<String>(); 
     SomeTable result = Query(...); // this contains my result set of 1M rows initially 

     for (Iterator itr = result.getRecordIterator(); itr.hasNext();) { 
       String colName =..... 
       String colValue = ..... 

      int colCount = colNames.size(); // 100 * 30 

      for (int i = 0; i < colCount; i++) { 
       //add row keys and columns to mutator 
       mutator.addInsertion(String.valueOf(rowCounter), "data", HFactory.createStringColumn(colNames.get(i), colValues.get(i))); 
      } 
      rowCounter++; 

      //insert rows of block size 100 
      if (rowCounter % 100==0) { 

       mutator.execute(); 
       //clear data 
       colNames = new ArrayList<String>(); 
       colValues = new ArrayList<String>(); 
       mutator = HFactory.createMutator(keyspace, stringSerializer); 
      } 

     } 

回答

2

多線程將有很大的幫助,是的。目前,您正在Cassandra中使用一個連接,這意味着您只能在Cassandra中使用單個線程。您需要使用多個連接,這需要客戶端中有多個線程。

一種方法是使用Java ThreadPoolExecutor並將mutator.execute()包裝在可運行的環境中,然後在線程池中執行它。小心處理異常。您還應該使用BlockingQueue來限制排隊的突變數量,以防您讀取源的速度比Cassandra可以插入的速度快。

用這個,在Hector中設置你的連接池大小爲10,你的插入應該快得多。

如果您不清楚Cassandra的注意事項,請注意,Cassandra不適用於單節點操作。我假設你打算擴展和添加複製。如果不是的話,那麼您可能會找到更高性能,更簡單的替代解決方案來滿足您的需求。使用多個節點時,多個連接和線程變得尤爲重要,因此您的插入速率可以擴展。

+0

感謝您的回答!所以我需要多個節點,如果我想讓我的客戶端多線程?我不知道多線程,我不知道你是否知道在線的任何好的多線程cassandra例子? 是的,我現在正在測試,稍後會擴展到更多節點。 @Richard – 2013-04-04 13:09:55

+0

不,您可以爲每個節點建立多個連接,這就是讓您的客戶端成爲多線程所需的全部內容。我不知道Cassandra的例子,但ThreadPoolExecutor的javadoc是很好的http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html,並且有關於Java的教程在此處進行線程化http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html – Richard 2013-04-04 13:15:19

+0

再次感謝@Richard。對不起另一個新手問題 - 看起來我會將我的代碼封裝在Runnable中,並創建許多線程併發送不同的「表」對象。我的問題是,我是否應該爲每個線程或同一個線程創建一個新的Cluster/Mutator/Keyspace對象? – 2013-04-04 15:28:55