金山雲團隊分享 | 5000字讀懂Presto如何與Alluxio搭配

語言: CN / TW / HK

導語

  • 金山雲-企業雲團隊(趙侃、李金輝)在互動查詢場景下對Presto與Alluxio相結合進行了一系列測試,並總結了一些Presto搭配Alluxio使用的建議。
  • 本次測試未使用物件儲存,計算引擎與儲存間的網路延時也比較低。如果儲存IO耗時和網路耗時較大時,Alluxio加速收益應會更明顯。

測試目的

  • 驗證影響Alluxio加速收益的各種因素
  • 記錄Alluxio在適宜條件下的加速表現
  • 總結Alluxio的使用建議

測試環境

叢集部署架構圖

  • 計算引擎使用Presto,資料來源為Hive,Alluxio作為快取。
  • 共搭建2個叢集:Presto+Alluxio叢集,Hadoop叢集。

Presto+Alluxio叢集配置

  • 機器:4臺 linux虛擬機器
  • cpu/記憶體:32核 64G
  • 磁碟:60GB SSD + 200GB SSD
  • 網路:萬兆頻寬
  • 關鍵配置:

Hadoop叢集配置

  • 機器:5臺 linux虛擬機器
  • cpu/記憶體:16核 32G
  • 磁碟:60GB HDD + 1200GB HDD
  • 網路:萬兆頻寬

測試用資料集列表

  • 測試使用的資料是tpc-ds標準資料集。
  • 因測試需要,我們匯入了多份不同大小的資料集。每份資料集裡的表結構是完全相同的,區別是表中的資料量不同,部分表之間的分割槽也不相同。

Alluxio強悍的加速表現

首先我們來看看,當提供了相對適宜的條件,Alluxio的具體加速表現。

  • 以下查詢的資料集是tpc-ds資料集tpcds_bin_partitioned_orc_100,整個資料集的大小為23.4G。
  • 以下執行的SQL是在tpc-ds提供的sql中選取7條滿足條件的,實驗中對7條SQL各反覆查詢10次,記錄每次查詢的耗時。
  • 每次查詢之間間隔8~10秒,給Alluxio的非同步快取一定時間,儘量提高下一次查詢的命中率。

實驗結果展示

• 重點說明

○ 耗時的單位為ms。
○ “avg”列的值是第2次查詢至第10次查詢耗時的平均數。
○“first”列的值就是第1次查詢的耗時。“加速收益”列的計算方式是:(first - avg) / first。

實驗結果分析

  • 第一次查詢時,由於資料還沒有被快取,耗時是最高的,往後資料逐漸被非同步快取入Alluxio,查詢耗時逐漸遞減,等全量資料進入Alluxio快取,此時加速收益達到最高,查詢耗時最低且停止遞減。
  • 我們可以看到相較於耗時最大的first,avg的值有大幅度的降低,耗時僅有原來的20%~30%。從“加速收益”列來看可以更量化的評估加速收益。
  • 下面我們驗證一下關於影響Alluxio加速收益的具體因素。在下面的實驗中,可以看到Alluxio在更適宜的環境下,甚至可以把查詢耗時減少到原來的5%。

影響加速收益的重要因素

  • 根據測試的結果,結合官方文件描述,總結出幾點因素會對Alluxio加速收益產生影響。下面我們就來看看這些因素
  • 重點說明:這裡說的Alluxio加速收益,指的是查詢的耗時在加速後比加速前快了多少,並不單單是指IO那部分的耗時快了多少。更具象化的描述,它指的是單個查詢在加速後的耗時比加速前降低了百分之多少。

因素一:查詢的Hive表的底層資料檔案的大小和加速收益正相關

1. 結論:查詢的資料檔案在小於約2MB時,檔案越小,Alluxio加速收益越低。

因檔案過小,所以每個檔案是一個split。Presto解析每個split建立driver,排程driver執行,這段耗時是不能被加速的,而operator掃描的資料太小,那麼磁碟IO的耗時在整個耗時中佔比就會較低,Alluxio對查詢的加速收益就會降低。

在本次測試所使用的環境中,每個資料檔案小於約50KB時,在查詢的整體耗時上,加速收益會比較低。

資料檔案大於約2MB時,檔案大小對加速收益的影響相對不那麼明顯。

這個2MB和50KB只是在本環境中觀察到的一個大概閾值,在不同環境中可能會有不同的表現。

2. 驗證:用一條簡單的SQL進行測試

【a. 實驗用例說明】

測試方法採用相同的SQL去查詢5個tpcds資料集中的同名表,保證SQL複雜度相同、表結構相同,分割槽表的分割槽數相同,僅僅是資料檔案大小不同。

這裡用一條簡單的SQL語句反覆多次查詢,記錄每次查詢的耗時。

select * from web_sales where ws_wholesale_cost=1。where條件欄位ws_wholesale_cost並不是分割槽欄位,所以會觸發全表掃描。

在presto看到僅被劃分出2個stage

本次實驗查詢的web_sales表在5個數據集中的相關元資料

○ 對於分割槽表,由於資料檔案較小,每個檔案就是一個split。
○ 為了有更清晰的對比,也引入了非分割槽表的查詢,非分割槽表的資料檔案數較少,每個資料檔案大小均在100MB以上,Presto會按照HDFS檔案塊大小來劃分split,每個split中的資料大概是28~38MB左右。

【b. 實驗結果展示】

【c. 實驗結果分析】

○ 當每個split的資料小於2MB時,加速收益會明顯低一些。資料越小,加速收益越低,split的資料達到幾十KB時,加速就很微弱了。
○ 我們看到當每個split的資料達到2MB時,加速收益和30MB的區別不大,說明資料大於2MB後,資料大小對加速的影響就不大了。
○ 下面我們換一條SQL、換一張表再驗證一次,可以看到結論是一樣的。

3. 驗證:用tpcds中的Query55進行測試

【a. 實驗用例說明】

query55中包含聚合、排序、大小表join,複雜度一般,presto會為其劃分7個stage

query55查詢的事實表為store_sales。

store_sales表的相關元資料

【b.實驗結果展示】

 

【c. 實驗結果分析】

○ 結論跟上一次實驗一致,當split的資料只有百來K的時候,加速收益比較微弱,僅20%。
○ split的資料大於2M以上,資料大小對加速收益的影響較小。

因素二:執行的SQL語句的複雜度和加速收益負相關

1. 結論:SQL語句越複雜,Alluxio的加速收益越低

SQL語句越複雜,計算的耗時就會越長,在整體耗時中,IO耗時的佔比就會下降,而Alluxio只能加速IO的耗時,所以在整體耗時的加速上,收益會降低。

在評估SQL複雜度時,我們可以參考Presto在執行SQL時劃分的Stage的數量,來量化SQL的複雜度,Stage越多則說明SQL相對複雜些。當然也可以肉眼大致判斷下複雜度:

a. 簡單:分組聚合、排序
b. 複雜:大小表join、select語句巢狀
c. 特別複雜:大表join大表、更多的表參與join、多個select語句巢狀

2. 驗證:針對store_sales事實表進行測試

a. 實驗用例說明】

測試方法:採用選取tpc-ds中查詢同一張事實表的不同query,去查詢同一個資料集。保證表結構相同、檔案數相同、檔案大小相同、分割槽數相同,僅僅SQL不同。

query中除了事實表還會查詢維度表,不同query涉及的維度表可能不同,但是維度表的資料量極小(比事實表小1000倍至1w倍),且都不是分割槽表,所以在這裡我們可以忽略維度表不同所帶來的影響。

測試時對同一條sql反覆執行,記錄每次執行的耗時。每次查詢之間間隔8~10秒。

以下測試資料集選擇tpcds_bin_partitioned_orc_100,事實表選擇store_sales。

store_sales表的相關元資料:

測試SQL採用如下6條

【b. 實驗結果展示】

【c. 實驗結果分析】

○ 我們看到最簡單的SQL,加速收益非常高。
○ 面對一般複雜的SQL,Alluxio也依然很好的加速收益。
○ 整體來看,Stage數量小於15時,Alluxio都有不錯的表現。

3. 驗證:當查詢的資料檔案較小且SQL語句很複雜

【a. 實驗用例說明】

我們這裡再補充做一個實驗,當查詢的資料檔案較小,而SQL語句又複雜的話,加速收益如何呢。

本實驗SQL語句使用query88,分別查詢2套資料集。

表的相關元資料

【b. 實驗結果展示】

【c. 實驗結果分析】

我們看到,在這種很不適宜Alluxio的條件下,加速收益會比較低。

因素三:查詢SQL語句返回的資料量的大小和加速收益負相關

1. 結論:查詢返回的資料量越大,Alluxio的加速收益越低

Presto最後會使用一個Driver來reduce所有Driver的計算結果,資料量越大,reduce的耗時越長,這裡主要包括計算的耗時和網路IO耗時。如果是掃表時過濾的資料就很少,那麼參與計算的資料量就會增加,增加了計算耗時,那麼就降低了IO耗時在整個查詢耗時中的佔比

2. 驗證:

【a. 實驗用例說明】

我們使用2條簡單的SQL查詢同一張表,用where條件和limit控制一下返回的資料量

使用tpcds_bin_partitioned_orc_100中的web_sales表。

表的相關元資料

○ SQL1:select * from web_sales where ws_wholesale_cost=1- 返回的資料條數為7.35K,資料大小為2.12MB。
○ SQL2:select * from web_sales limit 2000000- 返回的資料條數為2M,資料大小為558.87MB。

【b. 實驗結果展示】

【c. 實驗結果分析】

○ 在返回少量資料時,查詢的整體耗時很短,加速收益非常好
○ 返回大量資料時,查詢的整體耗時大幅增加,加速收益不太好

因素四:影響加速收益的硬體環境因素

Alluxio的加速收益還受以下硬體因素影響:

• Alluxio快取讀寫速度
• UFS磁碟讀寫速度
• 網路頻寬

這部分結論就不做驗證了。

宣告:所有測試均在較為理想的環境下進行

  • 上述所有測試,都沒有考慮同時掃描的資料檔案大小超過了Alluxio快取的情況,在查詢時,資料可以被全量快取,達到全部本地命中的效果。所以我們看到每次查詢耗時在經過2到4次查詢的遞減後,就會在一個很小的範圍內波動,總的來說耗時比較穩定。
  • 在生產環境可能會面臨很多查詢並行執行,需要掃描大量資料,資料檔案的總大小會超過Alluxio快取的大小。那麼就會觸發資料的淘汰,每個查詢都不可能快取所有需要的資料,所以查詢的耗時永遠不會穩定,而是在一個較大的區間範圍去波動。
  • 本次測試沒有涵蓋資料檔案儲存在物件儲存的場景。如果使用物件儲存S3,預計會有更顯著的加速效果。

關於Alluxio應用於生產業務的使用、優化建議

• Alluxio並不能在所有場景下都達到良好的加速收益,要發揮Alluxio更大的價值,我們總結了一些使用、優化建議。

建議一:使用Shadow Cache檢測Alluxio與生產上業務的貼合性

生產上引入Alluxio是否能帶來加速收益,應該設定多大的快取容量能達到最大收益,需要有評估和檢測。

Alluxio提供了一個Shadow Cache功能,可以使用布隆過濾器記錄計算引擎訪問過哪些資料以及總資料量的大小。每次計算引擎訪問資料,都統計一次是否命中shadow cache中的資料。結合shadow cache和Alluxio的命中率可以檢測業務是否適合使用快取。

○ 業務場景不適合使用快取:統計shadow cache的命中率,如果較低,則說明業務場景中極少會訪問重複資料,那麼是不適合使用快取的。
○ Alluxio快取需要加大空間:如果shadow cache的命中率高,但Alluxio快取的命中率低,說明業務場景適合使用快取,但是當前Alluxio快取的空間過小了。因為在資料檔案被重複訪問時,之前存入Alluxio的快取,已經因為快取滿了而被淘汰了,所以重複訪問時將得不到任何加速。那麼此時加大Alluxio快取空間會取得更好的加速收益。
○ Alluxio快取的收益已經達到較佳值:如果shadow cache命中率高,Alluxio快取的命中率也高,則說明目前Alluxio快取帶給業務的加速收益已經達到良好水平,再加大Alluxio快取空間意義不大。

使用Shadow Cache,對使用Alluxio在優化上有一個更直觀的方向指導。

建議二:預先載入熱資料

Alluxio的加速需要先把資料load到快取中,這需要等待使用者先訪問一次資料,也就是說第一次查詢是沒有加速收益的。那麼對於熱點資料,我們可以在使用者訪問前就預先load到快取中。對於長時間不會改變且熱點的資料,還可以把資料pin在快取中,不會被淘汰。

建議三:動態判斷查詢是否需要被加速

有的查詢被Alluxio快取可以帶來很好的加速收益,有的則不行。我們可以在查詢時動態的判斷是否需要讓Alluxio快取。在查詢時,解析SQL語句得到查詢的表,先去拿到表的元資料,判斷資料檔案大小,同時也結合SQL的大致複雜度,再決定查詢是否要走Alluxio。

建議四:設定單層快取,使用SSD作為儲存介質

Alluxio官方建議不要設定多層快取,資料在多層快取中的下沉和上浮可能會對效能有些影響。出於成本和效能的綜合考慮,單層快取的儲存介質建議使用SSD。

建議五:合併小檔案

小檔案過多會影響Alluxio的加速收益,可以對熱點資料,在查詢前先執行小檔案的合併。Alluxio提供了這個功能,可以對Hive表同一分割槽下的所有檔案進行合併,合併後的檔案不會覆蓋原來的小檔案,也不會更改Hive的元資料。當Alluxio要快取這些小檔案時,會直接快取合併後的檔案,大幅提升讀取速度。

想要獲取更多有趣有料的【活動資訊】【技術文章】【大咖觀點】,請點選關注 [Alluxio 智庫]