Doris 最佳實踐-Compaction調優(2)

本文是 Compaction 調優系列文章的第二篇。在[前一篇文章]中咱們介紹了Compaction的一些基本概念。這裏咱們回顧下兩個重要概念:性能

  1. 每一個 BE 節點上的 Compaction 操做都是獨立進行的。Compaction 的對象是單個 BE 節點上的所有數據分片。優化

  2. Compaction 分爲 Base Compaction(BC) 和 Cumulative Compaction(CC),由Cumulative Point(CP) 劃分,根據必定策略,選擇一組rowset進行Compaction。url

本文將繼續從如下兩個方面深刻了解 Compaction.net

  1. Compaction 機制是如何挑選數據分片進行 Compaction 的。線程

  2. 對於一個數據分片,Compaction 機制是如何肯定哪些數據版本參與 Compaction 的。調試

數據分片選擇策略

Compaction 的目的是合併多個數據版本,一是避免在讀取時大量的 Merge 操做,二是避免大量的數據版本致使的隨機IO。所以,Compaction 策略的重點問題,就是如何選擇合適的 tablet,以保證節點上不會出現數據版本過多的數據分片。code

Compaction 分數對象

一個天然的想法,就是每次都選擇數據版本最多的數據分片進行 Compaction。這個策略也是 Doris 的默認策略。這個策略在大部分場景下都能很好的工做。可是考慮到一種狀況,就是版本多的分片,可能並非最頻繁訪問的分片。而 Compaction 的目的就是優化讀性能。那麼有可能某一張 「寫多讀少」 表一直在 Compaction,而另外一張 「讀多寫少」 的表不能及時的 Compaction,致使讀性能變差。blog

所以,Doris 在選擇數據分片時還引入了 「讀取頻率」 的因素。「讀取頻率」 和 「版本數量」 會根據各自的權重,綜合計算出一個 Compaction 分數,分數越高的分片,優先作 Compaction。這兩個因素的權重由如下 BE 參數控制(取值越大,權重越高): compaction_tablet_scan_frequency_factor:「讀取頻率」 的權重值,默認爲 0。 compaction_tablet_compaction_score_factor:「版本數量」 的權重,默認爲 1。  「讀取頻率」 的權重值默認爲0,即默認僅考慮 「版本數量」  這個因素。_排序

生產者與消費者

Compaction 是一個 生產者-消費者 模型。由一個生產者線程負責選擇須要作 Compaction 的數據分片,而多個消費者負責執行 Compaction 操做。 生產者線程只有一個,會按期掃描全部 tablet 來選擇合適的 compaction 對象。由於 Base Compaction 和 Cumulative Compaction 是不一樣類型的任務,所以目前的策略是每生成 9 個 CC 任務,生成一個 BC 任務。任務生成的頻率由如下兩個參數控制: cumulative_compaction_rounds_for_each_base_compaction_round:多少個CC任務後生成一個BC任務。 generate_compaction_tasks_min_interval_ms:任務生成的間隔。

這兩個參數一般狀況下不須要調整。_

生產者線程產生的任務會被提交到消費者線程池。由於 Compaction 是一個IO密集型的任務,爲了保證 Compaction 任務不會過多的佔用IO資源,Doris 限制了每一個磁盤上可以同時進行的 Compaction 任務數量,以及節點總體的任務數量,這些限制由如下參數控制: compaction_task_num_per_disk:每一個磁盤上的任務數,默認爲2。該參數必須大於等於2,以保證 BC 和 CC 任務各自至少有一個線程。 max_compaction_threads:消費者線程,即Compaction線程的總數。默認爲 10。

舉個例子,假設一個 BE 節點配置了3個數據目錄(即3塊磁盤),每一個磁盤上的任務數配置爲2,總線程數爲5。則同一時間,最多有5個 Compaction 任務在進行,而每塊磁盤上最多有2個任務在進行。而且最多有3個 BC 任務在進行,由於每塊盤上會自動預留一個線程給CC任務。

另外一方面,Compaction 任務同時也是一個內存密集型任務,由於其本質是一個多路歸併排序的過程,每一路是一個數據版本。若是一個 Compaction 任務涉及的數據版本不少,則會佔用更多的內存,若是僅限制任務數,而不考慮任務的內存開銷,則有可能致使系統內存超限。所以,Doris 在上述任務個數限制以外,還增長了一個任務配額限制:

total_permits_for_compaction_score:Compaction 任務配額,默認 10000。

每一個 Compaction 任務都有一個配額,其數值就是任務涉及的數據版本數量。假設一個任務須要合併100個版本,則其配額爲100。當正在運行的任務配額總和超過配置後,新的任務將被拒絕。

三個配置共同決定了節點所能承受的 Compaction 任務數量。
 

數據版本選擇策略

一個 Compaction 任務對應的是一個數據分片(Tablet)。消費線程拿到一個 Compaction 任務後,會根據 Compaction 的任務類型,選擇 tablet 中合適的數據版本(Rowset)進行數據合併。下面分別介紹 Base Compaction 和 Cumulative Compaction 的數據分片選擇策略。

Base Compaction

前文說過,BC 任務是增量數據和基線數據的合併任務。而且只有比 Cumulative Point(CP) 小的數據版本纔會參與 BC 任務。所以,BC 任務的數據版本選取策略比較簡單。

首先,會選取全部版本在 0 到 CP之間的 rowset。而後根據如下幾個配置參數,判斷是否啓動一個 BC 任務:

base_compaction_num_cumulative_deltas:一次 BC 任務最小版本數量限制。默認爲5。該參數主要爲了不過多 BC 任務。當數據版本數量較少時,BC 是沒有必要的。

base_compaction_interval_seconds_since_last_operation:第一個參數限制了當版本數量少時,不會進行 BC 任務。但咱們須要避免另外一種狀況,即某些 tablet 可能僅會導入少許批次的數據,所以當 Doris 發現一個 tablet 長時間沒有執行過 BC 任務時,也會觸發 BC 任務。這個參數就是控制這個時間的,默認是 86400,單位是秒。

 以上兩個參數一般狀況下不須要修改,在某些狀況下如何須要想盡快合併基線數據,能夠嘗試改小 base_compaction_num_cumulative_deltas 參數。但這個參數只會影響到 「被選中的 tablet」。而 「被選中」 的前提是這個 tablet 的數據版本數量是最多的。_

Cumulative Compaction

CC 任務只會選取版本比 CP 大的數據版本。其自己的選取策略也比較簡單,即從 CP 版本開始,依次向後選取數據版本。最終的數據版本集合由如下參數控制:

min_cumulative_compaction_num_singleton_deltas:一次 CC 任務最少的版本數量限制。這個配置是和 cumulative_size_based_compaction_lower_size_mbytes 配置同時判斷的。即若是版本數量小於閾值,而且數據量也小於閾值,則不會觸發 CC 任務。以免躲過不比較的 CC 任務。默認是5。

max_cumulative_compaction_num_singleton_deltas:一次 CC 任務最大的版本數量限制。以防止一次 CC 任務合併的版本數量過多,佔用過多資源。默認是1000。

cumulative_size_based_compaction_lower_size_mbytes:一次 CC 任務最少的數據量,和min_cumulative_compaction_num_singleton_delta 同時判斷。默認是 64,單位是 MB。

簡單來講,默認配置下,就是從 CP 版本開始日後選取 rowset。最少選5個,最多選 1000 個,而後判斷數據量是否大於閾值便可。

CC 任務還有一個重要步驟,就是在合併任務結束後,設置新的 Cumulative Point。CC 任務合併完成後,會產生一個合併後的新的數據版本,而咱們要作的就是判斷這個新的數據版是 「晉升」 到 BC 任務區,仍是依然保留在 CC 任務區。舉個例子:

假設當前 CP 是 10。有一個 CC 任務合併了 [10-13] [14-14] [15-15] 後生成了 [10-15] 這個版本。若是決定將 [10-15] 版本移動到 BC 任務區,則需修改 CP 爲 15,不然 CP 保持不變,依然爲 10。

CP 只會增長,不會減小。 如下參數決定了是否更新 CP:

cumulative_size_based_promotion_ratio:晉升比率。默認 0.05。

cumulative_size_based_promotion_min_size_mbytes:最小晉升大小,默認 64,單位 MB。

cumulative_size_based_promotion_size_mbytes:最大晉升大小,默認 1024,單位 MB。

以上參數比較難理解,這裏咱們先解釋下 「晉升」 的原則。一個 CC 任務生成的 rowset 的晉升原則,是其數據大小和基線數據的大小在 「同一量級」。這個相似 2048 小遊戲,只有相同的數字才能合併造成更大的數字。而上面三個參數,就是用於判斷一個新的rowset是否匹配基線數據的數量級。舉例說明:

在默認配置下,假設當前基線數據(即全部 CP 以前的數據版本)的數據量爲 10GB,則晉升量級爲 (10GB * 0.05)512MB。這個數值大於 64 MB 小於 1024 MB,知足條件。因此若是 CC 任務生成的新的 rowset 的大小大於 512 MB,則能夠晉升,即 CP 增長。而假設基線數據爲 50GB,則晉升量級爲(50GB * 0.05)2.5GB。這個數值大於 64 MB 也大於 1024 MB,所以晉升量級會被調整爲 1024 MB。因此若是 CC 任務生成的新的 rowset 的大小大於 1024 MB,則能夠晉升,即 CP 增長。

從上面的例子能夠看出,cumulative_size_based_promotion_ratio 用於定義 「同一量級」,0.05 即表示數據量大於基線數據的 5% 的 rowset 都有晉升的可能,而 cumulative_size_based_promotion_min_size_mbytes 和 cumulative_size_based_promotion_size_mbytes 用於保證晉升不會過於頻繁或過於嚴格。

> 這三個參數會直接影響 BC 和 CC 任務的頻率,尤爲在高頻導入場景下須要適當調整。咱們會在後續文章中舉例說明。

其餘 Compaction 參數和注意事項

還有一些參數和 Compaction 相關,在某些狀況下須要修改:

disable_auto_compaction:默認爲 false,修改成 true 則會禁止 Compaction 操做。該參數僅在一些調試狀況,或者 compaction 異常須要臨時關閉的狀況下才需使用。

Delete 災難

經過 DELETE FROM 語句執行的數據刪除操做,在 Doris 中也會生成一個數據版本用於標記刪除。這種類型的數據版本比較特殊,咱們成爲 「刪除版本」。刪除版本只能經過 Base Compaction 任務處理。所以在在遇到刪除版本時,Cumulative Point 會強制增長,將刪除版本移動到 BC 任務區。所以數據導入和刪除交替發生的場景一般會致使 Compaction 災難。好比如下版本序列:

[0-10]
[11-11] 刪除版本
[12-12]
[13-13] 刪除版本
[14-14]
[15-15] 刪除版本
[16-16]
[17-17] 刪除版本
....

在這種狀況下,CC 任務幾乎不會 被觸發(由於CC任務只能選擇一個版本,而沒法處理刪除版本),全部版本都會交給 Base Compaction 處理,致使 Compaction 進度緩慢。目前Doris還沒法很好的處理這種場景,所以須要在業務上儘可能避免。

未完待續

本文介紹了 Doris Compaction 任務的生成邏輯和執行邏輯。而且介紹了相關控制參數。接下來的文章,將經過一些具體場景來介紹調整 Compaction 參數的思路,以知足業務需求。

【往期回顧】

【Doris Weekly】2020.05.25~2021.06.08

【Doris Weekly】2021.05.10~2021.05.24

【Doris Weekly】2021.04.26~2021.05.09

【精彩文章】

Apache Doris Roadmap 2021

【Doris功能介紹】proc系統

【Doris全面解析】Doris Compaction 機制解析

相關文章
相關標籤/搜索