Elasticsearch寫入原理深入詳解

1、題記:

Elasticsearch寫入流程,網上有視頻、筆記等各種版本,本文結合最新官方文檔進行重新梳理,節省大家的時間。
思考如下幾個問題?

1、爲什麼Elasticsarch是近實時,而不是準實時?
2、爲什麼文檔的CRUD操作是實時的?
3、爲什麼Elasticsearch能做到保證數據不丟失?
4、Refresh、flush的作用是什麼? 什麼時候使用?
5、Elasticsearch存儲怎麼讓數據保存在磁盤上,而不是在內存上?

本文會給出以上問題的答案。

2、Elasticsearch寫入核心概念

2.1 索引 index

Elasticsearch中的“索引”有點像關係數據庫中的數據庫。 它是存儲/索引數據的地方。

2.2 分片 shard

“分片”是Lucene的一個索引。 它本身就是一個功能齊全的搜索引擎。
“索引”可以由單個分片組成,但通常由多個分片組成,一部分主分片、一部分副本分片。
ES默認5個主分片,1個副本分片;
副本分片的用途:(1)主節點故障時的故障轉移;(2)增加的讀取吞吐量。

2.3 分段 segment

每個分片包含多個“分段”,其中分段是倒排索引。
分段內的doc數量上限是2的31次方。
默認每秒都會生成一個segment文件.
在分片中搜索將依次搜索每個片段,然後將其結果合併到該分片的最終結果中。
查看索引中分段信息的方法:

GET /test/_segments

2.4 倒排索引

“倒排索引”是Lucene用於使數據可搜索的數據結構。

一圖勝千言!如下:索引、分片、分段的關係一目瞭然。
在這裏插入圖片描述

2.5 translog日誌文件:

爲了防止elasticsearch宕機造成數據丟失保證可靠存儲,es會將每次寫入數據同時寫到translog日誌中。
translog還用於提供實時CRUD。 當您嘗試按ID檢索,更新或刪除文檔時,它會首先檢查translog中是否有任何最近的更改,然後再嘗試從相關段中檢索文檔。 這意味着它始終可以實時訪問最新的已知文檔版本。

2.6、倒排索引是不可變的

寫入磁盤的倒排索引永遠不會改變。
好處:無需鎖定,不用擔心多進程操作更改數據導致數據不一致問題。
壞處:經常被問到的問題,更新了詞典詞庫後,老的索引不能生效。如果要使其可搜索,則必須重建整個索引。建議:reindex操作。

2.7 分段不可變

分段是不可變的。更新文檔時,它實際上只是將舊文檔標記爲已刪除,併爲新文檔編制索引。合併過程還會清除這些舊的已刪除文檔。

3、Elasticsearch寫入步驟拆解

步驟1:新document首先寫入內存Buffer緩存中。
步驟2:每隔一段時間,執行“commitpoint”操作,buffer寫入新Segment中。
步驟3:新segment寫入文件系統緩存 filesystem cache。
步驟4:文件系統緩存中的index segment被fsync強制刷到磁盤上,確保物理寫入。
此時,新egment被打開供search操作。
步驟5:清空內存buffer,可以接收新的文檔寫入。

官方解讀地址:http://t.cn/EyhPQt5
這是傳統意義的寫入步驟,實際ES爲保證實時性,會做refresh操作。

#4、Elasticsearch refresh和flush

4.1、refresh操作

相比於Lucene的提交操作,ES的refresh是相對輕量級的操作。
先將index-buffer中文檔(document)生成的segment寫到文件系統之中,這樣避免了比較損耗性能io操作,又可以使搜索可見。
默認1s鍾刷新一次,所以說ES是近實時的搜索引擎,不是準實時。
注意:實際需要結合自己的業務場景設置refresh頻率值。調大了會優化索引速度。注意單位:s代表秒級。

PUT /my_logs
{
  "settings": {
    "refresh_interval": "30s" 
  }
}

4.2、flush操作

新創建的document數據會先進入到index buffer之後,與此同時會將操作記錄在translog之中,當發生refresh時ranslog中的操作記錄並不會被清除,而是當數據從filesystem cache中被寫入磁盤之後纔會將translog中清空
從filesystem cache寫入磁盤的過程就是flush。

步驟1:當translog變得太大時 ,可以執行commit ponit操作。
步驟2:使用fsync刷新文件系統緩存,寫入磁盤。
步驟3:舊緩衝區被清除。

flush操作如下:

POST /_flush?wait_for_ongoing 

5、圖解Elasticsearch寫入持久化模型

在這裏插入圖片描述
圖的示意圖要從上往下看。
1、當新的文檔寫入後,寫入 index buffer的同時會寫入translog。
2、refresh操作使得寫入文檔搜索可見;
3、flush操作使得filesystem cache寫入磁盤,以達到持久化的目的。

6、小結

相信經過梳理,開篇幾個問題的答案便非常清晰了。
知識的累積,需要過程,《高手》中尤其強調第一手文檔的重要性。
第一手的官方文檔+源碼是根基,是最快、最準的方式。

參考:
[1] 官方文檔:https://www.elastic.co/guide/en/elasticsearch/guide/master/translog.html
[2] 對比:https://stackoverflow.com/questions/19963406/refresh-vs-flush
[3] http://www.uml.org.cn/bigdata/201801263.asp
[4] https://stackoverflow.com/questions/15426441/understanding-segments-in-elasticsearch
[5] http://www.cnblogs.com/smile361/p/7483561.html
[6] https://blog.csdn.net/R_P_J/article/details/82254494
[7] 讀寫:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-replication.html

Elasticsearch基礎
Elasticsearch基礎、進階、實戰第一公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章