說明:本文章使用的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中的文檔