ES聚合底層機制-bucket深的話采用廣度優先更好,而如果是年度統計還是深度優先好


見原文,僅僅摘錄部分:https://www.elastic.co/guide/cn/elasticsearch/guide/current/_preventing_combinatorial_explosions.html

。。。

圖 42. Build full depth tree

Build full depth tree

用真實點的數據,設想平均每部影片有 10 名演員,每部影片就會生成 102 == 100 個桶。如果總共有 20,000 部影片,粗率計算就會生成 2,000,000 個桶。

現在,記住,聚合只是簡單的希望得到前十位演員和與他們聯合出演者,總共 50 條數據。為了得到最終的結果,我們創建了一個有 2,000,000 桶的樹,然后對其排序,取 top10。 圖 圖 43 “Sort tree” 和圖 圖 44 “Prune tree” 對這個過程進行了闡述。

圖 43. Sort tree

Sort tree

圖 44. Prune tree

Prune tree

這時我們一定非常抓狂,在 2 萬條數據下執行任何聚合查詢都是毫無壓力的。如果我們有 2 億文檔,想要得到前 100 位演員以及與他們合作最多的 20 位演員,作為查詢的最終結果會出現什么情況呢?

可以推測聚合出來的分組數非常大,會使這種策略難以維持。世界上並不存在足夠的內存來支持這種不受控制的聚合查詢。

深度優先與廣度優先(Depth-First Versus Breadth-First)

Elasticsearch 允許我們改變聚合的 集合模式 ,就是為了應對這種狀況。 我們之前展示的策略叫做 深度優先 ,它是默認設置, 先構建完整的樹,然后修剪無用節點。 深度優先 的方式對於大多數聚合都能正常工作,但對於如我們演員和聯合演員這樣例子的情形就不太適用。

為了應對這些特殊的應用場景,我們應該使用另一種集合策略叫做 廣度優先 。這種策略的工作方式有些不同,它先執行第一層聚合,  繼續下一層聚合之前會先做修剪。 圖 圖 45 “Build first level” 和圖 圖 47 “Prune first level” 對這個過程進行了闡述。

在我們的示例中, actors 聚合會首先執行,在這個時候,我們的樹只有一層,但我們已經知道了前 10 位的演員!這就沒有必要保留其他的演員信息,因為它們無論如何都不會出現在前十位中。

圖 45. Build first level

Build first level

圖 46. Sort first level

Sort first level

圖 47. Prune first level

Prune first level

因為我們已經知道了前十名演員,我們可以安全的修剪其他節點。修剪后,下一層是基於 它的 執行模式讀入的,重復執行這個過程直到聚合完成,如圖 圖 48 “Populate full depth for remaining nodes” 所示。 這種場景下,廣度優先可以大幅度節省內存。

圖 48. Populate full depth for remaining nodes

Step 4: populate full depth for remaining nodes

要使用廣度優先,只需簡單 的通過參數 collect 開啟:

{
  "aggs" : {
    "actors" : {
      "terms" : {
         "field" :        "actors",
         "size" :         10,
         "collect_mode" : "breadth_first" 
      },
      。。。
    }
  }
}

廣度優先僅僅適用於每個組的聚合數量遠遠小於當前總組數的情況下,因為廣度優先會在內存中緩存裁剪后的僅僅需要緩存的每個組的所有數據,以便於它的子聚合分組查詢可以復用上級聚合的數據。

廣度優先的內存使用情況與裁剪后的緩存分組數據量是成線性的。對於很多聚合來說,每個桶內的文檔數量是相當大的。 想象一種按月分組的直方圖,總組數肯定是固定的,因為每年只有12個月,這個時候每個月下的數據量可能非常大。這使廣度優先不是一個好的選擇,這也是為什么深度優先作為默認策略的原因。

針對上面演員的例子,如果數據量越大,那么默認的使用深度優先的聚合模式生成的總分組數就會非常多,但是預估二級的聚合字段分組后的數據量相比總的分組數會小很多所以這種情況下使用廣度優先的模式能大大節省內存,從而通過優化聚合模式來大大提高了在某些特定場景下聚合查詢的成功率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM