对bulk request的处理流程:

1、遍历所有的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)。

2、创建一个shardId--> Operation的Map,再次遍历所有的request,获取获取每个request应该发送到的shardId,获取的过程是这样的:request有routing就直接返回,如果没有,会先对id求一个hash,这里的hash函数默认是Murmur3,当然你也可以通过配置index.legacy.routing.hash.type来决定使用的hash函数,决定发到哪个shard:

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

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

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

上述1中的ID生成算法:

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

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

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插入的详细说明

ES批量索引写入时的ID自动生成算法的更多相关文章

  1. ThinkPHP出现项目目录不可写,目录无法自动生成

    问题描述:维护一个老项目,用的TP2.1,down完代码,配好环境,访问的时候出现“项目目录不可写,目录无法自动生成!请使用项目生成器或者手动生成项目目录~”: 问题原因:在linux 服务器上,th ...

  2. 新引入thinkphp报错“应用目录[./Application/]不可写,目录无法自动生成! 请手动生成项目目录~”

    新引入thinkphp报错“应用目录[./Application/]不可写,目录无法自动生成! 请手动生成项目目录~”, 其主要原因是文件夹的权限问题,手动将项目文件夹权限更改为可读可写就OK,具体操 ...

  3. es批量索引

    使用Python操作Elasticsearch数据索引的教程 这篇文章主要介绍了使用Python操作Elasticsearch数据索引的教程,Elasticsearch处理数据索引非常高效,要的朋友可 ...

  4. Elasticsearch 索引文档如何使用自动生成 Id?

    一个文档的 _index . _type 和 _id 唯一标识一个文档. 我们可以提供自定义的 _id 值,或者让 index API 自动生成. 如果你的数据没有自然的 ID, Elasticsea ...

  5. 在SQL2008中,如何让id自动生成并自动递增?如何让时间默认生成?

    id自动递增:    如果是用语句操作,这样定义:ID INT IDENTITY,如果是要生成一对数字,这样定义:ID INT IDENTITY(1,1)    如果要在SQL Server的表中设置 ...

  6. thinkphp应用目录不可写,目录无法自动生成! 请手动生成项目目录~

    一是 要把 html下的相关目录设置成 777 chmod -R 777 /var/www/html/..... 二是 要设置 selinux , 或者是 临时 关闭 selinux: setenfo ...

  7. 写一个umi插件 自动生成代码 解放cv的双手

    引言 最近在写一个中台项目,使用的react的umi框架. 各种增删改查.基本是列表页 新建页 详情页这种页面 为了避免不必要的简单重复(主要是想偷懒) 于是想去实现自己的一个代码生成器 探索 首先, ...

  8. 写一个TT模板自动生成spring.net下面的配置文件。

    这个是目标. 然后想着就怎么开始 1.

  9. 自动生成.py文件头部的C语言小程序

    每次都 vi xxx.py 然后再打 #!/usr/bin/env python 等等的程序头信息感觉有点麻烦,于是便想着写一个小程序自动生成这些头信息了,顺便在 ~/.bashrc 里写入 alia ...

随机推荐

  1. 散列表(HashTable)

    散列表 i. 散列函数 i. 冲突解决 ii. 分离链表法 ii. 开放地址法 iii. 线性探测法 iii. 平方探测法 iii. 双散列 ii. 再散列 ii. 可扩散列 i. 装填因子:元素个数 ...

  2. ELK之elasticsearch6.5

    官方网站:https://www.elastic.co/guide/en/elasticsearch/reference/current/rpm.html 这里采用rpm的方式安装: # wget h ...

  3. 20145332卢鑫 MSF基础应用

    20145332卢鑫 MSF基础应用 实验过程 靶机的IP地址:192.168.10.160 Kali的IP地址:192.168.10.128 1.一个主动攻击 攻击XP系统的漏洞:ms08_067 ...

  4. 【TCP/IP详解 卷一:协议】第9章 IP选路

    推荐链接:网络地址与主机地址 9.1 引言 路由选择程序(daemon),通常这是一个用户进程.在大多数的Unix系统中,大多数的路由选择程序都是路由程序和网关程序. 路由表经常被IP访问,但是它被路 ...

  5. hdu 5524 Subtrees dfs

    Subtrees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Probl ...

  6. shell 无限循环输出时间

    #!/bin/bash while(true) do date >> /home/k/a.log sleep done 查看 tail -f /home/k/a.log

  7. python 集合从头部删除元素

    num_set = , , , , ]) num_set.pop() print(num_set) num_set.pop() print(num_set)

  8. c++ 判断给定区间是否是一个heap. O(N) (is_heap)

    #include <iostream> // cout #include <algorithm> // is_heap, make_heap, pop_heap #includ ...

  9. Linux更改主机名

    1.临时 # hostname newhostname 2.修改/etc/hostname文件,需重启 # vim /etc/hostname 3.查看 # hostname Ubuntu18 # h ...

  10. BeautifulSoup中的select方法

    在写css时,标签名不加任何修饰,类名前加点,id名前加 #,我们可以用类似的方法来筛选元素,用到的方法是soup.select(),返回类型是list. (1).通过标签名查找 print(soup ...