ES批量索引写入时的ID自动生成算法

对bulk request的处理流程:html

一、遍历全部的request,对其作一些加工,主要包括:获取routing(若是mapping里有的话)、指定的timestamp(若是没有带timestamp会使用当前时间),若是没有指定id字段,在action.bulk.action.allow_id_generation配置为true的状况下,会自动生成一个base64UUID做为id字段,并会将request的opType字段置为CREATE,由于若是是使用es自动生成的id的话,默认就是createdocument而不是updatedocument。(注:坑爹啊,我从github上面下的最新的ES代码,发现自动生成id这一段已经没有设置opType字段了,看起来和有指定id是同样的处理逻辑了,见https://github.com/elastic/elasticsearch/blob/master/core/src/main/java/org/elasticsearch/action/index/IndexRequest.java)。java

二、建立一个shardId--> Operation的Map,再次遍历全部的request,获取获取每一个request应该发送到的shardId,获取的过程是这样的:request有routing就直接返回,若是没有,会先对id求一个hash,这里的hash函数默认是Murmur3,固然你也能够经过配置index.legacy.routing.hash.type来决定使用的hash函数,决定发到哪一个shard:node

return MathUtils.mod(hash, indexMetaData.getNumberOfShards());git

即用hash对shard的总数求模来获取shardId,将shardId做为key,经过遍历的index和request组成BulkItemRequest的集合做为value放入以前说的map中(为何要拿到遍历的index,由于在bulk response中能够看到对每一个request的请求处理结果的),其实说了这么多就是要对request按shard来分组(为负载均衡)。github

三、遍历上面获得的map,对不一样的分组建立一个bulkShardRequest,包含配置consistencyLevel和timeout。并从集群state中得到primary shard,若是primary在本机就直接执行,若是不在会再发送到其shard所在的node。算法

 

上述1中的ID生成算法:api


对于ES1.71版本,所处包为org.elasticsearch.action.index.IndexRequestapp

void org.elasticsearch.action.index.IndexRequest.process(MetaData metaData, @Nullable MappingMetaData mappingMd, boolean allowIdGeneration, String concreteIndex) throws ElasticsearchException
{
............
// generate id if not already provided and id generation is allowed if (allowIdGeneration) { if (id == null) { id(Strings.base64UUID()); // since we generate the id, change it to CREATE opType(IndexRequest.OpType.CREATE); autoGeneratedId = true; } }
............
}

 

IndexRequest org.elasticsearch.action.index.IndexRequest.id(String id)负载均衡

Sets the id of the indexed document. If not set, will be automatically generated.
Parameters:
id dom


String org.elasticsearch.common.Strings.base64UUID()

Generates a time-based UUID (similar to Flake IDs), which is preferred when generating an ID to be indexed into a Lucene index as primary key. The id is opaque and the implementation is free to change at any time!

/** Generates a time-based UUID (similar to Flake IDs), which is preferred when generating an ID to be indexed into a Lucene index as
* primary key. The id is opaque and the implementation is free to change at any time! */
public static String base64UUID() {
    return TIME_UUID_GENERATOR.getBase64UUID();
}

 

 

参考: 

https://discuss.elastic.co/t/generate-id/28536/2

https://www.elastic.co/blog/performance-considerations-elasticsearch-indexing 

https://github.com/elastic/elasticsearch/pull/7531/files ES历史版本的改动能够在这里看到,最开始ES使用的是randomBase64UUID,出于性能后来用了相似Flake的ID!

http://xbib.org/elasticsearch/2.1.1/apidocs/org/elasticsearch/common/Strings.html

http://www.opscoder.info/es_indexprocess1.html 有bulk插入的详细说明

相关文章
相关标签/搜索