開發與維運

EMR Spark-SQL性能極致優化揭祕 概覽篇

引子

最近阿里雲 E-MapReduce 團隊在 TPCDS-Perf 榜單中提交了最新成績,相比第二名(其實也是 EMR 團隊於 2019 年提交的記錄),無論從性能還有性價比都取得了 2 倍+的優秀成績!詳細看 TPCDS Perf

tpcds

阿里雲 E-MapReduce 團隊,除了在產品、易用性、安全性等維度上投入了大量的研發資源和精力,打造了 EMR 這樣一個廣受好評的大數據產品;在引擎層面上也長期投入,持續深耕,目的就是要在保持開源軟件的 100% 兼容性的同時,要利用團隊的技術深度去打造產品的技術壁壘,讓客戶在使用開源軟件棧的時候,能夠獲得更多的性價比,真真切切的把雲上成本降低到極致,讓客戶能夠在上雲的過程中沒有疑慮和後顧之憂。

阿里雲 E-MapReduce 團隊在 TPCDS Perf 中取得的成績也足以驗證,團隊在 SPARK 引擎的技術深度以及技術實力,接下來會有一個系列的文章,去介紹我們 2020 年度打榜過程的一些優化點還有思考,歡迎社區裡的 spark 引擎開發者或者 spark 應用開發者可以關注我們的系列文章,也歡迎來和我們交流,最關鍵的是,歡迎多投簡歷,加入阿里雲 E-MapReduce 團隊,我們求賢若渴!!!

第三次刷榜的 Flag

從上述的 TPCDS Perf 鏈接中,我們可以看到,其實 EMR 團隊在 10TB 規模總共提交了三次成績。第三次也就是這一次打榜,背後還有一個小故事。因為在 Perf 頁面中,最終 TPCDS 關注的指標有兩個,一個是性能指標一個是性價比指標。這次項目立項的時候,我們就給自己立下了一個艱難的 Flag ,我們要在物理硬件保持不變的條件下,純靠軟件優化提升 2 倍+,這樣子性能指標和性價比指標就都能翻倍了。

與開源 Spark 版本的一些對比數據

在提交完成績後,我們用開源 Spark V2.4.3 版本進行了 TPCDS 99 Query 測試,以下是性能數據對比

Load 階段性能提升約 3 X

load

PT 階段性能提升約 6 X

pt

PS. 其中社區 Spark V2.4.3 版本中 Query 14 以及 Query 95 因為 OOM 的原因沒法跑出來,不納入計算

社區 Spark 版本運行時間大於 200S 的 Query 單獨拿出來對比

_200

PS. 這幾個 Query 最低的 Query 78 有 3X 性能提升,Query 57有接近 100 倍的性能提升。

優化點概述

優化器

  • 基於 InMemoryTable Cache 的 CTE 物化

簡單來說,就是儘量更合理的利用 InMemoryTable Cache 去減少不必要的重複計算,比如說 Query 23A/B 中的標量計算,本身是非常重的操作,並且又必須重複的計算,通過 CTE 優化的模式匹配,識別出需要重複計算且比較耗時的操作,並利用 InMemoryTable 緩存,整體減少 E2E 時間

  • 更加有效的 Filter 相關優化

    • Dynamic Partition Pruning 這個在社區最新的3.0版本才有這個功能
    • 小表廣播複用 一個具有過濾性的小表,如果可以過濾 2 個或以上的打表數據時,可以複用該小表的過濾效果 Query 64 就是一個好例子
    • BloomFilter before SMJ 在 SMJ 真正實施之前,通過前置 BloomFilter ,Join 過程的數據進一步減少,最大限度的消除 SpillDisk 的問題
  • PK/FK Constraint 優化 通過主鍵外鍵信息,對優化器提供更多的優化建議

    • RI-Join 去除 事實表與維表於主鍵外鍵上做 Join ,但是維表的列並沒有被 Project 的情況下,這次 Join 其實完全沒有必要執行
    • GroupBy Keys 去除非主鍵列 當GroupBy Keys 中同時包括主鍵列以及非主鍵列,其實非主鍵列對 GroupBy 結果已經沒有影響了,因為主鍵列已經隱含了 Unique 的信息
    • GroupBy Push Down before Join
  • Fast Decimal

基於 Table Analyze 以及運行時中的 Stat 信息,優化器可以決定把某些 Decimal 優化為 Long 或者 Int 的計算,這會有極大的提升,而 TPCDS 99 Query 裡有大量的 Decimal 計算

運行時

這次的優化裡面,還有一個很好玩的優化,就是我們引入的 Native Runtime,如果說上述的優化器優化都是一些特殊 Case 的殺手鐗,Native Runtime 就是一個廣譜大殺器,根據我們後期統計,引入 Native Runtime,可以普適性的提高 SQL Query 15~20%的 E2E 耗時,這個在TPCDS Perf 裡面也是一個很大的性能提升點。

大致的介紹一下 Native Runtime
基於開源版本的 WholeStageCodeGeneration 的框架,在原有的生成的 Java 代碼,替換成 Weld IR 來真實運行。Weld詳細參考 http://weld.stanford.edu/。在整個項目裡,Weld IR 的替換其實是非常小的一部分工作,為了Weld IR 能夠運行起來,我們還需要做以下的工作

  • Expression Weld IR CodeGen ( TPCDS 範圍內全支持)
  • Operators Weld IR CodeGen (除了 SortMergeJoin 用 C++ 實現,其他均可以用 Weld IR 代替)
  • 統一內存佈局 (OffHeap UnsafeRow => C++ & Weld Runtime)
  • Batch 化執行框架 (因為如果按照 Java 運行時,每次都是一條記錄的在生成代碼裡流轉,在 NativeRuntime 的時間裡代價太高, JNI 以及WeldRuntime 明顯不能這麼玩)
  • 其他高性能Native算子 SortMergeJoin、PartitionBy、CSV Parsing,這幾個算子目前用 Weld IR 提供的接口無法直接實現,我們通過 C++來實現這些算子的 Native 執行

結語

這個文章只是大概的介紹了這次性能優化的一些優化點,在接下來的系列文章裡,我們會針對每一個優化點細緻的展開、分析,希望對 Spark-SQL 有興趣的同學們可以多多關注,多多捧場。同時,我們也希望對 EMR 團隊有興趣的同學,積極聯繫我們,我們真的求賢若渴,海量 HC ,請有興趣者聯繫 林學維(峰七) 18518298234,也可郵箱 [email protected] !!!


阿里巴巴開源大數據技術團隊成立Apache Spark中國技術社區,定期推送精彩案例,技術專家直播,問答區近萬人Spark技術同學在線提問答疑,只為營造純粹的Spark氛圍,歡迎釘釘掃碼加入!

image.png

對開源大數據和感興趣的同學可以加小編微信(下圖二維碼,備註“進群”)進入技術交流微信群。
image.png

Apache Spark技術交流社區公眾號,微信掃一掃關注

image.png

Leave a Reply

Your email address will not be published. Required fields are marked *