這個要比基本的建立-讀取-更新-删除(CRUD)請求要難一些。CRUD操作是處理的單個文檔。這就意味着我們明确的知道叢集中的哪個分片存儲我們想要的文檔。
一個 CRUD 操作隻對單個文檔進行處理,文檔有唯一的組合,由
_index
, _type
, 和 路由值 (預設是該文檔的 _id
)組成。 這表示我們确切的知道此文檔在叢集中哪個分片中。
搜尋請求是更複雜的執行模型,因為我們不知道哪些文檔會與查詢比對,它們可能存在在叢集中的任意一個分片中。一個搜尋請求不得不搜尋我們關注的一個或多個索引中的每個分片拷貝(主分片或者副本分片),以檢視分片中中是否有比對的文檔。
但找到所有比對到文檔隻是完成了一半工作.在
search
API傳回一“頁”結果之前,來自多個分片的結果必須聚合成單個排序的清單。 是以,搜尋在兩階段過程中執行, query
和 fetch
。 https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB6b581f75c9e7b9ec7928b4b19cd0dad8%3Fmethod%3Ddownload%26read%3Dtrue#1-query%E9%98%B6%E6%AE%B5 1. Query階段
在初始化查詢階段(query phase),查詢将廣播到索引中的每個分片的拷貝上(主分片或者副本分片)。每個分片在本地執行搜尋并且建立了比對文檔的優先隊列(priority queue)。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB6b581f75c9e7b9ec7928b4b19cd0dad8%3Fmethod%3Ddownload%26read%3Dtrue#11-%E4%BC%98%E5%85%88%E7%BA%A7%E9%98%9F%E5%88%97 1.1 優先級隊列
優先級隊列
priority queue
隻是一個存有前n個(top-n)比對文檔的有序清單。優先級隊列的大小取決于
from
size
分頁參數。 例如,以下搜尋請求将需要足夠大的優先級隊列來容納100個文檔:
GET /_search
{
"from": 90,
"size": 10
}
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB6b581f75c9e7b9ec7928b4b19cd0dad8%3Fmethod%3Ddownload%26read%3Dtrue#12-query 1.2 Query
Query階段過程如下圖所示:
Query階段包含如下步驟:
(1) 用戶端發送一個
Search
請求給節點 3,節點 3 建立了一個長度為
from+size
的空優先級隊列。
(2) 節點3将搜尋請求轉發到索引中每個分片的一個主分片或副本分片上( forwards the search request to a primary or replica copy of every shard in the index)。 每個分片在本地執行查詢,并将結果添加到大小為
from
+
size
的本地排序的優先級隊列中。
(3) 每個分片将其優先級隊列中的所有文檔的文檔ID和排序值傳回給協調節點節點3,節點3将這些值合并到其自己的優先級隊列中,以生成全局排序的結果清單。
當一個搜尋請求被發送到一個節點,這個節點就變成了協調節點。這個節點的工作是向所有相關的分片廣播搜尋請求并且把它們的響應整合成一個全局的有序結果集。将這個結果集傳回給用戶端。
第一步是将請求廣播到索引裡每個節點的一個主分片或者副本分片上(broadcast the request to a shard copy of every node in the index)。就像document的GET請求一樣,搜尋請求可以被主分片或者任意副本分片處理。是以說更多的副本能夠更高效的提高搜尋。協調節點将在之後的請求中輪詢所有的分片拷貝來分攤負載。
每一個分片在本地執行查詢和建立一個長度為
from+size
的有序優先級隊列——這個長度意味着它自己的結果數量就足夠滿足全局的請求要求。分片傳回一個輕量級的結果清單給協調節點。隻包含文檔ID值和排序需要用到的值,例如_score。
協調節點将這些分片結果合并到其自己的排序優先級隊列中,表示全局排序的結果集。 到此查詢階段結束。
備注
索引可以由一個或多個主分片組成,是以針對單個索引的搜尋請求需要能夠組合來自多個分片的結果。 搜尋多個或所有索引的工作方式完全相同 - 隻是會涉及更多的分片。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB6b581f75c9e7b9ec7928b4b19cd0dad8%3Fmethod%3Ddownload%26read%3Dtrue#2-fetch-%E9%98%B6%E6%AE%B5 2. Fetch 階段
查詢階段标示出哪些文檔滿足我們的搜尋請求,我們隻傳回了文檔ID以及對排序有用的值,并沒有傳回文檔本身。們仍然需要檢索那些文檔。這就是
fetch
階段的工作,過程如下圖所示:
分發階段由以下步驟構成:
(1) 協調節點标示出哪些文檔需要取回,并且向相關分片發出GET請求。
(2) 如果需要,每個分片加載文檔,然後将文檔傳回協調節點。
(3) 一旦所有的文檔都被取回,協調節點将結果傳回給用戶端。
協調節點首先決定哪些文檔是實際需要取回的。例如,如果我們查詢指定
{ "from": 90, "size": 10 }
,那麼前90條結果将會被丢棄,隻需要檢索接下來的10個結果。這些文檔可能來自與查詢請求相關的一個、多個或者全部分片。
協調節點給擁有相關文檔的每個分片建立一個
multi-get request
,并發送請求給同樣處理查詢階段的分片拷貝。
分片加載文檔體--
_source
字段--如果有需要,用
metadata
search snippet highlighting
豐富結果文檔。 一旦協調節點接收到所有的結果文檔,它就組合這些結果為單個響應傳回給用戶端。
原文:
https://www.elastic.co/guide/en/elasticsearch/guide/current/distributed-search.html https://www.elastic.co/guide/en/elasticsearch/guide/current/_query_phase.html https://www.elastic.co/guide/en/elasticsearch/guide/current/_fetch_phase.html