ES索引过程详解:java
1.客户端发送索引请求。node
客户端向ES节点发送索引请求,以RestClient客户端发起请求为例:算法
ES提供了Java High Level REST Client,用户能够经过RestClient发送请求:缓存
RestClient restClient = RestClient.builder( new HttpHost("127.0.0.1", 9200, "http"), new HttpHost("127.0.0.2", 9200, "http") ).build();
其中127.0.0.1,127.0.0.1是ES中的节点,ES在接受请求时,充当coordinate node节点的角色,若是设置有专用coorinate node则应该将接受客户端请求的节点设置为该专用节点,负责请求的接受和转发。在RestClient中使用round-robin轮询算法,进行发送节点的选取。app
2.参数检查。学习
对请求中的参数进行检查,检查参数是否合法,不合法的参数直接返回失败给客户端。优化
3.数据预处理ui
若是请求指定了pipeline参数,则对数据进行预处理,数据预处理的节点为Ingest Node,若是接受请求的节点不具备数据处理能力,则转发给其余能处理的节点。spa
在Ingest Node上有定义好的处理数据的Pipeline,Pipeline中有一组定义好的Processor,每一个Processor分别具备不一样的处理功能,ES提供了一些内置的Processor,如:split、join、set 、script等,同时也支持经过插件的方式,实现自定义的Processor。数据通过Pipeline处理完毕后继续进行下一步操做。插件
4.判断索引是否存在
判断索引是否存在。若是索引不存在,则判断是否可以自动建立,能够经过action.auto_create_index设置可否自动建立索引;若是节点支持Dynamic Mapping,写入文档时,若是字段还没有在mapping中定义,则会根据索引文档信息推算字段的类型,但并不能彻底推算正确。
配置:Dynamic:true时,文档有新增字段的时候,索引的mapping也会同步更新。
Dynamic:false时,索引的mapping不会被更新,新增字段没法被索引到。
Dynamic:strict时,索引有新增字段时,将会报错。
注:生产环境尽可能避免使用Dynamic mapping,以避免过多字段致使cluster state占用过多。
5.建立索引
建立索引请求被发送到Master节点,由Master节点负责进行索引的建立,索引建立成功后,Master节点会更新集群状态clusterstate,更新完毕后将索引建立的状况返回给Coordinate节点,收到Master节点返回的全部建立索引的响应后,进入下一流程。
6.请求预处理
shard_num = hash(_routing) % num_primary_shards
routing_partition_size参数,
routing_partition_size越大,数据的分布越均匀。分片的计算公式变为:
shard_num = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards
5)每隔必定的时间(默认30分钟),ES会调用Flush操做,Flush操做会调用Refresh将Index Buffer清空;而后调用fsync将缓存中的Segments写入磁盘;随后清空Transaction Log。同时当Transaction Log空间(默认512M)后也会触发Flush操做。
9.副本分片索引文档
当主分片完成索引操做后,会循环处理要写的全部副本分片,向副本分片所在的节点发送请求。副本分片执行和主分片同样的文档写入流程,而后返回写入结果给主分片节点。
10.请求返回
主分片收到副本分片的响应后,会执行finish()操做,将收到的响应信息返回给Coordinate节点,告知Coordinate节点文档写入分片成功、失败的状况;coordinate节点收到响应后,将索引执行状况返回给客户端。当文档写入失败时,主分片节点会向Master节点返送shardFieled请求,由于主副本分片未同步,Master会更新集群的状态,将写失败的副本分片从in-sync-allocation中去除;同时在路由表中将该分片的状态改成unassigned,即未分配状态。
学习来源:
阮一鸣《Elasticsearch核心技术与实战》
张超《Elasticsearch 源码解析与优化实战》