官方API:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-bulk.html
之前和ES support的小伙伴说是我现在就是异步的,会自动进行大小验证,数量验证,然后进行数据提交,而不是同步的。之前因为忙,一直没调研。后面有时间就调研了一下,果然这位同学,看错了。
es rest client 现在bulk api,默认是同步的,而不是异步的。
bulksync才是,所以我把代码拔的过程,重新梳理一遍让自己思路更清楚一点。
但是这里有一个问题,是为什么要异步了?其实这里就是有一个概念,首先从ES插入来说
ES每次提交一个请求都会有一个segement file,如果1000条数据,提交1000次和提交1次里面是1000的处理的性能是完全不同的。当然ES是有segement合并,但是合并就有性能损耗
当然代码我还没看过,所以可以参考一下,其他大佬的文章:
https://blog.csdn.net/jiaojiao521765146514/article/details/83753215
但是个人我,在使用中出现了类似的问题。由于上次调用方无法每次大量数据,拆分成多个小请求,导致偶尔请求高峰,但是我有重试机制,但是长此以往对于扩展肯定不好。所以就带来了下面的研究。
然后在源码分析之前:再来分享一下自己对于ES查询的优化想法。ES查询是倒排索引,以前我总以为直接是把倒排索引直接放内存,放不下就进硬盘。然后一直感觉想法不对。查了一下lucene文档,感觉真的聪明,term dictionry是很大,那么做一个term index来做。
然后term index的索引做成一个二叉树,这样子就牛逼了。时间复杂度又变成了logN.
logN带来的结果是即便数据量再大,也能压缩到很少的。
然后这个推荐看 极客时间的:算法 还有 漫画算法。
算法导论,我是真的服气。刷不完。最主要是算法题还有一个很重要的功能就是面试。哈哈哈。祝福自己面试顺利
然后再补充一下:缓存概念,es缓存分为了 query cache,request cache,fielddata data
所以完全可以把常用的index尽量合并,来提高命中率。同时提高内存。
这样子每次驱逐的是使用低频的index.
/**
* @deprecated If creating a new HLRC ReST API call, consider creating new actions instead of reusing server actions. The Validation
* layer has been added to the ReST client, and requests should extend {@link Validatable} instead of {@link ActionRequest}.
*/
@Deprecated
protected final <Req extends ActionRequest, Resp> Resp performRequest(Req request,
CheckedFunction<Req, Request, IOException> requestConverter,
RequestOptions options,
CheckedFunction<Response, Resp, IOException> responseConverter,
Set<Integer> ignores) throws IOException {
//这里进行request校验
ActionRequestValidationException validationException = request.validate();
if (validationException != null && validationException.validationErrors().isEmpty() == false) {
throw validationException;
}
return internalPerformRequest(request, requestConverter, options, responseConverter, ignores);
}
@Override
//注意这里是子类进行的重写。父亲节点
public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = null;
if (requests.isEmpty()) {
validationException = addValidationError("no requests added", validationException);
}
for (DocWriteRequest<?> request : requests) {
// We first check if refresh has been set
if (((WriteRequest<?>) request).getRefreshPolicy() != RefreshPolicy.NONE) {
validationException = addValidationError(
"RefreshPolicy is not supported on an item request. Set it on the BulkRequest instead.", validationException);
}
//这里的validate是基于iindex的了
ActionRequestValidationException ex = ((WriteRequest<?>) request).validate();
if (ex != null) {
if (validationException == null) {
validationException = new ActionRequestValidationException();
}
validationException.addValidationErrors(ex.validationErrors());
}
}
return validationException;
}
比如这里我使用的都是IndexRequest,一些基本类型的判断,其实没啥价值
@Override
public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = super.validate();
if (source == null) {
validationException = addValidationError("source is missing", validationException);
}
if (Strings.isEmpty(type())) {
validationException = addValidationError("type is missing", validationException);
}
if (contentType == null) {
validationException = addValidationError("