我的ES 2.3.1实例使用了97%的堆,因此几乎不断地收集垃圾,并阻止任何请求成功。事实是,我无法弄清楚正在吃掉所有记忆的东西。根本没有field_data用法。
以下是我的node stats。
如果我能提供更多信息,请告诉我。任何帮助,将不胜感激。谢谢!
编辑:
这是一个基于Elasticsearch JVM堆的泄漏嫌疑人报告屏幕截图。它似乎是与groovy脚本相关的内存泄漏。这是Elasticsearch本身的问题吗?或者我可能会对客户做错事吗?
编辑:
以下是我正在使用的脚本。只要更新值不是陈旧的,这个用一个id替换当前版本的嵌套对象:
def found = false;
if (ctx._source.my_field != null) {
for (int i = 0; i < ctx._source.my_field.size(); i++) {
if (ctx._source.my_field[i].id == 1) {
found = true;
if (ctx._source.my_field[i].timestamp < 201605011912488050) {
ctx._source.my_field[i] = jsonMap }
else {
ctx.op = "none"
}
}
};
if (!found) {
ctx._source.my_field += jsonMap;
}
} else {
ctx._source.my_field = [jsonMap];
};
如果更新不是陈旧的,则只需更新常规字段:
if (ctx._source.my_field2 == null || ctx._source.my_field2.timestamp < 201605011913320690) {
ctx._source.my_field2 = jsonMap
} else {
ctx.op = "none"
}
在上述两种情况下,我都是通过地图传递的json对象更新字段(如建议的here)。我正在使用以下代码创建并传递地图:
Map<?, ?> jsonMap = new ObjectMapper().readValue(updateJson.toString(), HashMap.class);
Map<String, Object> params = ImmutableMap.of("jsonMap", jsonMap);
return new Script(script, ScriptService.ScriptType.INLINE, null, params);
编辑:
更多信息:
1)第一个脚本循环的嵌套文档数通常为O(1)且不超过O(10)。
2)要运行脚本,我首先创建一个updateRequest:
UpdateRequest updateRequest = new UpdateRequest()
.index(index)
.type(documentType)
.id(documentId.toString())
.script(script)
.retryOnConflict(5)
.upsert(getIndexRequestForDocumentUpsert(...));
其中getIndexRequestForDocumentUpsert(...)
只返回一个简单的(非脚本)索引请求,作为新文档。然后将这些UpdateRequests添加到批量更新请求中,该请求最多包含100个更新。
3)最后,需要注意的一点是,在对索引进行任何更新(或查询)后2天就会进行这种堆转储,这就是为什么它有点泄漏而不仅仅是过度负载。< / p>