<input id="ohw05"></input>
  • <table id="ohw05"><menu id="ohw05"></menu></table>
  • <var id="ohw05"></var>
  • <code id="ohw05"><cite id="ohw05"></cite></code>
    <label id="ohw05"></label>
    <var id="ohw05"></var>
  • Elasticsearch核心技術(五):搜索API和搜索運行機制

    本文將從數據存儲和搜索的角度簡單分析Elasticsearch的搜索運行機制,主要涉及搜索API、搜索機制、存在問題和解決方案。

    4.1 Search API

    Search API允許用戶執行一個搜索查詢并返回匹配查詢的搜索命中結果。

    Elasticsearch查詢主要有兩種方式:URI SearchRequest Body Search

    • URI Search:通過URI參數實現搜索,特點是操作簡便,僅包含部分查詢語法,常用參數如下:
      q:指定查詢語句,使用Query String Syntax
      df:默認字段,不指定時,會對所有字段進行查詢
      sort:排序
      profile:用于查看查詢是如何被執行的

    • Request Body Search:完備的查詢語法Query DSL,所以還是建議使用Request Body Search。

    4.2 深入了解Search運行機制

    建議先參考上篇Elasticsearch核心技術(四):分布式存儲架構與索引原理分析,其中主要介紹了ES的分布式存儲架構和原理。

    4.2.1 Query-then-Fetch運行機制

    Elasticsearch的分布式搜索的運行機制稱為Query-then-Fetch。具體分為Query和Fetch兩個階段:

    Query階段

    用戶發出搜索請求到達ES節點。節點收到請求后,會以協調節點(Coordinating Node)的身份,在6個主副分片中隨機選擇3個分片,發送查詢請求。

    被選中的節點,進行排序(根據score值進行排序)。然后每個分片都返回 From+size 個排序后的文檔id和排序值給協調節點。 注意這里返回的是文檔id。

    Fetch階段

    Coordinating節點將Query階段從每個分片獲取的排序的文檔id列表重新進行排序,選取 From 到 From+size 個文檔的id。

    multi get請求的方式,到相應的分片獲取詳細的文檔數據。

    4.2.2 為什么需要兩階段才能完成搜索

    因為Elasticsearch在查詢的時候不知道文檔位于哪個分片,因此索引的所有分片都要參與搜索,然后協調節點將結果合并,在根據文檔ID獲取文檔內容。例如現在有5個分片,需要查詢匹配度Top10的數據,那么每個分片都要查詢出當前分片的Top10的數據,協調節點將5×10個結果再次進行排序,返回Top10的結果給客戶端。

    4.2.3 Query-then-Fetch存在問題和解決方案

    Query-then-Fetch存在問題分為兩方面,一個是性能問題,一個是相關性算分問題。

    • 性能問題

    性能問題主要表現為深度分頁的問題。Elasticsearch數據是分片存儲的,數據分布在多臺機器上。有這樣一個場景,如何獲取前1000個文檔?當獲取從990-1000的文檔時候,會在每個分片上面都先獲取1000個文檔,然后再由協調節點聚合所有分片的結果在排序選取前1000個文檔。

    這個過程有什么問題嗎?當然是有的,頁數越深,處理文檔越多,占用內存越多,耗時越長。所以要盡量避免深度分頁。當然,ES官方也注意了這個問題,所以通過index.max_result_window限定最多到10000條數據。當然我們也可以根據業務需要修改這個參數,這也解釋了:為什么Google搜索結果只有相關度最高的17頁結果,百度只有76頁的結果,原因之一是受限于Elasticsearch深度分頁的性能問題。

    • 相關性算分問題
      另外一個問題是相關性算分不準確問題。每個分片都基于自己分片上面的數據進行相關度計算。這會導致打分偏離的情況,特別是數據量很少的時候。相關性算分在分片之間是相互獨立。當文檔總數很少的情況下,如果主分片大于1,如果主分片數越多,相關性算分會越不準。

    • 如何解決算分不準的問題?

    1. 當數據量不大的時候,將主分片數設置為1;當數據量足夠大的時候,只要保證文檔均勻分布在各個分片上面,結果一般不會出現偏差
    2. 使用DFS Query Then Fetch
      在搜索的URL中指定參數 _search?search_type=dfs_query_then_fetch ;這樣就可以保證每個分片把各個分片的詞頻和文檔頻率進行搜集,然后進行一次相關性算分。但是這樣會耗費更多的CPU和內存資源,執行性能較低。
    • 如何避免深度分頁的問題?

    使用Search_After
    ES提供實時的下一頁文檔獲取功能,這個功能只能下一頁,不能上一頁;
    不能指定頁數,不能使用from參數;

    • 三種分頁方式對比:
    類型 場景
    From/Size 需要實時獲取頂部的部分文檔,且需要自由翻頁
    Scroll 需要全部文檔,如導出所有數據的功能
    Search_After 需要全部文檔,不需要自由翻頁

    4.3 總結

    經濟基礎決定上層建筑,ES的分片存儲決定了搜索機制。其實存儲和搜索不能分割開來看,只存儲不可搜索,這個存儲是沒有意義的;只搜索沒有存儲(數據源)是空中樓閣。

    posted @ 2021-12-28 23:18  James_Shangguan  閱讀(543)  評論(0編輯  收藏  舉報
    国产美女a做受大片观看