java客户端的并发更新弹性索引和一些更新丢失

时间:2015-07-31 10:13:22

标签: elasticsearch

当java客户端并发执行更新弹性索引时,最终它似乎丢失了一些更新。例如,我最初有一个索引{“count”:0},然后有10个线程增加1个,最后我预计计数为10,但实际上我发现它小于10.我的演示代码是:

ExecutorService service = Executors.newFixedThreadPool(10);
// create index
client.prepareIndex(index, type, id)
.setSource(XContentFactory.jsonBuilder().startObject().field("count", 0).endObject())
.execute().get();

// multi thread update
int count = 10;
CountDownLatch latch = new CountDownLatch(count);
for (int i = 0; i < count; i++) {
service.execute(new Runnable() {

@Override
public void run() {
   try {
       client.prepareUpdate(index, type, id)
        .setScript("ctx._source.count += 1", ScriptService.ScriptType.INLINE).execute();

     } catch (Exception e) {
        e.printStackTrace();
    } finally {
        latch.countDown();
    }
}
});
}

// check result
latch.await();
service.shutdown();
GetResponse getResponse = client.prepareGet(index, type, id).execute().get();

System.out.println(getResponse.getSourceAsString());

那么这些丢失的更新?

=============================================== =========

补充信息

实际上在客户端不需要make并发,实际上顺序执行也会有同样的效果,

for (int i = 0; i < count; i++) {
  client.prepareUpdate(index, type, id)
      .setScript("ctx._source.count += 1", ScriptService.ScriptType.INLINE).execute();
}

通过wireshark我发现版本冲突发生了异常。

enter image description here

所以现在我对服务器端进程客户端reuqest如何感到困惑?为什么在连续的情况下仍然无法得到正确的结果?

1 个答案:

答案 0 :(得分:0)

默认情况下,每个*RequestBuilder都有一个超时,如果无法立即执行索引/更新/删除操作,则会等待。

因此从理论上讲,您的某些更新可能仍未处理且未执行。尝试使用以下方法强制刷新索引:

client.prepareUpdate(index, type, id)
   .setScript("ctx._source.count += 1", ScriptService.ScriptType.INLINE)
   .setRefresh(true)
   .execute()
   .actionGet();