ES讀寫流程

簡述ES的寫流程,GET讀取數據流程和Search搜索數據流程。

ES的讀寫流程主要是協調節點,主分片節點、副分片節點間的相互協調。

ES的讀取分為GET和Search兩種操作。GET根據文檔id從正排索引中獲取內容;Search不指定id,根據關鍵字從倒排索引中獲取內容。

寫單個文檔的流程

  1. 客戶端向集群中的某個節點發送寫請求,該節點就作為本次請求的協調節點;
  2. 協調節點使用文檔ID來確定文檔屬於某個分片,再通過集群狀態中的內容路由表信息獲知該分片的主分片位置,將請求轉發到主分片所在節點;
  3. 主分片節點上的主分片執行寫操作。如果寫入成功,則它將請求並行轉發到副分片所在的節點,等待副分片寫入成功。所有副分片寫入成功後,主分片節點向協調節點報告成功,協調節點向客戶端報告成功。

讀取單個文檔的流程

  1. 客戶端向集群中的某個節點發送讀取請求,該節點就作為本次請求的協調節點;

  2. 協調節點使用文檔ID來確定文檔屬於某個分片,再通過集群狀態中的內容路由表信息獲知該分片的副本信息,此時它可以把請求轉發到有副分片的任意節點讀取數據。

    協調節點會將客戶端請求輪詢發送到集群的所有副本來實現負載均衡。

  3. 收到讀請求的節點將文檔返回給協調節點,協調節點將文檔返回給客戶端

Search流程

ES的Search操作分為兩個階段:query then fetch。需要兩階段完成搜索的原因是:在查詢時不知道文檔位於哪個分片,因此索引的所有分片都要參與搜索,然後協調節點將結果合併,在根據文檔ID獲取文檔內容。

Query查詢階段

  1. 客戶端向集群中的某個節點發送Search請求,該節點就作為本次請求的協調節點;
  2. 協調節點將查詢請求轉發到索引的每個主分片或者副分片中;
  3. 每個分片在本地執行查詢,並使用本地的Term/Document Frequency信息進行打分,添加結果到大小為from+size的本地有序優先隊列中;
  4. 每個分片返回各自優先隊列中所有文檔的ID和排序值給協調節點,協調節點合併這些值到自己的優先隊列中,產生一個全局排序後的列表。

Fetch拉取階段

query節點知道了要獲取哪些信息,但是沒有具體的數據,fetch階段要去拉取具體的數據。相當於執行多次上面的GET流程

  1. 協調節點向相關的節點發送GET請求;
  2. 分片所在節點向協調節點返回數據;
  3. 協調階段等待所有的文檔被取得,然後返回給客戶端。

參考自《ES源碼解析與優化實踐》