当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我发现版本冲突发生了异常。
所以现在我对服务器端进程客户端reuqest如何感到困惑?为什么在连续的情况下仍然无法得到正确的结果?
答案 0 :(得分:0)
默认情况下,每个*RequestBuilder
都有一个超时,如果无法立即执行索引/更新/删除操作,则会等待。
因此从理论上讲,您的某些更新可能仍未处理且未执行。尝试使用以下方法强制刷新索引:
client.prepareUpdate(index, type, id)
.setScript("ctx._source.count += 1", ScriptService.ScriptType.INLINE)
.setRefresh(true)
.execute()
.actionGet();