说明:本文章使用的ES版本是:6.7.0
java
在上一篇文章搜索引擎ElasticSearch的启动过程中,介绍了ES的启动过程。node
由此可知,在ES启动过程当中,建立Node对象(new Node(environment))时,初始化了RestHandler,由其名字能够知道这是用来处理Rest请求的。git
在ES源码中,RestHandlerAction以下图:github
其中:算法
adminsql
接下来咱们具体的看一下ES是如何建立索引的:org.elasticsearch.rest.action.document.RestIndexAction
数据库
一个完整的ES集群由如下几个基本元素组成json
名称 | 概念 | 对应关系型数据库概念 | 说明 |
---|---|---|---|
Cluster | 集群 | 一个或多个节点的集合,经过启动时指定名字做为惟一标识,默认cluster-state | |
node | 节点 | 启动的ES的单个实例,保存数据并具备索引和搜索的能力,经过名字惟一标识,默认node-n | |
index | 索引 | Database | 具备类似特色的文档的集合,能够对应为关系型数据库中的数据库,经过名字在集群内惟一标识 |
type | 文档类别 | Table | 索引内部的逻辑分类,能够对应为Mysql中的表,ES 6.x 版本中,一个索引只容许一个type,再也不支持多个type。7.x版本中,type将废弃。 |
document | 文档 | Row | 构成索引的最小单元,属于一个索引的某个类别,从属关系为: Index -> Type -> Document,经过id 在Type 内惟一标识 |
field | 字段 | Column | 构成文档的单元 |
mapping | 索引映射(约束) | Schema | 用来约束文档字段的类型,能够理解为索引内部结构 |
shard | 分片 | 将索引分为多个块,每块叫作一个分片。索引定义时须要指定分片数且不能更改,默认一个索引有5个分片,每一个分片都是一个功能完整的Index,分片带来规模上(数据水平切分)和性能上(并行执行)的提高,是ES数据存储的最小单位 | |
replicas | 分片的备份 | 每一个分片默认一个备份分片,它能够提高节点的可用性,同时可以提高搜索时的并发性能(搜索能够在所有分片上并行执行) |
一个ES集群的结构以下:安全
每一个节点默认有5个分片,每一个分片有一个备分片。并发
6.x版本以前的索引的内部结构:
说明:ES 6.x 版本中,相同索引只容许一个type,再也不支持多个type。7.x版本中,type将废弃。
因此,6.x版本的索引结构以下:
7.x版本的索引结构以下:
启动ES实例后,发送以下请求:
curl -X PUT 'localhost:9200/index_name/type_name/1' -H 'Content-Type: application/json' -d ' { "title": "我是文件标题,可被搜索到", "text": "文本内容,ES时如何索引一个文档的", "date": "2019/01/01" }'
其中:
RestIndexAction#prepareRequest:封装request,识别行为,容许的行为以下,默认INDEX
enum OpType { // Index the source. If there an existing document with the id, it will be replaced. INDEX(0), // Creates the resource. Simply adds it to the index, if there is an existing document with the id, then it won't be removed. CREATE(1), /** Updates a document */ UPDATE(2), /** Deletes a document */ DELETE(3); ... }
参数检查,查看是否有关键字,并获取相关关键字的值
0 = "parent" 1 = "pretty" 2 = "version_type" 3 = "format" 4 = "index" 5 = "refresh" 6 = "error_trace" 7 = "type" 8 = "timeout" 9 = "pipeline" 10 = "routing" 11 = "if_seq_no" 12 = "if_primary_term" 13 = "wait_for_active_shards" 14 = "id" 15 = "op_type" 16 = "human" 17 = "filter_path"
indices:data/write/index
TransportAction#execute():将请求封装成CreateIndexRequest并发送到服务端,处理发送前置任务
这里若是是更新或者删除操做,检查是否传入ID字段,没传如则报错
if (opType() != OpType.INDEX && id == null) { addValidationError("an id is required for a " + opType() + " operation", validationException); }
Transport将request封装成Task,将请求发送给服务端
读取AutoCreateIndex#AUTO_CREATE_INDEX_SETTING,该值由配置文件elasticsearch.yml
中的auto_create_index
控制,true表示当插入的索引不存在时,自动建立该索引
若是"auto_create_index"为true:
而后遍历indices,判断索引名称是否存在
onlyCreateIndex方法,其内部执行clusterService.submitStateUpdateTask,提交集群状态修改任务,提交任务的执行逻辑是AckedClusterStateUpdateTask类内部的execute方法。其内部逻辑为:
上一步修改完成clusterstate后
遍历request中的文档