自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SparkSQL 在企業(yè)級數(shù)倉建設(shè)的優(yōu)勢

原創(chuàng) 精選
大數(shù)據(jù) Spark
隨著企業(yè)的業(yè)務(wù)發(fā)展越來越復(fù)雜,需要更加靈活、更加高效的數(shù)倉架構(gòu),在這樣的業(yè)務(wù)驅(qū)動背景下,Hive 的局限變得越來越明顯,而基于 Spark SQL 靈活構(gòu)建數(shù)倉的方案將會變得越來越主流。

前言

Apache Hive 經(jīng)過多年的發(fā)展,目前基本已經(jīng)成為業(yè)界構(gòu)建超大規(guī)模數(shù)據(jù)倉庫的事實標(biāo)準(zhǔn)和數(shù)據(jù)處理工具,Hive 已經(jīng)不單單是一個技術(shù)組件,而是一種設(shè)計理念。Hive 有 JDBC 客戶端、支持標(biāo)準(zhǔn) JDBC 接口訪問的 HiveServer2 服務(wù)器、管理元數(shù)據(jù)服務(wù)的 Hive Metastore,以及任務(wù)以 MapReduce 分布式任務(wù)運行在 YARN 上。

標(biāo)準(zhǔn)的 JDBC 接口、標(biāo)準(zhǔn)的 SQL 服務(wù)器、分布式任務(wù)執(zhí)行以及元數(shù)據(jù)中心,這一系列組合讓 Hive 完整地具備了構(gòu)建一個企業(yè)級數(shù)據(jù)倉庫的所有特性,并且 Hive 的 SQL 服務(wù)器是目前使用最廣泛的標(biāo)準(zhǔn)服務(wù)器。

雖然 Hive 有非常明顯的優(yōu)點,可以找出完全替代 Hive 的組件寥寥無幾,但是并不等于 Hive 在目前階段是一個完全滿足企業(yè)業(yè)務(wù)要求的組件,很多時候選擇 Hive 出發(fā)點并不是因為 Hive 很好地支持了企業(yè)需求,單單是因為暫時找不到一個能支撐企業(yè)訴求的替代服務(wù)。

企業(yè)級數(shù)倉構(gòu)建需求

數(shù)倉架構(gòu)通常是一個企業(yè)數(shù)據(jù)分析的起點,在數(shù)倉之下會再有一層數(shù)據(jù)湖,用來做異構(gòu)數(shù)據(jù)的存儲以及數(shù)據(jù)的冷備份。但是也有很多企業(yè),特別是幾乎完全以結(jié)構(gòu)化數(shù)據(jù)為主的企業(yè)在實施上會把數(shù)據(jù)湖和企業(yè)數(shù)倉庫合并,基于某個數(shù)倉平臺合二為一。

企業(yè)在考慮構(gòu)建自身數(shù)倉體系的時候,雖然需要參考現(xiàn)有的行業(yè)技術(shù)體系,以及可以選擇的組件服務(wù),但是不能太過于局限于組件本身,尋找 100%開箱即用的產(chǎn)品。太過局限于尋找完全契合的組件服務(wù)必然受限于服務(wù)本身的實現(xiàn),給未來擴(kuò)展留下巨大的約束。企業(yè)數(shù)據(jù)倉庫架構(gòu)必然不等于一個組件,大部分企業(yè)在數(shù)倉架構(gòu)實施的都是基于現(xiàn)有的部分方案,進(jìn)行基于自己業(yè)務(wù)合適的方向進(jìn)行部分開發(fā)與定制,從而達(dá)到一個半自研的穩(wěn)態(tài),既能跟上業(yè)務(wù)變化的速度,又不過于依賴和受限于組件自身的發(fā)展。

一般來說企業(yè)級數(shù)倉架構(gòu)設(shè)計與選型的時候需要從以下幾個維度思考:

  • 開發(fā)的便利性:所選擇的數(shù)倉架構(gòu)是否具有很好的開發(fā)生態(tài),可以提供不同類型的開發(fā)態(tài)接口,不限于 SQL 編輯器,代碼提交,以及第三方工具整合。
  • 生態(tài):所選擇實現(xiàn)引擎自身是否有很好的生態(tài)功能,或者是否可以很好的與其他服務(wù)集成,例如數(shù)據(jù)湖引擎 delta lake,icebeg,hudi 等優(yōu)秀組件出現(xiàn),但是 Hive 集成的節(jié)奏卻非常慢。
  • 解耦程度:分布式任務(wù)必然需要多個組件的協(xié)調(diào),例如分布式存儲,資源管理,調(diào)度等,像 Hive 就重度依賴于 YARN 體系,計算引擎也與 MR 強(qiáng)綁定,在解耦方面較弱,如果企業(yè)考慮在 K8S 上構(gòu)建自己的計算引擎,Hive 面臨的局限會更加明顯。
  • 性能:整體架構(gòu)是否擁有更好的性能。
  • 安全:是否支持不同級別,不同力度的用戶訪問和數(shù)據(jù)安全鑒權(quán)體系。

對于企業(yè)數(shù)倉架構(gòu)來說,最重要的是如何基于企業(yè)業(yè)務(wù)流程來設(shè)計架構(gòu),而不是基于某個組件來擴(kuò)展架構(gòu)。

一個企業(yè)數(shù)倉的整體邏輯如上圖所示,數(shù)倉在構(gòu)建的時候通常需要 ETL 處理和分層設(shè)計,基于業(yè)務(wù)系統(tǒng)采集的結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)進(jìn)行各種 ETL 處理成為 DWD 層,再基于 DWD 層設(shè)計上層的數(shù)據(jù)模型層,形成 DM,中間會有 DWB/DWS 作為部分中間過程數(shù)據(jù)。

從技術(shù)選型來說,從數(shù)據(jù)源的 ETL 到數(shù)據(jù)模型的構(gòu)建通常需要長時任務(wù),也就是整個任務(wù)的運行時間通常是小時及以上級別。而 DM 層主要是支持業(yè)務(wù)的需求,對時效性要求比較高,通常運行在 DM 層上的任務(wù)時間以分鐘作為單位。

基于如上的分層設(shè)計的架構(gòu)圖可以發(fā)現(xiàn),雖然目前有非常多的組件,像 Presto、Doris、ClickHouse、Hive 等等,但是這些組件各自工作在不同的場景下,像數(shù)倉構(gòu)建和交互式分析就是兩個典型的場景。

交互式分析強(qiáng)調(diào)的是時效性,一個查詢可以快速出結(jié)果,像 Presto、Doris、ClickHouse 雖然也可以處理海量數(shù)據(jù),甚至達(dá)到 PB 及以上,但主要還是用在交互式分析上,也就是基于數(shù)據(jù)倉庫的 DM 層,給用戶提供基于業(yè)務(wù)的交互式分析查詢,方便用戶快速進(jìn)行探索。由于這類引擎更聚焦在交互式分析上,因此對于長時任務(wù)的支持度并不友好,為了達(dá)到快速獲取計算結(jié)果,這類引擎重度依賴內(nèi)存資源,需要給這類服務(wù)配置很高的硬件資源,這類組件通常有著如下約束:

  • 沒有任務(wù)級的重試,失敗了只能重跑 Query,代價較高。
  • 一般全內(nèi)存計算,無 shuffle 或 shuffle 不落盤,無法執(zhí)行海量數(shù)據(jù)。
  • 架構(gòu)為了查詢速度快,執(zhí)行前已經(jīng)調(diào)度好了 task 執(zhí)行的節(jié)點,節(jié)點故障無法重新調(diào)度。

一旦發(fā)生任務(wù)異常,例如網(wǎng)絡(luò)抖動引起的任務(wù)失敗、機(jī)器宕機(jī)引起的節(jié)點丟失,再次重試所消耗的時間幾乎等于重新提交一個任務(wù)。在分布式任務(wù)的背景下,任務(wù)運行的時間越長,出現(xiàn)錯誤的概率越高。對于此類組件的使用,業(yè)界最佳實踐的建議也是不超過 30 分鐘左右查詢使用這類引擎是比較合適的。

而在離線數(shù)倉場景下,幾乎所有任務(wù)都是長時任務(wù),也就是任務(wù)運行時長在小時級以上,這時就要求執(zhí)行 ETL 和構(gòu)建數(shù)倉模型的組件服務(wù)需要具有較高的容錯性和穩(wěn)定性,當(dāng)任務(wù)發(fā)生錯誤時可以以低成本的方式快速恢復(fù),盡可能避免因為部分節(jié)點狀態(tài)異常導(dǎo)致整個任務(wù)完全失敗。

可以發(fā)現(xiàn)在這樣的訴求下類似于 Presto、Doris、ClickHouse 就很難滿足這樣的要求,而像 Hive、Spark 這類計算引擎依托于 Yarn 做資源管理,對于分布式任務(wù)的重試、調(diào)度、切換有著非常可靠的保證。Hive、Spark 等組件自身基于可重算的數(shù)據(jù)落盤機(jī)制,確保某個節(jié)點出現(xiàn)故障或者部分任務(wù)失敗后可以快速進(jìn)行恢復(fù)。數(shù)據(jù)保存于 HDFS 等分布式存儲系統(tǒng)上,自身不管理數(shù)據(jù),具有極高的穩(wěn)定性和容錯處理機(jī)制。

反過來,因為 Hive、Spark 更善于處理這類批處理的長時任務(wù),因此這類組件不擅長與上層的交互式分析,對于這種對時效性要求更高的場景,都不能很好地滿足。所以在考慮構(gòu)建數(shù)倉的時候,通常會選擇 Hive、Spark 等組件來負(fù)責(zé),而在上層提供交互式分析查詢的時候,通常會使用 Presto、Doris、ClickHouse 等組件。

歸納如下:

  • Presto、Doris、ClickHouse:更注重交互式分析,對單機(jī)資源配置要求很高,重度依賴內(nèi)存,缺乏容錯恢復(fù),任務(wù)重試等機(jī)制,適合于 30 分鐘以內(nèi)的任務(wù),通常工作在企業(yè)的 DM 層直接面向業(yè)務(wù),處理業(yè)務(wù)需求。
  • Hive、Spark:更注重任務(wù)的穩(wěn)定性,對網(wǎng)絡(luò),IO 要求比較高,有著完善的中間臨時文件落盤,節(jié)點任務(wù)失敗的重試恢復(fù),更加合適小時級以上的長時任務(wù)運行,工作在企業(yè)的的 ETL 和數(shù)據(jù)模型構(gòu)建層,負(fù)責(zé)清洗和加工上層業(yè)務(wù)所需要的數(shù)據(jù),用來支撐整個企業(yè)的數(shù)倉構(gòu)建。

一個企業(yè)在實施數(shù)據(jù)平臺的時候,由多個不同組件各自工作在不同的架構(gòu)層中,無法相互取代,相互協(xié)作配合,承載整個企業(yè)的數(shù)據(jù)平臺業(yè)務(wù)。

企業(yè)級數(shù)倉技術(shù)選擇

Google 發(fā)表的三篇論文從存儲、計算、檢索三個方向闡述了海量數(shù)據(jù)下一種新的分布式數(shù)據(jù)加工處理技術(shù),這三個方向被雅虎 Nutch 團(tuán)隊實現(xiàn)后貢獻(xiàn)給 Apache,也就是目前大家看到的 HDFS、MapReduce 和 HBase,形成了早期 Hadoop 的三大利器。

然而這三大利器更聚焦在異構(gòu)數(shù)據(jù)的信息提取處理上,沒有提供對結(jié)構(gòu)化數(shù)據(jù)很友好的類似 SQL 語法的分析入口,同時在編程態(tài)的支撐也不夠友好,只有 Map 和 Reduce 兩階段,嚴(yán)重限制了業(yè)務(wù)處理的實現(xiàn),雅虎團(tuán)隊也是爬蟲相關(guān)業(yè)務(wù)孵化而出,可以看出 Hadoop 早期的三大套件有著如下特點:

  • 門檻高,需要編程實現(xiàn),并且編程態(tài)受限于 MapReduce 的兩階段約束。
  • 以離散數(shù)據(jù)處理為主,對分析能力、查詢等常用數(shù)據(jù)分析功能支持不足。
  • 沒有交互式客戶端,無法實現(xiàn)交互式探索。

Hive 就是誕生在這樣的較大的行業(yè)背景下,Hive 的出現(xiàn)剛好彌補(bǔ)了 Hadoop 只能用來做離線數(shù)據(jù)處理這個缺陷,提供了一種常用的分析接口,并且提供了非常好的用戶交互方式。

Hive 整體架構(gòu)如上圖所示,Hive 提供 JDBC 接口實現(xiàn)支持以編程形式進(jìn)行交互,同時業(yè)內(nèi)幾乎所有 SQL Client、開源或商業(yè) BI 工具都支持通過標(biāo)準(zhǔn) JDBC 的方式連接 Hive,可以支持?jǐn)?shù)據(jù)探索的動作,極大地豐富了大數(shù)據(jù)生態(tài)圈下的組件多樣性,同時也降低了使用門檻,可以讓熟悉 SQL 的人員低成本遷移。

基于這些設(shè)計非常好的特效,加上 Hive 經(jīng)過多年的逐步完善,發(fā)展到今天已經(jīng)是一個非常穩(wěn)定成熟的生產(chǎn)環(huán)境可用的數(shù)據(jù)倉庫組件,甚至替代品都很難找到,因此使用 Hive 作為數(shù)據(jù)倉庫的構(gòu)建基礎(chǔ)是一個非常好的選擇。

如上圖所示,其中有很多優(yōu)點:

  • 穩(wěn)定:穩(wěn)定性是 Hive 一個非常讓人稱道的特性,很多時候雖然 Hive 的性能,計算速度不及其他引擎,但是 Hive 的穩(wěn)定性卻一直是非常好的。
  • 低門檻:只需要掌握基本的 SQL 技能,便可使用 Hive 進(jìn)行開發(fā),相比其他分布式計算引擎引擎成本更低。
  • 生態(tài)豐富:Hive 和 Hadoop 生態(tài)圈緊密結(jié)合,而 Hive 自身的 Metastore 也成了大數(shù)據(jù)生態(tài)圈內(nèi)的標(biāo)準(zhǔn)元數(shù)據(jù)服務(wù),大部分引擎都支持直接適配 MetaStore。
  • 擴(kuò)展方便:Hive 自身的 UDF 機(jī)制可以快速基于業(yè)務(wù)需要擴(kuò)展功能。
  • 安全:Hive 支持 Kerberos/LDAP 多種認(rèn)證方式,并且和 Ranger 結(jié)合可以做到更細(xì)粒度的行列權(quán)限級別,擁有較好的數(shù)據(jù)安全。
  • 集成成本低:MapReduce 只支持編程態(tài)的接口,并且不支持迭代計算,Hive 封裝了 MapReduce 提供 SQL 的接口,可以很低成本的和上層數(shù)據(jù)挖掘,數(shù)據(jù)分析工具進(jìn)行集成。

所以,雖然 Hive 出現(xiàn)已經(jīng)有很長時間了,但依舊是數(shù)倉構(gòu)建的首選,在整個數(shù)倉構(gòu)建中隨處可見 Hive 的身影。盡管 Hive 有種種優(yōu)點,讓人難以割舍,但是并不等于能很好地支撐企業(yè)業(yè)務(wù)需求。很多時候選擇 Hive 僅僅是因為暫時沒有其他可選的組件,如果自己從頭開發(fā)一個,或者基于某個組件改造,成本又會遠(yuǎn)超企業(yè)預(yù)期,因此不得不繼續(xù)選擇使用 Hive。

基于實踐來看,Hive 在構(gòu)建企業(yè)數(shù)倉過程中存在的主要局限圍繞在以下幾個方面:

  • 性能:Hive 基于 MapReduce 雖然帶來了非常好的穩(wěn)定性,同時也降低了它的性能,雖然有 TEZ 做一定的優(yōu)化,但是與同類的計算引擎 Spark 相比依舊有非常大的差距。
  • 資源配置:由于 Hive 底層使用 MapReduce 作為計算引擎,而 MapReduce 對 SQL 不友好,因此 Hive 在 HiveServer2 層面實現(xiàn)了 SQL 的轉(zhuǎn)換處理,再生成基于 MapReduce 的物理計劃,從而導(dǎo)致 HiveServer2 需要非常高的配置,才能維持足夠好的穩(wěn)定性。
  • 并發(fā):Hive 的并發(fā)受限于 HiveServer2,企業(yè)需要維護(hù)多個高配的 HiveServer2 實例才能支持更好的并非,通常 Hive 的瓶頸都在 HiveServer2 而不是更底層的分布式計算。
  • 容錯成本:Hive 基于 HiveServer2 進(jìn)行 SQL 的分析處理,多個 HiveServer2 之間相互獨立不共享信息,因此當(dāng) HiveServer2 掛掉后,整個 HiveServer2 的任務(wù)都會結(jié)束,需要客戶端自行重試,為整個作業(yè)級別的容錯重啟。
  • 事務(wù)支持:Hive 的事務(wù)設(shè)置在 HiveServer2 上,一旦 HiveServer2 實例開啟事務(wù)后,整個通過該 HiveServer2 的請求都會開啟事務(wù),整個事務(wù)成本過高。
  • 部署:如果企業(yè)的計算引擎部署是基于 K8S 等容器架構(gòu),Hive on K8S 將會帶來非常大的部署成本。

雖然 Hive 在以上局限層面也做了很多嘗試(Hive On Spark),但是受限于 Hive 的架構(gòu),HiveServer2 自身有自己的 SQL 解析引擎,為了兼容架構(gòu)將解析后的結(jié)果直接翻譯成 Spark 最底層的接口,整體性能反而提升不大。

除了 Hive 之外,還有非常多其他的優(yōu)秀組件。然而,從企業(yè)數(shù)倉技術(shù)選型的視角來看,適合用來構(gòu)建數(shù)據(jù)倉庫的,目前只有 Hive 和 Spark SQL 相對更加合適,在這兩個組件中,Spark SQL 相對 Hive 的優(yōu)勢又更加明顯。

SparkSQL 如何支撐企業(yè)級數(shù)倉

Spark 引擎因為自身強(qiáng)大的生態(tài)和方便的編程接口被廣泛應(yīng)用在數(shù)據(jù)處理場景下,Spark 提供的 Spark SQL 模塊更是為使用 Spark 支撐企業(yè)數(shù)據(jù)倉庫提供了一個良好的基礎(chǔ)設(shè)施。

如上圖所示,一個典型的數(shù)據(jù)倉庫架構(gòu)需要包含不同層次的模型構(gòu)建。由于數(shù)據(jù)量大、數(shù)據(jù)結(jié)構(gòu)異構(gòu)等多種原因,大數(shù)據(jù)架構(gòu)下的企業(yè)數(shù)倉構(gòu)建拋棄了基于關(guān)系型數(shù)據(jù)庫下的 Cube 設(shè)計,直接采用基于分布式任務(wù)進(jìn)行處理來構(gòu)建多層數(shù)據(jù)模型。因此對于構(gòu)建企業(yè)數(shù)倉的服務(wù)來說,有著如下要求:

  • 支持長時任務(wù),通常是小時以上,天級別居多。
  • 支持多任務(wù),也就是高并發(fā)。
  • 穩(wěn)定性必須被保障。
  • 速度快。
  • 支持 SQL 的交互式接口。
  • 易于集成。
  • 支持任務(wù)的重跑和容錯以及快速任務(wù)失敗恢復(fù)。

基于以上特性可以發(fā)現(xiàn),在目前可選擇的組件范圍內(nèi),Spark SQL 相比其他組件(乃至 Hive)更加適合承擔(dān)這類任務(wù)。但是很多企業(yè)在進(jìn)行架構(gòu)設(shè)計的時候割舍不掉 Spark SQL 帶來的豐富特性,又愁于 Spark SQL 缺乏類似 Hive 這樣的 SQL 服務(wù)器,于是退而求其次變成 Hive 與 Spark SQL 兩個組件共存的形態(tài),Hive 退化為僅僅提供 MetaStore 服務(wù),因此從很多實踐的現(xiàn)象來看,Hive 構(gòu)建企業(yè)數(shù)倉已是過去式,采用 Spark SQL 進(jìn)行數(shù)據(jù)倉庫的構(gòu)建是眾多的選擇。

如上圖所示,企業(yè)在構(gòu)建數(shù)倉的時候,通過一個 Spark SQL Server 提供基于 SQL 接口的常駐服務(wù),同時也可以采用 Spark Submit 的方式直接提交 Jar 任務(wù)去運行,既能達(dá)到提供標(biāo)準(zhǔn) SQL 交互式接口,又能提供更靈活的編程態(tài)接口。

從不同的企業(yè)級數(shù)倉構(gòu)建視角來看,Hive 帶來的約束都越來越大,而 Spark SQL 的成熟度和發(fā)展趨勢已經(jīng)完全具備取代 Hive 來構(gòu)建整個數(shù)倉,Spark SQL 的優(yōu)勢集中體現(xiàn)在如下方面:

  • 豐富的生態(tài):Spark 不僅可以和很多組件集成,其自身擁有生態(tài)已經(jīng)涵蓋各個方面,從數(shù)據(jù)分析到機(jī)器學(xué)習(xí)和圖計算。
  • 開放:Spark 架構(gòu)設(shè)計上非常開放,可以快速整合其他產(chǎn)品,例如相比 Hive,在集成 Iceberg,Hudi 等特性方面就會開放很多。
  • 部署:Spark 既可以部署在 ECS 虛擬機(jī)上,也可部署在 K8S 架構(gòu)上,多種部署形態(tài)非常靈活。
  • 性能:Spark 的機(jī)制的流批處理性能非常合適用來構(gòu)建企業(yè)數(shù)倉。
  • 易于開發(fā):Spark SQL 既有 SQL 接口,也支持靈活的可迭代編程接口,非常方便不同場景下的數(shù)據(jù)開發(fā)。
  • 安全:Spark SQL 可和不同的安全服務(wù)集成,實現(xiàn)細(xì)粒度的鑒權(quán)。

因此,完全基于使用 Spark SQL 來支撐企業(yè)級的數(shù)倉是完全可行的,并且在目前也被眾多企業(yè)實踐驗證。

如上圖所示,一個基于 Spark SQL 構(gòu)建的企業(yè)數(shù)倉架構(gòu)邏輯架構(gòu)設(shè)計上包含以上幾個部分,每一個 Spark SQL 引擎都是一個服務(wù)器,Spark SQL 引擎將自己的信息注冊到 Zookeeper 中,SQL 服務(wù)器基于 Zookeeper 中的 Spark SQL 引擎來執(zhí)行客戶端過來的請求,SQL 服務(wù)器是一個兼容 Hive JDBC 接口的服務(wù)器,在使用 Spark SQL 來支撐數(shù)倉構(gòu)建的時需要重點考慮的實施點是:

  • 如何提供一個交互服務(wù)用來支撐不同的客戶端來連接,包括交互式的 beeline,以及編程態(tài)的 JDBC 和工具接口。
  • 如何打通權(quán)限對接,如果是 Ranger 的話需要的是 Spark SQL Ranger Plugin。
  • 如何支持跨多個隊列的任務(wù)提交。

使用 Spark SQL 支撐企業(yè)級數(shù)倉的核心之處還是在于如何提供一個好用的任務(wù)服務(wù)器,用來支撐任務(wù)的管理。任務(wù)管理服務(wù)器在邏輯上與 HiveServer2 相似,但是更加的輕量,沒有 HiveServe2 中復(fù)雜而繁重的 SQL 解析,同時又沒有 Spark Thrift Server 這種自身就是一個 YARN 作業(yè)的約束。企業(yè)可以基于自身的業(yè)務(wù)流程,開發(fā)一個輕量的服務(wù)器,在這方面字節(jié)有非常深的實踐經(jīng)驗,同時也有自己的 Spark SQL 引擎服務(wù)器,可關(guān)注后續(xù)的動態(tài)。同時業(yè)界也有其他企業(yè)做了類似的工作,例如網(wǎng)易開源的 Kyuubi。

Kyuubi 整個架構(gòu)圖如上所示,Kyuubi 基于 Spark SQL 之上,較好地彌補(bǔ)了 Spark Thrift Server 在多租戶、資源隔離和高可用等方面的不足,是一個真正可以滿足大多數(shù)生產(chǎn)環(huán)境場景的開源項目。但是 Kyuubi 在設(shè)計時考慮的是如何彌補(bǔ) Spark Thrift Server 的不足,目的在于增強(qiáng) Spark SQL 的能力,而不是對等設(shè)計一個可以替換 Hive 組件的服務(wù)。因此對于遺留項目來說遷移成本較高,Spark SQL 與 Hive 有著兩套不兼容的 SQL,在使用 Kyuubi 的時候如何降低遺留系統(tǒng)的遷移成本將是一個非常大的工作量。

而行業(yè)也有開源的 Spark Thrift Server,該思路是非常優(yōu)秀的,但是因為開發(fā)過程中有點太過于局限,導(dǎo)致依舊存在很多問題,主要體現(xiàn)在:

  • Driver 單點:整個 Spark thrift server 以一個 Spark 任務(wù)的形式運行在 YARN 上,所有的請求都運行在一個 Driver 中,一旦 Driver 掛掉后,所有任務(wù)都會同時失敗。
  • 資源隔離:因為 Spark thrift server 是以 Spark 任務(wù)的形式運行在 YARN 上,因此提交的任務(wù)如果有跨隊列提交需求的時候,Spark thrift server 很難支撐,其次多個任務(wù)運行在同一個 Driver 之中,資源使用會相互影響,很難更精細(xì)化的進(jìn)行資源的管理。
  • 多租戶:Spark thrift server 從請求層面是可以支持多用戶的,但是從架構(gòu)層面來看 Spark thrift server 是一個運行在 Yarn 上的任務(wù),它也有自己的 Application Id 有自己的任務(wù)提交者,因此它實際上是以一個超級管理員的身份運行,再做二次租戶隔離,必然存在一定的資源安全問題。
  • 高可用:Spark thrift server 本身是沒有高可用涉及的,因此它的高可用需要自行單獨設(shè)計,且還得考慮客戶端的兼容,例如 Hive JDBC 將 HA 信息存儲在 ZK 中,而 Spark thrift server 沒有這樣的機(jī)制,因此高可用的實施成本較高。

因此雖然 Spark 提供了 Spark thrift server 服務(wù)用來提供類似 JDBC 這樣的接口交互方式,但是目前依舊缺乏很多生成功能,導(dǎo)致在生產(chǎn)環(huán)境使用的情況非常少,Spark thrift server 更像是一個小眾的半成品,小修小補(bǔ)地嘗試著解決部分問題,但是沒有給予一個徹底的方案,導(dǎo)致現(xiàn)在有點缺乏實際的生產(chǎn)應(yīng)用。

字節(jié)跳動 EMR 產(chǎn)品在 Spark SQL 的優(yōu)化實踐

數(shù)據(jù)湖引擎集成

Hudi、Iceberg 等數(shù)據(jù)湖引擎目前使用的越來越廣泛,很多 B 端客戶在使用 Spark SQL 的時候也存在需要使用數(shù)據(jù)湖引擎的需求,因此字節(jié) EMR 產(chǎn)品需要將數(shù)據(jù)湖引擎集成到 Spark SQL 中,在這個過程中遇到了非常多的問題。

首先在與 Iceberg 集成的時候,對體驗和易用的問題進(jìn)行了優(yōu)化,用戶在使用 Spark SQL 過程中,需要手動輸入很多指令,并且需要找到對應(yīng)的 spark-iceberg 依賴包,這個也是目前集成 Iceberg 最常用的方案。我們的解決方式是在預(yù)先安裝的過程中,提前把 iceberg 的相關(guān) jar 包放到 spark jars 目錄下,這樣用戶只需要指定 catalog 即可,無需再手動輸出很多指令。

其次在 Spark 與 Hive 跨引擎分析場景下使用 Iceberg,Spark 正常創(chuàng)建表,Presto/Trono 可以正常讀寫,但 Hive 無法正常讀寫,這個問題官方的文檔也沒有清晰的描述,解決方案是需要修改 Spark 的配置文件或者修改 Hive 的 hive-site-spark override 配置,確保初始化出來的 Spark Session 中的配置項 iceberg.engine.hive.enable 的值為 true,Hive 才能正常地讀取 Spark 創(chuàng)建的表。

問題本質(zhì)上是由于 Iceberg 為了支持 Hive 引擎,在整體的設(shè)計上做了一些妥協(xié),使用了 Storage Handler 的方式去實現(xiàn) Hive 對 Iceberg 格式的表的讀寫,需要顯式的指定 Hive 的 Input/Output Format 實現(xiàn),而 Presto/Trono 則可以基于 Hive 的 format_type 自動識別表的格式進(jìn)行識別。

在兼容性上,由于 Iceberg 0.12 版本不支持 Spark 3.2,由于升級 Spark 的影響范圍非常大,于是更新了 Iceberg,使用了社區(qū)的一個 master 的 snapshot 版本進(jìn)行編譯,與 Spark 3.2 進(jìn)行集成。

Spark SQL 服務(wù)器

雖然行業(yè)針對 Spark SQL 提供一個 SQL 服務(wù)器已經(jīng)有 Spark Thrift Server 或者 Kyuubi 這樣的工具,但是在某些 B 端客戶的業(yè)務(wù)背景下,這些工具并不能完全滿足要求,因此字節(jié)跳動 EMR 團(tuán)隊自己設(shè)計實現(xiàn)了 Spark SQL Server,主要聚焦解決的是如下場景:

  • 兼容 Hive 語義:由于大部分 B 端客戶早期是基于 Hive 構(gòu)建的數(shù)據(jù)倉庫,后續(xù)逐步全部替換為 Spark SQL,中間必然面臨大量的系統(tǒng)遷移,而由于 Hive 與 Spark SQL 語義不盡相同,重寫 SQL 實現(xiàn)的工作量非常大,因此在字節(jié) EMR 產(chǎn)品中的 Spark SQL Server 中實現(xiàn) Hive 語義和 Spark SQL 語義的兼容,在實現(xiàn)方案上采用的時候講 Hive SQL 解析注入到 Spark 引擎中,形成一個 SQL Parser Chain,最終會匹配到某一個解析器,實現(xiàn)對 SQL 的解析,從而達(dá)到對整個 SQL 語義的兼容。
  • 提前初始化 Spark SQL 引擎:在業(yè)務(wù)請求到達(dá)前提前在 YARN 上提交 Spark 任務(wù),初始化資源信息,讓整個引擎處于等待的狀態(tài),可以減少任務(wù)提交消耗的時間,在用戶較多的情況下可以提示整體的任務(wù)執(zhí)行時間。
  • 跨 Yarn 隊列的任務(wù)提交:用戶可以指定 Yarn 隊列執(zhí)行任務(wù)。

如上圖所示,SQL 服務(wù)器是一個實現(xiàn)了 Thrift 接口的服務(wù)器,提供標(biāo)準(zhǔn)的 JDBC 訪問接口,Spark SQL 引擎同樣實現(xiàn)了 Thrift 接口,Spark SQL 引擎在服務(wù)啟動的時候便已經(jīng)被提交至 Yarn,處于等待狀態(tài)。當(dāng)業(yè)務(wù)任務(wù)到達(dá)的時候,由 SQL 服務(wù)器實現(xiàn)引擎的篩選,匹配一個已經(jīng)存在的引擎,或者重新提交一個全新的引擎用來執(zhí)行任務(wù)。

SQL 服務(wù)器支持 OpenLDAP、Kerberos 等常用的權(quán)限認(rèn)證,同時支持多種不同的隔離級別,例如 Session 級別則每一個業(yè)務(wù) SQL 都會初始化一個 Spark SQL 引擎用來接收任務(wù),任務(wù)執(zhí)行結(jié)束后,引擎從 Yarn 中銷毀。而 User 級別則針對用戶會初始性 0-N 個引擎,常駐于 Yarn 中,處于交替執(zhí)行任務(wù)。

這樣的服務(wù)器設(shè)計打破了 Spark Thrift Server 的單 Driver 所帶來的局限,解耦了 SQL 服務(wù)和任務(wù)執(zhí)行。也就支持更細(xì)粒度的資源管理和跨隊列的任務(wù)提交。

同時也兼容了 Hive 的接口,用戶可以通過如下方式訪問服務(wù)器:

HA 訪問鏈接:

./bin/beeline -u 
"jdbc:hive2://emr-5fqkwudj144d2gc1k8hi-master-1/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=midas/ha;auth=LDAP"
-n emr_dev -pEMR123456emr

非 HA 訪問鏈接:

./bin/beeline -u "jdbc:hive2://emr-master-2:10005/default;auth=LDAP” -n 
test_sub -pEMR123456emr

HA 模式下的信息被記錄在 Zookeeper 中,保存的內(nèi)容格式與 HiveServer2 的內(nèi)容一致,能確保使用 Hive 的客戶端可以直接訪問 HA 模式下的服務(wù)器。

Spark SQL 多租戶

在 Hive 任務(wù)執(zhí)行過程中,HiveServer2 服務(wù)承擔(dān)了提供 SQL 服務(wù)器進(jìn)行用戶身份認(rèn)證、權(quán)限判斷,以及解析 SQL 生成最終的執(zhí)行計劃,再由 MR 引擎執(zhí)行具體的分布式任務(wù)。

在這個過程中 HiveServer2 承擔(dān)了非常重的職責(zé),因此需要消耗非常大的資源,因此會很大程度的影響用戶的并發(fā)。對于分布式任務(wù)運行來說,它的資源約束來自于 Yarn 作為資源管理器所分配的資源,但是在 Hive 架構(gòu)下卻受限于 HiveServer2 的影響,導(dǎo)致用戶并發(fā)的數(shù)量無法隨著 Yarn 資源的提升而提升。

而在 Spark SQL 引擎中,SQL 解析是下推到引擎內(nèi)部,與具體的分布式任務(wù)執(zhí)行合為一體,不需要單獨的服務(wù)器去做 SQL 解析。也正因為 Spark SQL 與 Hive 在解析模塊的架構(gòu)存在差異,Hive On Spark 的模式會變得非常難。

針對如上的場景,字節(jié)跳動 EMR 團(tuán)隊重新設(shè)計的 SQL 服務(wù)器只負(fù)責(zé)任務(wù)的接收,進(jìn)行用戶資源、權(quán)限和身份的判斷,然后將任務(wù)發(fā)送給運行在 Yarn 中的 Spark SQL 服務(wù)器。打破了 Hive 這種并發(fā)受制于 HiveServer2 和 Yarn 兩層約束的局面,只由 Yarn 的資源決定用戶的并發(fā)程度,從而極大的降低了 Spark SQL 服務(wù)器的資源需求,增強(qiáng)了其穩(wěn)定性,在用戶并發(fā)上有了非常大的提升。

其次通過引擎預(yù)熱的功能減少任務(wù)執(zhí)行的時間,提升整體速度,引擎預(yù)熱指的是在服務(wù)啟動的時候便向 Yarn 提交 Spark SQL 引擎,處于等待的狀態(tài),當(dāng)業(yè)務(wù)請求到達(dá)的時候,基于業(yè)務(wù)類型從已經(jīng)處于就緒的引擎中選擇一個引擎來執(zhí)行任務(wù)。

并不是每一個預(yù)熱提交的引擎都會被選擇執(zhí)行,在 SQL 服務(wù)器中存在如下三種引擎隔離級別:

  • Session:基于每一個 connection 都會全新提交 Spark SQL 引擎,在鏈接斷開后,引擎從 Yarn 上銷毀。
  • User:同一個用戶可以共享多個 Spark SQL 引擎,具體的 Spark SQL 引擎?zhèn)€數(shù)由該用戶提交的任務(wù)資源需求決定,引擎在連接斷開后不會銷毀,直到引擎空閑時長到達(dá)上限。
  • Open:所有用戶都可共享的 Spark SQL 引擎,通常是用來應(yīng)對大賬號,或者集群不需要做權(quán)限管理的場景。

由此可見只有在 User、Open 的級別下引擎預(yù)熱才會產(chǎn)生價值,預(yù)熱省去了 Spark Submit 的時間,當(dāng)用戶數(shù)量足夠多,群體為統(tǒng)計單位所節(jié)省的時間越多。

Spark SQL 事務(wù)支持

Hive 的事務(wù)力度是基于 HiveServer2 實現(xiàn)的,例如通過如下語法:

CREATE TABLE tm (a int, b int) stored as orc TBLPROPERTIES
('transactional'='true', 'transactional_properties'='insert_only')

可開啟事務(wù),但是由于對事務(wù)的管理是在服務(wù)器上,因此需要開啟 ACID 的時候受影響的是整個 HiveServer2 的所有請求,而 Spark SQL 很好地集成和支持了 Hudi,Iceberg 等數(shù)據(jù)湖格式,因此在 Spark SQL 服務(wù)器中不需要實現(xiàn)類似 HiveServer2 的事務(wù)機(jī)制,只需要在最終讀取處理數(shù)據(jù)的時候,采用 Hudi、Iceberg 等特性便可達(dá)到支持事務(wù)的效果。

例如對于 Icdberg 數(shù)據(jù)格式的表已支持 update、delete 操作:

MERGE INTO prod.nyc.taxis ptUSING (SELECT * FROM staging.nyc.taxis) stON 
pt.id = st.idWHEN NOT MATCHED THEN INSERT *;

因此當(dāng) Spark SQL 集成了 Iceberg 后,便具有了事務(wù)能力,再配合 SQL 服務(wù)器,便可在很低的成本上具有和 Hive 事務(wù)能力同等的效益,同時也沒有 Hive 下的一些約束,從這樣的架構(gòu)設(shè)計上來看,能夠完整地替換 Hive。另外一個方面當(dāng)用戶數(shù)量變多,同時數(shù)據(jù)會發(fā)生修改、更新等操作,很容易造大量的小廣播傳輸,從而引起 Driver 的 OOM。雖然大廣播也會存在 OOM 的問題,但是大廣播可以通過閾值控制,而小廣播閾值對其不生效,一旦說數(shù)量變多,很容易引起 Driver 的 OOM。字節(jié) EMR 團(tuán)隊通過對小廣播進(jìn)行合并廣播,解決大量小廣播進(jìn)行傳播,導(dǎo)致打爆 Driver 的情況出現(xiàn)。

尾聲

隨著企業(yè)的業(yè)務(wù)發(fā)展越來越復(fù)雜,需要更加靈活、更加高效的數(shù)倉架構(gòu),在這樣的業(yè)務(wù)驅(qū)動背景下,Hive 的局限變得越來越明顯,而基于 Spark SQL 靈活構(gòu)建數(shù)倉的方案將會變得越來越主流。所以企業(yè)在考慮數(shù)據(jù)倉庫構(gòu)建體系的時候,可以考慮如何基于 Spark SQL 構(gòu)建自身數(shù)據(jù)體系,Spark 完善和開放的生態(tài)在未來必然會有更多優(yōu)秀的服務(wù)圍繞 Spark 形成強(qiáng)大的優(yōu)勢。

責(zé)任編輯:未麗燕 來源: 51CTO.com
相關(guān)推薦

2022-10-13 09:38:01

數(shù)據(jù)建設(shè)

2025-03-10 00:13:00

數(shù)據(jù)庫脫敏日志脫敏出脫敏

2021-06-21 11:57:04

數(shù)據(jù)中臺數(shù)字化轉(zhuǎn)型數(shù)字化

2012-04-13 13:58:52

數(shù)據(jù)加密

2010-12-14 19:56:32

IBM

2009-03-19 09:49:00

華為數(shù)據(jù)備份賽門鐵克

2010-04-26 15:27:07

互聯(lián)網(wǎng)

2013-07-19 10:21:02

數(shù)據(jù)中心四維模型評價

2022-01-04 20:34:00

數(shù)據(jù)安全Relay

2024-09-03 14:59:00

2011-02-24 10:58:16

數(shù)據(jù)庫開源

2019-11-06 10:43:20

HBaseSpark數(shù)據(jù)處理平臺

2022-01-06 20:00:39

數(shù)據(jù)企業(yè)安全

2014-08-18 09:01:09

Teradata數(shù)據(jù)倉庫

2022-01-05 20:16:52

Sentry Relay 數(shù)據(jù)安全

2022-01-08 15:08:17

項目配置Sentry

2022-01-09 21:46:22

安全數(shù)據(jù)Sentry

2010-05-24 09:04:08

2009-01-18 16:08:30

數(shù)據(jù)倉庫商務(wù)智能數(shù)據(jù)提取層

2009-04-27 17:12:11

數(shù)據(jù)保護(hù)EDPSafeNet
點贊
收藏

51CTO技術(shù)棧公眾號