提升50%!Presto如何提升Hudi表查詢效能?

leesf發表於2021-05-16

分享一篇關於使用Hudi Clustering來優化Presto查詢效能的talk

talk主要分為如下幾個部分

  • 演講者背景介紹
  • Apache Hudi介紹
  • 資料湖演進和用例說明
  • Hudi Clustering介紹
  • Clustering效能和使用
  • 未來工作

該talk的演講者為Nishith Agarwal和Satish Kotha,其中Nishith Agarwal是Apache Hudi PMC成員,在Uber任職團隊Leader,Satish Kotha是Apache Hudi Committer,也在Uber任職軟體工程師。

什麼是Apache Hudi?Hudi是一個資料湖平臺,提供了一些核心功能,來構建和管理資料湖,其提供的核心能力是基於DFS攝取和管理超大規模資料集,包括:增量資料庫攝取、日誌去重、儲存管理、事務寫、更快的ETL資料管道、資料合規性約束/資料刪除、唯一鍵約束、處理延遲到達資料等等。

現在Hudi在Uber內部的生產應用規模已經達到了一個新臺階,資料總規模超過了250PB8000+張表,每天攝取5000億條資料。

基於Hudi的資料湖架構演進如下。通過批、流方式將資料以Hudi格式寫入資料湖中,而Hudi提供的事務、主鍵索引以及二級索引等能力均可加速資料的寫入,資料寫入Hudi後,資料檔案的組織會以列存(基礎檔案)和行存(增量日誌檔案)方式儲存,同時藉助Hudi提供的各種表服務,如

  • Cleaning:清理服務,用來清理過期版本的檔案;
  • Clustering:資料聚簇,將檔案按照某些列進行聚簇,以重新佈局,達到優化查詢效能的效果;
  • Replication:複製服務,將資料跨地域進行復制;
  • Archiving:歸檔服務,歸檔commit後設資料,避免後設資料不斷膨脹;
  • Compaction:壓縮服務,將基礎檔案和增量日誌檔案進行合併,生成新版本列存檔案,提升查詢效能;

而對於查詢引擎而言,Hudi可以將其表資訊註冊至Metastore中,查詢引擎如Presto即可與Metastore互動獲取表的元資訊並查詢表資料。

由於Uber內部大規模使用了Presto查詢引擎,下面重點介紹Hudi和PrestoDB的整合細節。

現階段PrestoDB支援查詢兩種Hudi表型別:針對讀友好的COPY_ON_WRITE型別(存列存格式)和寫友好的MERGE_ON_READ型別(列存+行存格式);支援已經相對完備。

介紹完Hudi和PrestoDB整合現狀後,來看看使用案例和場景,Hudi與Presto的整合是如何降低成本和提高查詢效能的

大資料場景下,對於寫入(攝取)和查詢引擎的優化思路通常不同,可以從兩個維度進行對比,如資料位置和檔案大小,對於寫入而言,資料位置一般決定於資料到達時間,檔案大小則更傾向於小檔案(小檔案可減小寫入延遲);而對於查詢而言,資料位置會更傾向於查詢的資料在同一位置,檔案大小則更傾向於大檔案,小檔案帶來額外的開銷。

有沒有一種方式可以兼顧寫入和查詢呢,答案是肯定的,引入Clustering,對於Clustering,說明如下。

  • Clustering是Hudi提供的一種改變資料佈局的框架

    • 提供了可插拔的策略來重組資料;
    • 開源版本提供了一些開箱即用的策略;
  • Clustering還提供了非常靈活的配置

    • 可以單獨挑出部分分割槽進行資料重組;
    • 不同分割槽可使用不同方式處理;
    • 支援不同粒度的資料重組:全域性、本地、自定義方式;
  • Clustering提供了快照隔離和時間旅行

    • 與Hudi的Rollback和Restore相容;
    • 更新Hudi後設資料和索引;
  • Clustering還支援多版本併發控制

    • Clustering可與攝取併發執行;
    • Clustering和其他Hudi表服務如Compaction可併發執行;

下面來看一個使用Clustering來提高查詢效能的案例,使用的的SQL如下select b,c from t where a < 10000 and b <= 50000;列舉了三種情況。

  1. 未下推但未進行Clustering,掃描的檔案數很多;
  2. 下推但未進行Clustering,掃描及處理的檔案數也很多;
  3. 下推並且進行Clustering,掃描及處理的資料量變得較少;

接著看看未進行Clustering之前的查詢計劃,總共掃描輸入了2900W+條資料,最後過濾輸出了140W+條資料,過濾掉資料的比例達95.17%;

經過Clustering之後的執行計劃,總共掃描輸入了371W+條資料,最後過濾輸出了140W+條資料;相比未進行Clustering,掃描的資料量從2900W+減少到了371W+;可見Clustering的效果提升非常顯著。

對於Clustering帶來的查詢效能優化如下

  • 未進行Clustering,掃描輸入資料量大小為2290MB,條數為2900W+,CPU耗時27.56S
  • 進行Clustering後,掃描輸入資料量大小為182MB,條數為300W+,CPU耗時6.93S

掃描資料量減少了10倍,CPU消耗減少了4倍,查詢延遲降低了50%+

基於Clustering可提供強大的的效能優化,在Uber內部也已經在生產上使用了Clustering,利用了Clustering可以和攝入併發執行的特性。生產中使用了兩條Pipeline,一條攝入Pipeline,一條Clustering Pipeline,這樣攝入Pipeline可以不斷產生新的小檔案,而通過非同步的Clustering Pipeline將小檔案合併,從而對查詢端暴露大檔案,避免查詢端受寫入端產生太多小檔案問題影響。

關於通過Clustering加速Presto的查詢效能上面已經講述完了,當然對於Clustering還有後續的規劃:落地更多的用例;將Clustering作為一個更輕量級的服務呼叫;分優先順序及分層(如多個Job跨表重組資料佈局);根據歷史查詢效能優化新的資料佈局;在Presto中新增二級索引進一步減少查詢時間;提升重寫效能(如對於某些策略降低重寫資料開銷);

好了,今天的分享就這裡,歡迎關注Hudi郵件列表dev@hudi.apache.org 以及 star & fork https://github.com/apache/hudi

相關文章