新一代資料架構的效能與成本平衡之道

陶然陶然發表於2024-03-04

  Alluxio 大致可分為兩個部分:Alluxio Service 和 Alluxio Local Cache。Alluxio Local Cache 為計算儲存分離的計算環節實現了資料本地化,透過這種方式來加速查詢,同時減少對 underline 的 FS 的 request 和對應的資料的出口,從而提高效能並節省成本。

  NewsBreak 是美國的一家新聞資訊企業。文章將透過該公司案例,介紹Alluxio Local Cache for Presto 的應用。  

   01 NewsBreak 的架構

  首先來介紹一下 NewsBreak 的整體架構。  

  從下往上看,有很多不同的資料來源,透過 DIP(Data Engine Pipeline) 的 model 做到資料入湖和入倉。引入了 Schema Registry 來管理大部分的 schema,還有 Hudi 這種流行的 open table format,以及其它如 Mongo、Scylla、MySQL 等不同的 transactional Database。透過 Managed ETL 層,經過 Airflow,load 到 Data & Service。Data & Service 分兩大塊:偏 raw data 的資料湖和偏 ETL 的數倉。Query engine 是建構在 Presto 之上的,提供 ad-hoc 查詢和 BI 分析。同時,對敏感資料,利用 SnowFlake 做更精細化的管理,尤其是對 PRI 的資訊。

  在此之上構建了不同的資料產品,如內部的 Self-service ETL,偏向產品、工程、數分的 Log Query Service,幫助使用者獲得公司的原始資料以進行各種分析,還有面向運營或者 CXO 的不同的 data products 和 BI 工具,例如 AB 系統等。

   02 Presto at NewBreak

  今天主要介紹的是 Data & Service 部分。在不同的 log 之上,透過 Presto 來做計算、儲存和查詢。我們的資料比較雜也比較多,所以方案需要能夠加速 query 的整體效能,同時減少 S3 的 cost。

  S3 儲存的 cost 跟 query 沒有太大關係,最大部分的查詢 cost 是按照 request 的請求和資料的出口收費。

  1. Presto 在 NewsBreak 的使用方式和架構  

  Presto 是典型的計算儲存分離,我們使用了其很多功能,比如不同的 connecter,利用聯邦查詢,連線 Scylla、Mongo、Iceberg、Hive、MySQL、Hudi 等。底下的儲存,包括以 S3 為主的 Hive、Iceberg,還有比較偏 OLTP 的 MySQL、Scylla。

  上面是一些比較常見的產品,如 Feast 支援 feature store,還有自建的 CMS以及 Mode 等第三方 SaaS 系統。

  透過 Presto 的 CTAS 對數分或者偏內部的開發,對資料迴流處理,再匯入資料庫。

  另外,引入了 Presto 的一個外掛 event stream。它是一個 listener,將所有的 SQL 結果、執行狀態等發給 Kafka stream,透過 Hudi 落回到儲存。

  底部儲存以 S3 加上一些 OLTP 的方式為主。

  我們期望在整個資料生命週期內得到效能加速,資料無論是透過 CTS 產生,還是透過傳統 ETL 產生,能夠自動支援 Cache。

  2. Cache Considerations

  這裡列出了 Cache 相關的主要考慮點:  

  首先,需要支援 Presto On S3。Alluxio Local Cache 很早就有,在Facebook 和 Uber 都有實踐,但支援的是 Presto on HDFS,On S3 是在今年 3 月份剛剛釋出的 2.2.9.3 版本中才支援。

  第二,希望能最小化對現有系統的影響。

  第三,提速 query,同時透過減少 S3 request 來減少 S3 的 cost。

  第四,由於康威定律,我們的架構比較複雜,因此希望支援 multiple 的 Hive metastores。

  第五,cache 的 storage 是非常小的,只有整體的 1% 左右,所以希望支援 cache filter,來指定哪些表或哪些形式的內容需要被 cache,從而提高整體的命中率。

  第六,支援 Hudi,或有版本的檔案。

  最後,希望有詳細的 monitor 可以監控和衡量整個系統的效果。  

  經過評估,我們借鑑了 Uber 去年的類似實驗。在 Uber 的架構中,Alluxio 部分整體向外提供了一個 HDFS 的 API,在訪問遠端檔案的時候會判斷是否有 cache 能被 hit,如果有,就直接走 local disk,如果沒有就到外部找 external storage。

  這樣做的優點在於其強一致性,如果 local disk 沒有到遠端去找,或者遠端的檔案已經被修改,被改的資訊會傳遞到整個系統當中,會認為這個檔案是不命中的。

  在此之上我們做了幾點簡單的改動:

  首先,支援了 S3。這是透過修改 Presto 0.275,再結合最新的 release 0.292 的 Alluxio code 實現的。

  第二,將 cache filter 從 global 的粒度降低到 catalog level,因為是由於公司架構原因導致的,因此要支援 multiple catalog。

  第三,在最下面為整個 Alluxio Cluster 配置了一個 shadow cache 來衡量整體的效能效果。

   03 ALC4PS3 at NewsBreak  

  我們用實體資料進行了測試。上圖展示了 S3 的 prefix 效果:

  可以看到,在某一天有一個非常大的 burst,從平時不到幾十 million request,burst 到 900 million request。透過 SQL 方式訪問資料容易產生重複的訪問資料,也就帶來了更多的 cost,我們希望儘量避免這種情況。

  透過與 Alluxio 的整合可以基本上把資料量控制在每天 10 million 以下。因此得出 Alluxio 符合我們的場景需求,一方面可以降低整體的平均 access 的 request,同時還可以砍掉異常的峰值。

  1. Cache filters  

  接下來的問題是,如何從選中的幾個 bucket 或幾個 prefix,scale 到整個公司的十幾個 PB 的資料量之上。這裡就用到了 cache filter 機制。

  Uber 提供了比較複雜的機制,可以根據 database、namespace 上的 table partition 來進行配置。但這不適用於我們的場景,因為我們是資料湖+數倉的複雜模型,使用者有比較多的 ad-hoc 需求,因此我們需要更通用的方法。

  最終選擇了最原始的、對 cache 最基本的需求,採用了 mtime 這種 genernal 的方式來做處理,透過 monitor 的方式來看最終的效果。整體機制為,對當前的時間給一個 lookback window,透過 window 的資料才放到 cache 上。

  Alluxio Local Cache 提供了 cache filter 的 overwrite 的機制。這裡簡單定義一個 Latest21DayCacheFilter,可以得到每一個檔案的 modified time,跟 window time 做對比。

  另外,我們發現小檔案比較多,而小檔案會浪費 local cache 的 disk,所以增加了進一步的過濾機制,檔案大小要大於 patch size,預設 patch size 是 2MB。

  2. Multi HMS  

  第二個場景是支援 Multiple Hive Meta Store。由於公司組織架構複雜,業務繁多,造成了比較多的 Hive metastore,包括 Glue、Iceberg 等,各業務線處理自己的資料時需要跨 catalog 做 Spark 或 Flink 的處理,需要把後設資料重新在 remote 註冊一遍。

  Alluxio 假設自己是 Singleton,在初始化 manager、monitor 的時候是 singleton 的,但在 filter 級別支援 per catalog 的配置,所以利用這一特性,在每個 catalog 上面都設定一模一樣的配置,除了 cache filter 之外。這樣做的好處是,由於檔案是共享的,因此只要在任何 catalog 被 cache 後,其它查詢也會得到相似的資料。

   04 Presto event stream

  1. Query level monitor

  以上介紹了整體的機制。接下來看是如何對效果進行評估。  

  Alluxio 原有的 monitor 資料是比較粗的,只有 cluster 級別的最基本的資訊。我們引入了塊 level 的 monitor,利用了 Presto event stream 元件。它借鑑了 Trino event stream 的基本想法,Presto 產生的 query event 都會發到 Kafka 裡,透過 Hudi 把所有資料重新引入到資料平臺,再透過 Presto 查詢,中間透過簡單的 Schema 管理起來。

  有了這個元件,在 Presto cluster上面就可以簡單配置,加一個 event listener,指定名字到 Kafka 中簡單配置即可。

  需要強調的是,要把執行時的 detail 資訊暴露出來,因為 Alluxio 的 cache 命中率、命中 cache size 等都會透過這個配置 enable。

  2. Query/storage coverage and hit rate

  有了 detail 的 query level 的 monitor 後,就可以拿到很多的 metrics。這裡列出了一些常用的 metrics:  

  第一個是塊級別的命中率,最開始時是 70~80%,後來加上簡單的過濾條件,比如只 cache 最近幾十天的資料、只 cache 檔案大小大於某個 size,可以降到大約 20~30%。但整體的 storage 的 coverage 還是比較高的,在 70~80% 左右。

  第二個是每個 query 涉及到的 storage 有多少命中率。

  第三個是 storage 中多少是從 Alluxio cache中讀取,多少是從 underline remote 中讀取。

  3. Metrics  

  在 2 clusters、1600 核,針對 P95,整體從 9 秒減少到了 8 秒。每月 scan 的 storage 約 6PB,其中大約有 3PB 從 Alluxio 讀取,後續有可能會更高。

   05 ALC4PS4 Next  

  效能提升其實並不是特別明顯,但我們目的是提升效能的同時減少 cost,在過程中我們也發現了很多問題,比如 SQL 命中率大約只有 30%,系統中還有很多小檔案,甚至很多檔案不是列存。因此要進一步提升效能,還需要做一些傳統的 data governance,如列存、壓縮、處理小檔案等等。Local cache filter 還需要 fine tuning,比如,現在storage 比較小,每個 worker 上只配置大約500GB。Cache filter 也要繼續調優。後續也考慮將用在 Presto 的這種機制擴充套件到 Flink、Spark、Hudi、Iceberg 等。

來自 “ DataFunTalk ”, 原文作者:關立勝;原文連結:https://server.it168.com/a2024/0304/6841/000006841278.shtml,如有侵權,請聯絡管理員刪除。

相關文章