ElasticSearch的TransportClient 5.4.3中是否存在内存泄漏?或者我没有正确使用和关闭对象?
我正在使用Jenkins(2.68)中的客户端,它位于JRE 1.8.0_66上,并在Groovy中编写我的代码。 BulkRequestBuilder
用于提交多条记录。
在整个代码中,这些4x 16 MB字节数组出现在内存中,但即使经过TransportClient.close()方法也永远不会关闭: 如果我更慢地逐步执行代码,我可以获得这些16 MB字节数组中的9x,其中一些看起来非常相似:
我认为我完全遵循官方文件:https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/transport-client.html
这是我正在使用的代码的精简版本:
@Grapes([
@Grab(group = "org.apache.logging.log4j", module = "log4j-api", version = "2.8.2", initClass = true),
@Grab(group = "org.apache.logging.log4j", module = "log4j-core", version = "2.8.2", initClass = true),
@Grab(group = "org.elasticsearch.client", module = "transport", version = "5.4.3", initClass = true)
])
public class ElasticSearchReport implements Serializable {
pubblic void execute() {
// Data to report.
List<Map<String, Object>> data = ...
// ElasticSearch settings. Do not use sniffing because we want to upload data to the master node.
Settings settings = Settings.builder()
.put("cluster.name", "my-cluster")
.put("client.transport.sniff", false)
.build()
PreBuiltTransportClient preBuiltTransportClient = new PreBuiltTransportClient(settings)
TransportClient client = preBuiltTransportClient.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("my-elastic-search-host"), 9300))
List<String> errors = new LinkedList<String>()
try {
BulkRequestBuilder bulkRequest = client.prepareBulk()
// Build the bulk query with each data entry.
data.each({entry ->
String serialisedEntry = SerializationUtils.toJson(entry)
bulkRequest.add(client.prepareIndex("my-index", "my-type").setSource(serialisedEntry, XContentType.JSON))
})
// Process the response.
bulkRequest.get().getItems().each({response ->
if (response.failed) {
errors.add(response.failure.message)
return
}
final String statusName = response.status().name()
// Check statusName ...
})
if (errors) throw new Exception(...)
} finally {
client.close()
preBuiltTransportClient.close()
}
}
}
从我正在使用的对象中,只有PreBuiltTransportClient
和TransportClient
实现了Closeable
,因此我尝试在finally
块中明确关闭它们。
尝试使用.withCloseable()
(Groovy相当于try-with-resources
),但这并没有阻止问题的发生。
我想也许我的bulkRequest.get().getItems().each({response ->
行正在做一些有趣的事情,所以我用以下内容替换它但没有效果:
BulkResponse bulkResponse = bulkRequest.get()
BulkItemResponse[] bulkItemResponses = bulkResponse.getItems()
for (int responseIndex = 0; responseIndex < bulkItemResponses.length; responseIndex++) { ... }
我也尝试用BulkResponse bulkResponse = bulkRequest.get()
替换BulkResponse bulkResponse = bulkRequest.execute().actionGet()
而没有运气。
答案 0 :(得分:0)
ElasticSearch Java REST Client似乎没有这些问题。 我已经切换到它并且没有经历过内存不足的错误。一旦客户端关闭并确定范围,就会释放所有相对较大的字节数组。