2014-09-03 119 views
1

Couchbase的新手問題:多次插入失敗

我試圖插入100萬條記錄中couchbase,但我看到,近0.5萬條記錄插入得到(管理控制檯顯示517365作爲項目計數)。 此外,從管理GUI,我只能看到1000條記錄(每個100條記錄10頁)

我在想,其餘的記錄正在消失!

1)有人可以幫助我嗎?

2)我應該查看哪個日誌文件來查找插入失敗錯誤?

我懷疑Couchbase有一個內部隊列。一旦它滿了,進一步的請求將被刪除。如果是,那麼如何配置隊列大小? PS:我試着查看日誌C:\ Program Files \ Couchbase \ Server \ var \ lib \ couchbase \ logs,但找不到任何東西。

public class Test { 
    public static void main(String[] args) { 
     ArrayList<URI> nodes = new ArrayList<URI>(); 
     String cbUrl = "http://127.0.0.1:8091/pools"; 
     String dbName = "deafult"; 
     CouchbaseClient client = null; 
     try { 
      nodes.add(URI.create(cbUrl)); 

      client = new CouchbaseClient(nodes, dbName, ""); 

      insertRecords(client); 

      System.out.println("Test Over"); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      // client.shutdown(); 
     } 
    } 

    public static void insertRecords(CouchbaseClient client) throws Exception { 
     int num = 1000000; 

     for (int n = 1; n <= num; n++) { 
      System.out.println("Adding: " + n); 
      client.set(n + "", 0, n + ""); 
     } 
    } 
} 
+1

您可以登錄操作的狀態描述,相處?例如'client.set('foo','bar')。getStatus()' – avsej 2014-09-03 12:48:17

+0

請注意,在此處執行@avsej提及的操作將導致您的應用程序正常工作,因爲getStatus()調用將等待操作完成以獲取該操作的返回碼。 – mikewied 2014-09-03 20:04:27

+0

我試過client.set('foo','bar')。getStatus()。但是我得到{OperationStatus success = false:臨時失敗}作爲許多記錄的狀態。我如何配置Couchbase緩衝區大小?我想這應該可以解決問題。 – aneez 2014-09-04 03:47:19

回答

2

Couchbase Java SDK中的set操作是異步的。這意味着一旦調用返回,就不能保證你甚至將操作發送到Couchbase,因爲它可能還沒有寫入網絡緩衝區。爲了確保操作已完成,您需要調用由set()API返回的對象(它是Future)上的get()函數。

換句話說替換此行:

client.set(n + "", 0, n + ""); 

這一個:

client.set(n + "", 0, n + "").get(); 
+0

這不會使呼叫同步嗎?我想有一些Couchbase使用的隊列。知道如何配置它或檢查其默認大小將是一件好事。 – aneez 2014-09-04 03:06:24

+0

噢...既然它是一個未來,那麼這些調用將是異步的,但是對於每一次調用,仍然會有不必要的調用。有沒有辦法避免它? – aneez 2014-09-04 03:28:00

+0

在shutdown()API中,您應該能夠將「等待隊列」值設置爲true。否則,您需要在每個將來調用get()函數,以確保操作已完成。你還可以做的一件事就是將所有的Future對象放到一個列表中,然後定期對它們全部調用get()。在批量加載代碼中,我寫入隊列1000 Futures,然後在所有隊列上調用get()並重復,直到加載所有數據。 – mikewied 2014-09-04 17:31:06

0

爲了擴大對@ mikewied的回答,檢查所有這1百萬一套操作完成不必每個呼叫明確地呼叫.get()(並且因此將呼叫從異步轉換爲同步),您需要將聽衆添加到每個跟蹤你的多少個操作已經完成。

有如何做到這一點的blog post宣佈Couchbase的Java SDK 1.2一個很好的例子: -

final CountDownLatch latch = new CountDownLatch(100); 
for (int i = 0; i < 100; i++) { 
    OperationFuture<Boolean> future = client.set("key-" + i, "value"); 
    future.addListener(new OperationCompletionListener() { 
    @Override 
    public void onComplete(OperationFuture<?> future) throws Exception { 
     latch.countDown(); 
    } 
    }); 
} 
latch.await(); 

您創建一個CountDownLatch,初始化爲你多少文檔設置()ING,然後註冊一個在完成每個集合時調用的listener(但注意集合仍然是異步的)。最後,在鎖存器上調用await()以確保所有設置操作在繼續之前完成。

這種方法進行了更詳細的Couchbase的Java SDK開發人員指南的Understanding and Using Asynchronous Operations部分與更緊湊的語法,如果你使用的是Java 8

+0

請注意,作爲onComplete函數的一部分,檢查操作是否成功仍然很重要,因爲該操作可能會使用錯誤代碼「完成」。作爲一個例子,你可能想要檢查:future.getStatus()。isSuccess() – tom 2014-09-08 10:21:58