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 源碼解析與優化實戰》