2014-09-03 107 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