ES索引过程详解:

1.客户端发送索引请求。

  客户端向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轮询算法,进行发送节点的选取。

2.参数检查。

  对请求中的参数进行检查,检查参数是否合法,不合法的参数直接返回失败给客户端。

3.数据预处理

  如果请求指定了pipeline参数,则对数据进行预处理,数据预处理的节点为Ingest Node,如果接受请求的节点不具有数据处理能力,则转发给其他能处理的节点。

  在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.请求预处理

  1)获取集群状态信息,判断集群是否正常;
  2)从集群状态中获取对应索引的元信息,从元信息中获取索引的mapping、version、等信息,从请求中解析routing、id信息,如果请求没有指定文档的id,则会生成一个UUID作为文档的id。
7.路由计算
  根据请求的routing、id信息计算文档应该被索引到哪个分配,计算公式:
shard_num = hash(_routing) % num_primary_shards
  _routing默认值为文档id,num_primary_shards是主分片个数,所以从算法中即可以看出索引的主分片个数一旦指定便无法修改,因为文档利用主分片的个数来进行定位。当使用自定义_routing或者id时,按照上面的公式计算,数据可能会大量聚集于某些分配,造成数据分布不均衡,所以ES提供了routing_partition_size参数,routing_partition_size越大,数据的分布越均匀。分片的计算公式变为:
shard_num = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards
  定位到shard序号后,还需要定位shard所属的数据节点;从集群状态的内容路由表获取主分片所在的节点,并将请求转发至节点。需要注意的是shard到数据节点的映射关系不是固定的,当检测到数据分布不均匀、新节点加入或者节点宕掉等会进行shard重新分配。
8.主分片索引文档
  当主分片所在节点接受到请求后,节点开始进行本节点的文档写入,文档写入过程如下:
  1)文档写入时,不会直接写入到磁盘中,而是先将文档写入到Index Buffer内存空间中,到一定的时间,Index Buffer会Refresh把内存中的文档写入Segment中。当文档在Index Buffer中时,是无法被查询到的,这就是ES不是实时搜索,而是近实时搜索的原因。
  2)因为文档写入时,先写入到内存中,当文档落盘之前,节点出现故障重启、宕机等,会造成内存中的数据丢失,所以索引写入的同时会同步向Transaction Log写入操作内容。
  3)每隔固定的时间间隔ES会将Index Buffer中的文档写入到Segment中,这个写入的过程叫做Refresh,Refresh的时间可以通过index.refresh_interval,默认情况下为1秒。
  4)写入到Segment中并不代表文档已经落盘,因为Segment写入磁盘的过程相对耗时,Refresh时会先将Segment写入缓存,开放查询,也就是说当文档写入Segment后就可以被查询到。每次refresh的时候都会生成一个新的segment,太多的Segment会占用过多的资源,而且每个搜索请求都会遍历所有的Segment,Segment过多会导致搜索变慢,所以ES会定期合并Segment,减少Segment的个数,并将Segment和并为一个大的Segment;在操作Segment时,会维护一个Commit Point文件,其中记录了所有Segment的信息;同时维护.del文件用于记录所有删除的Segment信息。
  单个倒排索引文件被称为Segment。多个Segment汇总在一起,就是Lucene的索引,对应的就是ES中的shard。
  Lucene倒排索引由单词词典及倒排列表组成:
  单词词典:记录所有文档的单词,记录单词到倒排列表的关系,数据量比较大,一般采用B+树,哈希拉链法实现。
  倒排列表:记录单词对应的文档集合,由倒排索引项组成。倒排索引项结构如表所示:其中,文档ID:记录单词所在文档的ID;词频:记录单词在文档中出现的次数;位置:记录单词在文档中的位置;偏移:记录单词的开始位置,结束位置。

    

  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 源码解析与优化实战

【ElasticSearch学习】之一图读懂文档索引全过程的更多相关文章

  1. 【Elasticsearch学习】文档搜索全过程

    在ES执行分布式搜索时,分布式搜索操作需要分散到所有相关分片,若一个索引有3个主分片,每个主分片有一个副本分片,那么搜索请求会在这6个分片中随机选择3个分片,这3个分片有可能是主分片也可能是副本分片, ...

  2. 一张图读懂https加密协议

    搭建CA服务器和iis启用https:http://blog.csdn.net/dier4836/article/details/7719532 一张图读懂https加密协议 https是一种加密传输 ...

  3. 【Zigbee技术入门教程-02】一图读懂ZStack协议栈的基本架构和工作机理

    [Zigbee技术入门教程-02]一图读懂ZStack协议栈的基本架构和工作机理 广东职业技术学院  欧浩源  ohy3686@foxmail.com Z-Stack协议栈是一个基于任务轮询方式的操作 ...

  4. Elasticsearch 创建、更新、删除文档、处理冲突

    ----创建新文档---- 1._index,_type和_id的组合可以唯一标识一个文档,所以确保一个新文档的最简单的办法就是,使用索引请求的POST形式让elsticsearch自动生成唯一_id ...

  5. 一张图读懂PBN飞越转弯衔接DF航段计算

    飞越转弯衔接TF航段时,转弯外边界与旁切转弯相似,只是在拐角位置直接以风螺旋绘制外边界,大部分切点可以精确计算得到. 飞越转弯衔接DF航段时,转弯外边界全部由风螺旋和它的切线构成,又会有哪些神奇的事情 ...

  6. 一张图读懂PBN飞越转弯衔接TF/CF航段计算

    在PBN旁切转弯的基础上,再来看飞越转弯接TF(或CF)航段,保护区结构上有些相似,只是转弯拐角处的保护区边界有“简化”,其余部分是相近的. FlyOver接TF段的标称航迹有一个飞越之后转弯切入航迹 ...

  7. 【Zigbee技术入门教程-02】一图读懂ZStack协议栈的核心思想与工作机理

    [Zigbee技术入门教程-02]一图读懂ZStack协议栈的核心思想与工作机理 广东职业技术学院  欧浩源   Z-Stack协议栈是一个基于任务轮询方式的操作系统,其任务调度和资源分配由操作系统抽 ...

  8. SpringBoot学习笔记:Swagger实现文档管理

    SpringBoot学习笔记:Swagger实现文档管理 Swagger Swagger是一个规范且完整的框架,用于生成.描述.调用和可视化RESTful风格的Web服务.Swagger的目标是对RE ...

  9. 比传统事务快10倍?一张图读懂阿里云全局事务服务GTS

    近日,阿里云全局事务服务GTS正式上线,为微服务架构中的分布式事务提供一站式解决方案.GTS的原理是将分布式事务与具体业务分离,在平台层面开发通用的事务中间件GTS,由事务中间件协调各服务的调用一致性 ...

随机推荐

  1. Scratch 全套学习资料

    链接:https://pan.baidu.com/s/1qX0T2B_zczcLaCCpiRrsnA提取码:xfp8

  2. C语言 文件操作(一)

    #include<stdio.h> int main(){          FILE *fp = fopen("f:\\lanyue.txt","r&quo ...

  3. 一个java 码手 的老牛 --- 涉及 一些不错的java 基础课程

    http://www.zuidaima.      com/user/1550463811307520/share/collect.htm

  4. CORS漏洞的学习与分析

    同源策略 同源策略(Same origin policy)是一种约定,一种非常重要的安全措施,也是最基本的安全功能,它禁止了来自不同源的脚本对当前页面的读取或修改,从而限制了跨域访问甚至修改资源,防止 ...

  5. 【小学数学】算术口诀 独立音频MP3

    算术口诀 独立音频MP3 原文载于本人个人网站:http://www.unlimitedbladeworks.cc/writing_202004_01_sskj 特点 加法口诀 乘法口诀 独立音频 m ...

  6. AJ学IOS(13)UI之UITableView学习(下)汽车名牌带右侧索引

    AJ分享,必须精品 先看效果图 代码 ViewController #import "NYViewController.h" #import "NYCarGroup.h& ...

  7. Docker搭建Nessus pro笔记

    0x01 准备Docker环境 拉取镜像: docker pull ubuntu 创建容器: docker run -p 9922:22 -p 8834:8834 --name nessus -it ...

  8. ASP.NET MVC学习——控制器传递数据到view的简单案例

    从控制传数据到view端的方法: 方法一:修改Control数据,添加ViewBag 1.ViewBag.+ 任意变量名 = "你想要输入的数据" 2.在Control对应的csh ...

  9. Linux常见提权

    常见的linux提权 内核漏洞提权 查看发行版 cat /etc/issue cat /etc/*-release 查看内核版本 uname -a 查看已经安装的程序 dpkg -l rpm -qa ...

  10. Spiking-YOLO : 前沿性研究,脉冲神经网络在目标检测的首次尝试 | AAAI 2020

    论文提出Spiking-YOLO,是脉冲神经网络在目标检测领域的首次成功尝试,实现了与卷积神经网络相当的性能,而能源消耗极低.论文内容新颖,比较前沿,推荐给大家阅读   来源:晓飞的算法工程笔记 公众 ...