1. 程式人生 > 實用技巧 >elasticsearch文件檢索流程

elasticsearch文件檢索流程

這裡以es多節點叢集部署來做說明。單節點與之類似。基於es 7.1版本。

叢集模式下,對於document的檢索稱為 Distribute document search。在簡單的三節點叢集中,假設一個index有兩個primary shard,每個shard有2個replicate。如下圖:其中,P0,P1為兩個primary shard,NODE1和NODE2上的R0為P0的兩個replicate,NODE2和NODE3上的R1為P1的兩個replicate。P0+R0+R0為一個replicate group,P1+R1+R1為一個replicate group。按照es的儲存原則,一個節點上至多儲存同一個replicate group中的一個shard。

我們知道,es的底層是lucene,而lucene是一個全文搜尋引擎,顯而易見的,es很重要的功能就是全文檢索,附帶資料儲存功能。當叢集接收到來自客戶端的文件檢索請求,es除了要返回符合條件的內容,還要對返回的內容進行打分,按照搜尋引擎的工作形式,將打分從高(也既從es看來最符合使用者要求的資料)到低的順序返回給客戶端。es將這兩項工作分成了兩步來完成:query+fetch

首先,叢集中的某個節點,接收到來自客戶端的request,request可能包含了某個條件,並且包含了分頁引數from和size,假設是這樣的:

GET ac_blog/_search?preference=123456789
{ "query": { "bool": { "must": [ {"match": { "title": "entry" }} ] } }, "from":100, "size":10 }

要從ac_blog這個index獲取title(text型別)包含entry的文件,獲取排序100--109的document。這裡留意一下,es裡,from的下標是從0開始的。

query

要完成這個request,在query的步驟裡,es將請求分發到各個replicate group中的一個shard裡,至於是哪個shard,es是採用round-robin的方式選擇shard的(在7.1版本,還會額外考慮

allocation awarenessadaptive replica selection),確保各個shard的負載均衡。shard在自己內部根據條件檢索到對應的文件,並按照_score由高到低排序,獲取從0到109共110個文件的_id以及_score返回給node3。為哈是110個而不是10個,這個後面解釋。如下圖所示:

1,request到達node3,此時node3作為coordinator;
2,node3分發請求到node1的P1分片和NODE2的R0分片;
3,P1和R0在分片內部檢索資料,並返回id與score給node3.

fetch

此時,NODE3拿到了220個文件,然後從這220個文件裡,按照score從高到低排序,取100-109排序的文件,其餘丟棄。然後根據文件id構造_mget請求,到對應的分片獲取document的完整內容,並返回給客戶端。這是fetch階段。如下圖所示:

1,node3將選中的文件id發回對應分片;
2,分片返回完整document內容;
3,node3將文件內容返回給客戶端.

到此,整個檢索過程就結束了。但是其中有一些細節需要詳細描述。

首先,query階段,分片為何返回110個文件,而不是10個文件給coordinator?這是因為分片是在各自的內部進行排序的,這只是區域性的順序,並不是整個index的全域性排序,因此需要將前110個文件返回給coordinator,由coordinator進行全域性排序,確定最終的結果。這也是整個檢索過程中較為耗時的地方。假如請求的是from=100000,size=10呢?假如有10個replicate group呢?資源耗費巨大。