ES 分佈式搜索的運行機制
ES 有兩種 search_type
即搜索類型:git
query_then_fetch
(默認)dfs_query_then_fetch
query_then_fetch
- 用戶發起搜索,請求到集羣中的某個節點。
- query 會被髮送到全部相關的 shard 分片上。
- 每一個 shard 分片獨立執行 query 搜索文檔並進行排序分頁等,打分時使用的是分片自己的
Local
Term/Document 頻率。 - 分片的 query 結果(只有元數據,例如
_id
和_score
)返回給請求節點。 - 請求節點對全部分片的 query 結果進行彙總,而後根據打分排序和分頁,最後選擇出搜索結果文檔(也只有元數據)。
- 根據元數據去對應的 shard 分片拉取存儲在磁盤上的文檔的詳細數據。
- 獲得詳細的文檔數據,組成搜索結果,將結果返回給用戶。
缺點:因爲每一個分片獨立使用自身的而不是全局的 Term/Document 頻率進行相關度打分,當數據分佈不均勻時可能會形成打分誤差,從而影響最終搜索結果的相關性。github
dfs_query_then_fetch
dfs_query_then_fetch
與 query_then_fetch
的運行機制很是相似,可是有兩點不一樣。網絡
- 用戶發起搜索,請求到集羣中的某個節點。
- 預查詢每一個分片,獲得全局的 Global Term/Document 頻率。
- query 會被髮送到全部相關的 shard 分片上。
- 每一個 shard 分片獨立執行 query 搜索文檔並進行排序分頁等,打分時使用的是分片自己的
Global
Term/Document 頻率。 - 分片的 query 結果(只有元數據,例如
_id
和_score
)返回給請求節點。 - 請求節點對全部分片的 query 結果進行彙總,而後根據打分排序和分頁,最後選擇出搜索結果文檔(也只有元數據)。
- 根據元數據去對應的 shard 分片拉取存儲在磁盤上的文檔的詳細數據。
- 獲得詳細的文檔數據,組成搜索結果,將結果返回給用戶。
缺點:太耗費資源,通常仍是不建議使用。分佈式
經驗
- 雖然 ES 有兩種搜索類型,但通常仍是都用默認的
query_then_fetch
。 - 當數據量沒有足夠大的狀況下(好比搜索類型數據 20GB,日誌類型數據 20-50GB),設置一個 shard 主分片是比較推薦的,只設置一個主分片,你會發現搜索時省掉了好多事情。
- 不須要文檔數據時,使用
_source: false
能夠避免請求節點到非本機分片的網絡耗時以及讀取磁盤文件的耗時。 - 使用 from + size 分頁時,假設你只須要前 10k 條數據裏的最後十條,那麼每一個分片也會取 10k 條數據,若是你的索引有 5 個主分片,那麼彙總時就有 5 * 10k = 50k 條數據,這 50k 條數據是在內存裏進行排序和最後的分頁的,因此深度分頁也是比較吃資源的。
本文同步分享在 博客「rife」(SegmentFault)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。fetch