?Alluxio SDK 在 Presto/Trino 中的應(yīng)用
一、Alluxio Edge 產(chǎn)生的背景
首先來(lái)介紹一下現(xiàn)代數(shù)據(jù)技術(shù)棧的演變歷程。
10 年前,Hadoop 擁有一個(gè)緊密耦合的 MapReduce 和 HDFS 架構(gòu)。HDFS 在本地部署,計(jì)算資源多由 YARN 管理。今天,技術(shù)棧的豐富帶給我們更多的選擇,并讓不同的架構(gòu)具備了可能性。我們現(xiàn)在看到了越來(lái)越多的計(jì)算與存儲(chǔ)的解耦和分離;有了云和數(shù)據(jù)湖,而且越來(lái)越多的數(shù)據(jù)湖放在了云上;資源管理和編排則由 Kubernetes+ 容器來(lái)承擔(dān)。所有這些技術(shù)的改變讓我們的系統(tǒng)有了更好的彈性、更高的可擴(kuò)展性、更便捷的管理。然而,這些好處也伴隨著一個(gè)問(wèn)題,即數(shù)據(jù)本地性的喪失。數(shù)據(jù)本地性就是計(jì)算引擎在本地(比如本節(jié)點(diǎn)、本集群)就可以訪問(wèn)數(shù)據(jù)的特性,其好處是高效的數(shù)據(jù)訪問(wèn)性能和低廉的數(shù)據(jù)訪問(wèn)開(kāi)銷(xiāo)。
在失去數(shù)據(jù)本地性以后,我們發(fā)現(xiàn),數(shù)據(jù)的訪問(wèn)性能變得緩慢且不穩(wěn)定,用戶(hù)的查詢(xún)運(yùn)行時(shí)間變得更長(zhǎng),因此需要更長(zhǎng)的時(shí)間來(lái)獲取業(yè)務(wù)洞察。不僅如此,查詢(xún)運(yùn)行的時(shí)間越長(zhǎng),云上集群消耗的時(shí)間和資源就越多,導(dǎo)致集群成本增加。很多企業(yè)想要加快任務(wù)的執(zhí)行速度,一部分原因是想讓業(yè)務(wù)分析變得更加敏捷,另一部分原因是想節(jié)省計(jì)算資源的開(kāi)銷(xiāo)。
在使用云上對(duì)象存儲(chǔ)的情況下,由于數(shù)據(jù)量的快速增長(zhǎng),我們發(fā)現(xiàn)數(shù)據(jù)的出口開(kāi)銷(xiāo)(也就是 egress cost)變成企業(yè)使用云成本的重要組成部分。盡管云上的對(duì)象存儲(chǔ)的單位字節(jié)的存儲(chǔ)成本很低,但數(shù)據(jù)就像被“綁架”了,當(dāng)你想要從云上訪問(wèn)數(shù)據(jù)時(shí),會(huì)產(chǎn)生各種額外開(kāi)銷(xiāo),例如 API 調(diào)用開(kāi)銷(xiāo)和數(shù)據(jù)傳輸開(kāi)銷(xiāo)。如果這些開(kāi)銷(xiāo)發(fā)生在同一批數(shù)據(jù)上(比如熱數(shù)據(jù)的反復(fù)讀?。瑫?huì)帶來(lái)巨大的成本。因此,有些用戶(hù)會(huì)選擇把要分析的數(shù)據(jù)一次性拷貝到計(jì)算集群附近的存儲(chǔ)系統(tǒng)中,然后進(jìn)行分析。這個(gè)方案需要人們建設(shè)和維護(hù)多個(gè)存儲(chǔ)集群,并打造和維護(hù)數(shù)據(jù)拷貝任務(wù)的 pipeline。此外,數(shù)據(jù)的改動(dòng)、數(shù)據(jù)生產(chǎn)和消費(fèi)的變化等都容易引起拷貝錯(cuò)誤,需要排查和解決。
Alluxio System 作為分布式的數(shù)據(jù)編排系統(tǒng),具有緩存功能,能夠解決上面的痛點(diǎn)。同時(shí),我們?cè)谒伎?,如何把緩存這個(gè)最基本、最常用的功能做得更極致化。計(jì)算機(jī)領(lǐng)域有句著名的話(huà),“在計(jì)算機(jī)科學(xué)中只有兩件難事:緩存失效和命名”。于是,就誕生了 Alluxio Edge。
二、Alluxio Edge 概要介紹
Alluxio 是一個(gè)滿(mǎn)足不同用戶(hù)需求的數(shù)據(jù)平臺(tái)。它包括兩大類(lèi)產(chǎn)品線(xiàn),分別為Alluxio System 和 Alluxio Edge。
Alluxio System 作為一個(gè)開(kāi)源項(xiàng)目,已廣為人知。簡(jiǎn)單地說(shuō),它是一個(gè)獨(dú)立的分布式系統(tǒng),其緩存容量可以水平擴(kuò)展,并具備數(shù)據(jù)編排系統(tǒng)的其他功能,例如接口轉(zhuǎn)換、統(tǒng)一命名空間等。本次分享的重點(diǎn)是 Alluxio Edge。
1、Alluxio Edge 是什么
Alluxio Edge 是一個(gè)庫(kù),可以放在如 PrestoDB 和 Trino 的應(yīng)用程序的進(jìn)程中運(yùn)行。它可以利用 PrestoDB 或者 Trino 集群的本地存儲(chǔ)空間(比如 SSD 或內(nèi)存)來(lái)緩存數(shù)據(jù)。當(dāng)大部分熱數(shù)據(jù)能夠放在本地磁盤(pán)或者內(nèi)存中時(shí),它是最理想的選擇。
為什么我們需要一個(gè)緩存呢?主要有下面幾個(gè)原因:
- 對(duì)很多查詢(xún)來(lái)說(shuō),IO 是排在第一位的性能瓶頸。
- 對(duì)于有些存儲(chǔ)系統(tǒng),特別是 HDFS,Datanode 的性能波動(dòng)會(huì)對(duì) Presto 或者 Trino 等查詢(xún)引擎的 IO 性能造成影響,讓寶貴的 CPU 資源空轉(zhuǎn)。
- 分布式計(jì)算引擎工作需要消耗較大的網(wǎng)絡(luò)資源,比如 shuffle。
引入緩存能夠很好地解決上述 IO 瓶頸、存儲(chǔ)系統(tǒng)性能波動(dòng)的問(wèn)題,還能節(jié)約寶貴的網(wǎng)絡(luò)資源。
上圖顯示了 Alluxio Edge 的參考架構(gòu)。當(dāng)有一個(gè) Trino 工作節(jié)點(diǎn)時(shí),Alluxio Edge 會(huì)在 Trino 工作節(jié)點(diǎn)嵌入一個(gè)本地緩存。Trino 工作節(jié)點(diǎn)和 Alluxio Edge 在數(shù)量上是一一對(duì)應(yīng)的。通常,一個(gè) Trino 集群中包含很多 Trino Worker 節(jié)點(diǎn),所以也會(huì)有多個(gè) Alluxio Edge。Alluxio Edge 會(huì)利用本地節(jié)點(diǎn)的存儲(chǔ)資源緩存數(shù)據(jù),因此當(dāng) Trino 從 S3 等存儲(chǔ)系統(tǒng)訪問(wèn)數(shù)據(jù)時(shí),數(shù)據(jù)會(huì)經(jīng)過(guò) Alluxio Edge,并被 Alluxio Edge 自動(dòng)緩存在本地的存儲(chǔ)中。Alluxio Edge 提供了一個(gè) Dashboard,來(lái)匯總整個(gè) Trino 集群中所有 Alluxio Edge 的統(tǒng)計(jì)信息,并在儀表板中匯總、顯示諸如集群信息、成本節(jié)約、資源狀態(tài)之類(lèi)的內(nèi)容。
經(jīng)過(guò)測(cè)試發(fā)現(xiàn),Alluxio Edge 使端到端查詢(xún)的性能提高了大約 1.5 倍到 10 倍。在僅有 IO 的查詢(xún)上,能夠觀察到 10 到 50 倍的 IO 速度提升。不僅如此,我們還看到,云存儲(chǔ) API 的調(diào)用在使用 Alluxio Edge 后減少了 50% 到 90%。有的時(shí)候,如果有大量請(qǐng)求同時(shí)發(fā)送到 S3,S3 可能會(huì)出現(xiàn)流量限制,其他的對(duì)象存儲(chǔ)也會(huì)有相同的限流行為來(lái)保證系統(tǒng)的整體公平性和穩(wěn)定性。當(dāng)限流出現(xiàn)時(shí),查詢(xún)性能會(huì)變得不穩(wěn)定。通過(guò)使用 Alluxio Edge 數(shù)據(jù)緩存,有助于減少網(wǎng)絡(luò)擁塞和存儲(chǔ)系統(tǒng)需要接受的請(qǐng)求數(shù)量,因此也有助于減輕底層存儲(chǔ)的負(fù)載。
2、Alluxio Edge 的主要功能
Alluxio Edge 的設(shè)計(jì)目標(biāo)是提供一個(gè)數(shù)據(jù)處理和分析場(chǎng)景下的邊緣緩存解決方案。主要功能如下:
- 利用本地 SSD 或內(nèi)存進(jìn)行數(shù)據(jù)緩存,以提供更快的數(shù)據(jù)訪問(wèn)速度。當(dāng)數(shù)據(jù)緩存在本地磁盤(pán)或者內(nèi)存中時(shí),數(shù)據(jù)的重復(fù)讀取將不再訪問(wèn)底層存儲(chǔ)。底層存儲(chǔ)的性能不穩(wěn)定或者強(qiáng)負(fù)載已經(jīng)嚴(yán)重影響它的性能的時(shí)候,本地緩存的效果會(huì)非常明顯。
- Alluxio Edge 支持多種現(xiàn)代數(shù)據(jù)湖連接器,包括 Iceberg、Hudi、DeltaLake 和 Hive。這意味著,無(wú)論您的數(shù)據(jù)是存儲(chǔ)在哪個(gè)數(shù)據(jù)湖解決方案中,Alluxio Edge 都能與之兼容。這個(gè)功能大大擴(kuò)展了 Alluxio Edge 的使用場(chǎng)景和可用范圍。
- Alluxio Edge 支持廣泛的數(shù)據(jù)格式,圖中只列出了一部分,其實(shí) Alluxio Edge可以支持任何 PrestoDB 和 Trino 所支持的數(shù)據(jù)格式。這為用戶(hù)提供了巨大的靈活性,使用戶(hù)能夠在不同的數(shù)據(jù)格式之間進(jìn)行選擇。
- Alluxio Edge 支持靈活的緩存驅(qū)逐和使用策略。默認(rèn)情況下,它支持 LRU 和 FIFO 策略。LRU (Least Recently Used) 是一個(gè)常見(jiàn)的緩存替換策略,當(dāng)緩存空間占滿(mǎn)時(shí),這個(gè)策略會(huì)驅(qū)逐最近最少使用的數(shù)據(jù)。FIFO (First-In-First-Out) 如其名所示,會(huì)驅(qū)逐最先進(jìn)入緩存的數(shù)據(jù)。用戶(hù)還可以根據(jù)其特定的需求和場(chǎng)景定義自己的緩存替換策略。Alluxio Edge 也支持 TTL (Time To Live)。使用 TTL 后,過(guò)期數(shù)據(jù)會(huì)被優(yōu)先驅(qū)逐。Alluxio Edge 的“數(shù)據(jù)配額”功能可以確保緩存不會(huì)超出為其分配的特定大小或配額的存儲(chǔ)空間。
3、Alluxio Edge 是如何工作的
Alluxio Edge 的大致工作原理如下(以 Trino 為例):
當(dāng) Trino 通過(guò)連接器(比如 Hudi)嘗試訪問(wèn)數(shù)據(jù)時(shí),它將請(qǐng)求 AlluxioCachingFileSystem。如果 AlluxioCachingFileSystem 檢查后發(fā)現(xiàn)緩存被命中了,那么,它會(huì)通過(guò)緩存管理器(AlluxioCacheManager)從本地 SSD 或內(nèi)存中訪問(wèn)數(shù)據(jù);如果緩存并未命中,請(qǐng)求則會(huì)被發(fā)送到 UnderFileSystem 中,UnderFileSystem 負(fù)責(zé)從存儲(chǔ)系統(tǒng)中(例如 S3、HDFS 等)訪問(wèn)數(shù)據(jù)。在數(shù)據(jù)被讀取后,AlluxioCachingFileSystem 會(huì)通過(guò) AlluxioCacheManager 異步緩存數(shù)據(jù)。
此外,這里提到的對(duì)象如 AlluxioCachingFileSystem、AlluxioCacheManager 都是在集群?jiǎn)?dòng)過(guò)程中,加載到 Trino Worker 進(jìn)程中的,它們成為了 Alluxio Trino Worker 進(jìn)程的一部分。所以,計(jì)算節(jié)點(diǎn)對(duì)緩存的讀取完全是在進(jìn)程內(nèi)部進(jìn)行的,效率非常高。
4、Alluxio Edge 相關(guān)的技術(shù)挑戰(zhàn)
- 數(shù)據(jù)一致性
底層存儲(chǔ)中的文件在被緩存后,有可能被更新。Hive 上的文件出現(xiàn)不一致的情況比較少,但是在使用了 Hudi 等組件后,upsert 操作的頻率大大增加,使得文件更新的頻率加快,底層存儲(chǔ)和緩存中的數(shù)據(jù)一致性問(wèn)題亟待解決。為了解決數(shù)據(jù)一致性的問(wèn)題,引入了 page versioning 的概念,把文件的 modification time 作為文件的 page 的版本號(hào)。在使用緩存數(shù)據(jù)之前,Alluxio Edge 會(huì)檢查 page 的版本號(hào),只有在版本一致的情況下,緩存數(shù)據(jù)才被使用。
- 數(shù)據(jù)本地性
默認(rèn)情況下,數(shù)據(jù)會(huì)被緩存在任意的 worker 節(jié)點(diǎn)上。如果緩存的位置是不固定的,Coordinator 很難判斷應(yīng)該把 split 派給哪個(gè) worker。“軟親和”用來(lái)解決這個(gè)問(wèn)題。軟親和開(kāi)啟后,數(shù)據(jù)可以固定地緩存在某個(gè)節(jié)點(diǎn)上。Coordinator 在分派 split 的時(shí)候,優(yōu)先選擇可能會(huì)有緩存數(shù)據(jù)的 worker。由于是“軟”親和,所以這個(gè)分派不是固定的:如果可能會(huì)有緩存數(shù)據(jù)的 worker 比較繁忙,coordinator 會(huì)選擇最“閑”的 worker 分派 split,這樣雖然損失了數(shù)據(jù)本地性,但是平衡了 worker 之間的工作負(fù)載。另外,即使緩存能夠穩(wěn)定地找到某個(gè) worker 節(jié)點(diǎn),也要考慮 worker 節(jié)點(diǎn)變化的情況。比如,原來(lái)的 worker 下線(xiàn)了,或者新的 worker 上線(xiàn)了,要避免其他 worker 重新緩存數(shù)據(jù)。一致性哈希技術(shù)用來(lái)解決 worker 節(jié)點(diǎn)變化的問(wèn)題。
- 緩存利用率
由于一段時(shí)期內(nèi)需要訪問(wèn)的全量數(shù)據(jù)總是遠(yuǎn)遠(yuǎn)大于熱數(shù)據(jù),而緩存的資源又是有限的,如果對(duì)所有的數(shù)據(jù)不加限制地進(jìn)行緩存,會(huì)造成數(shù)據(jù)頻繁被驅(qū)逐,緩存命中率不高的結(jié)果。解決這個(gè)問(wèn)題的辦法是使用緩存過(guò)濾策略。即用戶(hù)在緩存過(guò)濾策略中定義“庫(kù)、表、分區(qū)的 TTL”。只有滿(mǎn)足策略的數(shù)據(jù)才被緩存。通過(guò)這個(gè)辦法,緩存資源可以有效地存放熱數(shù)據(jù),大大增加了緩存命中率。
5、TPC-DS Benchmark 測(cè)試
對(duì) Alluxio Edge 的效果,我們首先做了充分的內(nèi)部測(cè)試。測(cè)試時(shí),我們使用了TPC-DS 作為測(cè)試數(shù)據(jù)集和 SQL 集。在所有其他條件都相同的情況下,我們比較了使用 Alluxio Edge 和直接讀 S3 兩種方式,結(jié)果顯示:
在性能方面,所有查詢(xún)時(shí)間大于 2 秒的 73 個(gè)查詢(xún)中,70 個(gè)查詢(xún)有明顯的加速效果;所有查詢(xún)執(zhí)行時(shí)間的平均值提高了 63%。左圖中,紅色部分是 S3 直讀的查詢(xún)運(yùn)行時(shí)間,藍(lán)色部分是使用了 Alluxio Edge 作為本地緩存后查詢(xún)的運(yùn)行時(shí)間,藍(lán)色部分明顯小于紅色部分。
在成本節(jié)約方面,S3 API 的請(qǐng)求數(shù)和數(shù)據(jù)傳輸量有肉眼可見(jiàn)的減少。右圖來(lái)自 AWS CloudWatch 監(jiān)控系統(tǒng)提供的 S3 對(duì)象存儲(chǔ)的相關(guān)指標(biāo),每個(gè)圖中有兩部分線(xiàn)段,前一部分的線(xiàn)段是使用 Alluxio Edge 時(shí),API 調(diào)用和下載數(shù)據(jù)量的指標(biāo),后一部分是 S3 直讀的(API 調(diào)用和下載數(shù)據(jù)量)指標(biāo)??梢钥吹剑@些 Alluxio Edge 對(duì)應(yīng)的指標(biāo)遠(yuǎn)遠(yuǎn)優(yōu)于直讀 S3 對(duì)應(yīng)的指標(biāo)。
6、應(yīng)用實(shí)例
Uber 在三個(gè)集群,共 1500 個(gè)節(jié)點(diǎn)上部署了 Alluxio Edge。在他們的使用中,觀察到端到端的輸入-讀取性能提高了 50%,而對(duì) HDFS 的數(shù)據(jù)讀取流量減少了 10%。到 GCS 的讀取請(qǐng)求有 80% 被避免了。而且,查詢(xún)延遲的 90 分位數(shù)從 228 秒減少到了 50 秒。
在新加坡某電商用戶(hù)的測(cè)試環(huán)境中,Alluxio Edge 使查詢(xún)延遲降低了 40%,同時(shí) IO 吞吐量增加了 10 倍。
7、Alluxio Edge Dashboard
Alluxio Edge 為用戶(hù)提供了一個(gè)本地部署的 dashboard。這個(gè) dashboard 對(duì) Trino/PrestoDB 上所有的 Alluxio Edge 節(jié)點(diǎn)收集的指標(biāo)進(jìn)行集中化匯總和展示。提供的信息包括集群摘要、成本節(jié)省、資源使用狀態(tài)等。通過(guò)使用這個(gè) Dashboard,用戶(hù)可以了解當(dāng)前 Alluxio Edge 的狀態(tài),比如緩存空間有多少、使用了多少;Alluxio Edge 幫助用戶(hù)節(jié)約了多少數(shù)據(jù)訪問(wèn)成本,比如一共多少 S3 API 被調(diào)用、多少 S3 API 調(diào)用實(shí)際產(chǎn)生了費(fèi)用;還有資源狀態(tài)指標(biāo),如果看到峰值,可能會(huì)發(fā)現(xiàn)系統(tǒng)出了問(wèn)題。有了這個(gè)儀表板,用戶(hù)可以輕松地了解節(jié)約的成本,并獲得具有洞察力的調(diào)優(yōu)信息。
三、Alluxio Edge 最佳實(shí)踐場(chǎng)景
- 用戶(hù)需要正在或者準(zhǔn)備使用 Trino 或者 PrestoDB。
- 用戶(hù)想要提升性能或者控制成本。
- 探索如何優(yōu)化 Trino 或者 PrestoDB 的時(shí)候,不要忘記考慮 Alluxio Edge。
四、Alluxio Edge 使用流程
Alluxio Edge 的使用非常簡(jiǎn)便,基本流程如下:
第一步
- 從網(wǎng)站(www.alluxio.com.cn)下載 Alluxio Edge 的 tarball
- 將其放入計(jì)算引擎的相關(guān)路徑中
- 運(yùn)行查詢(xún)并比較查詢(xún)性能的變化
- 啟動(dòng)本地 dashboard 查看成本節(jié)省指標(biāo)
第二步
- 使用本地儀表板進(jìn)行持續(xù)的觀測(cè)和優(yōu)化
五、問(wèn)答環(huán)節(jié)
Q1:小規(guī)模的集群、數(shù)據(jù)量的場(chǎng)景下,是不是推薦使用 Alluxio Edge 呢?
A1:在剛才我們分享的實(shí)戰(zhàn)場(chǎng)景中,比如 Uber 的例子和新加坡電商的例子,那些用戶(hù)的體量都很大,具體來(lái)說(shuō),他們的集群大小、數(shù)據(jù)量、任務(wù)數(shù)等都很大。所以,一方面,Alluxio Edge 是經(jīng)受過(guò)大規(guī)模實(shí)戰(zhàn)場(chǎng)景的打磨的。另一方面,對(duì)于這些用戶(hù),10% 甚至 1% 的性能提升或者成本控制都非??捎^。而 Alluxio Edge 為這些用戶(hù)實(shí)際帶來(lái)了遠(yuǎn)超 10% 的增益,結(jié)果是非常令人激動(dòng)的。在小規(guī)模的場(chǎng)景中,用戶(hù)可以分析一下自己的數(shù)據(jù)類(lèi)型,比如熱數(shù)據(jù)的占比是否可觀,看一下自己的可用資源的情況,比如 SSD 的可用資源和熱數(shù)據(jù)的大小的比例。如果熱數(shù)據(jù)有一定的占比,并且有足夠的本地緩存資源,用戶(hù)應(yīng)該嘗試一下 Alluxio Edge,畢竟 Alluxio Edge 的使用非常簡(jiǎn)單。一旦任務(wù)的規(guī)模增加,它的價(jià)值能夠很快體現(xiàn)。:
Q2:如果 Trino 或者 PrestoDB 的本地資源有限怎么辦?
A2:在這種情況下,您可以考慮使用多級(jí)緩存。例如,使用 Alluxio System 作為 L2 緩存,配合 Alluxio Edge 一起工作。和 Alluxio Edge 相比,Alluxio System 的特點(diǎn)是:(1)它是一個(gè)獨(dú)立的系統(tǒng)并且可以橫向擴(kuò)展,所以它可以緩存比 Alluxio Edge 更多的數(shù)據(jù);(2) 它的數(shù)據(jù)可以被不同的 worker 節(jié)點(diǎn)或不同的 Trino 或 Presto DB 集群共享,甚至被其他計(jì)算引擎共享。即使 Alluxio System 存在的情況下,Alluxio Edge 仍然有優(yōu)勢(shì),因?yàn)樗怯?jì)算引擎的一部分(嵌入式緩存),緩存性能更高。
Q3:緩存空間的大小如何影響緩存的性能和成本節(jié)約的增益?
A3:如果緩存大小太小,緩存未命中率會(huì)更高,緩存數(shù)據(jù)會(huì)被更頻繁地驅(qū)逐,從而收益會(huì)減少。理想情況下,本地存儲(chǔ)容量應(yīng)該能夠容納在一段時(shí)間內(nèi)訪問(wèn)的大部分熱數(shù)據(jù)。如果熱數(shù)據(jù)存在并且可以被識(shí)別,那么可以相應(yīng)地分配或調(diào)整緩存存儲(chǔ)大小。