由于Groovy脚本,Elasticsearch使用了大量内存

时间:2016-04-28 15:16:56

标签: elasticsearch groovy

我的ES 2.3.1实例使用了97%的堆,因此几乎不断地收集垃圾,并阻止任何请求成功。事实是,我无法弄清楚正在吃掉所有记忆的东西。根本没有field_data用法。

以下是我的node stats

如果我能提供更多信息,请告诉我。任何帮助,将不胜感激。谢谢!

编辑:

这是一个基于Elasticsearch JVM堆的泄漏嫌疑人报告屏幕截图。它似乎是与groovy脚本相关的内存泄漏。这是Elasticsearch本身的问题吗?或者我可能会对客户做错事吗? leak suspects report

编辑:

以下是我正在使用的脚本。只要更新值不是陈旧的,这个用一个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>

1 个答案:

答案 0 :(得分:0)

我在Github上打开了一个issue,显然这是因为已知的Groovy内存泄漏。