close

企業級數倉架構設計與選型的時候需要從開發的便利性、生態、解耦程度、性能、 安全這幾個緯度思考。本系列分兩次連載,第一部分(本文)分享我們在企業級數倉建設上的技術選型觀點,第二個部分則重點介紹了字節跳動數據平台在通過SparkSQL進行企業級數倉建設的實踐。

文 |驚帆 來自 字節跳動數據平台EMR團隊

EMR

前言
Apache Hive 經過多年的發展,目前基本已經成了業界構建超大規模數據倉庫的事實標準和數據處理工具,Hive已經不單單是一個技術組件,而是一種設計理念。Hive有JDBC客戶端,支持標準JDBC接口訪問的HiveServer2服務器,管理元數據服務的Hive Metastore,以及任務以MapReduce分布式任務運行在YARN上。

標準的JDBC接口,標準的SQL服務器,分布式任務執行,以及元數據中心,這一系列組合讓Hive完整的具備了構建一個企業級數據倉庫的所有特性,並且Hive的SQL服務器是目前使用最廣泛的標準服務器。

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

EMR

企業級數倉構建需求

數倉架構通常是一個企業數據分析的起點,在數倉之下會再有一層數據湖,用來做異構數據的存儲以及數據的冷備份。但是也有很多企業,特別是幾乎完全以結構化數據為主的企業在實施上會把數據湖和企業數倉庫合併,基於某個數倉平台合二為一。

企業在考慮構建自身數倉體系的時候,雖然需要參考現有的行業技術體系,以及可以選擇的組件服務,但是不能太過於局限於組件本身,尋找100%開箱即用的產品。太過於局限於尋找完全契合的組件服務必然受限於服務本身的實現,給未來擴展留下巨大的約束。

企業數據倉庫架構必然不等於一個組件,大部分企業在數倉架構實施的都是都是基於現有的部分方案,進行基於自己業務合適的方向進行部分開發與定製,從而達到一個半自研的穩態,既能跟上業務變化的速度,又不過於依賴和受限於組件自身的發展。

企業級數倉架構設計與選型維度

一般來說企業級數倉架構設計與選型的時候需要從以下幾個緯度思考:

開發的便利性:所選擇的數倉架構是否具有很好的開發生態,可以提供不同類型的開發態接口,不限於SQL編輯器,代碼提交,以及第三方工具整合。

生態:所選擇實現引擎自身是否有很好的生態功能,或者是否可以很好的與其他服務集成,例如數據湖引擎delta lake,icebeg,hudi等優秀組件出現,但是Hive集成的節奏卻非常慢。

解耦程度:分布式任務必然需要多個組件的協調,例如分布式存儲,資源管理,調度等,像Hive就重度依賴於YARN體系,計算引擎也與MR強綁定,在解耦方面較弱,如果企業考慮在K8S上構建自己的計算引擎,Hive面臨的局限會更加明顯。

性能:整體架構是否擁有更好的性能。

安全:是否支持不同級別,不同力度的用戶訪問和數據安全鑒權體系。

對於企業數倉架構來說,最重要的是如何基於企業業務流程來設計架構,而不是基於某個組件來擴展架構。

一個企業數倉的整體邏輯如上圖所示,數倉在構建的時候通常需要ETL處理和分層設計,基於業務系統採集的結構化和非結構化數據進行各種ETL處理成為DWD層,再基於DWD層設計上層的數據模型層,形成DM,中間會有DWB/DWS作為部分中間過程數據。

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

基於如上的分層設計的架構圖可以發現,雖然目前有非常多的組件,像Presto、Doris、ClickHouse等等,但是這些組件各自工作在不同的場景下,像數倉構建和交互式分析就是兩個典型的場景。

交互式分析強調的是時效性,一個查詢可以快速出結果,像Presto、Doris、ClickHouse雖然也可以處理海量數據,甚至達到PB及以上,但是主要還是是用在交互式分析上,也就是基於數據倉庫的DM層,給用戶提供基於業務的交互式分析查詢,方便用戶快速進行探索。

由於這類引擎更聚焦在交互式分析上,因此對於長時任務的支持度並不友好,為了達到快速獲取計算結果,這類引擎重度依賴內存資源,需要給這類服務配置很高的硬件資源,這類組件通常有着如下約束:

沒有任務級的重試,失敗了只能重跑Query,代價較高。

一般全內存計算,無shuffle或shuffle不落盤,無法執行海量數據。

架構為了查詢速度快,執行前已經調度好了task執行的節點,節點故障無法重新調度。

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

而在離線數倉場景下,幾乎所有任務都是長時任務,也就是任務運行時常在小時及以上,這時就要求執行ETL和構建數倉模型的組件服務需要具有較高的容錯性和穩定性,當任務發生錯誤的時候可以以低成本的方式快速恢復,儘可能避免因為部分節點狀態異常導致整個任務完全失敗。

可以發現在這樣的訴求下類似於Presto、Doris、ClickHouse就很難滿足這樣的要求,而像Hive、Spark這類計算引擎依託於Yarn做資源管理,對於分布式任務的重試,調度,切換有着非常可靠的保證。

Hive、Spark等組件自身基於可重算的數據落盤機制,確保某個節點出現故障或者部分任務失敗後可以快速進行恢復。數據保存於HDFS等分布式存儲系統上,自身不管理數據,具有極高的穩定性和容錯處理機制。

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

歸納下來如下:

Presto、Doris、ClickHouse:更注重交互式分析,對單機資源配置要求很高,重度依賴內存,缺乏容錯恢復,任務重試等機制,適合於30分鐘以內的任務,通常工作在企業的DM層直接面向業務,處理業務需求。

Hive、Spark:更注重任務的穩定性,對網絡,IO要求比較高,有着完善的中間臨時文件落盤,節點任務失敗的重試恢復,更加合適小時及以上的長時任務運行,工作在企業的的ETL和數據模型構建層,負責清洗和加工上層業務所需要的數據,用來支撐整個企業的數倉構建。

一個企業在實施數據平台的時候,由多個不同組件各自工作在不同的架構層中,無法相互取代,相互協作配合,承載整個企業的數據平台業務。

EMR

企業級數倉技術選擇

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

然而這三大利器更聚焦在異構數據的信息提取處理上,沒有提供對結構化數據很友好的類似SQL語法的分析入口,同時在編程態的支撐也不夠友好,只有Map和Reduce兩階段,嚴重限制了業務處理的實現,雅虎團隊也是爬蟲相關業務孵化而出,可以看出Hadoop早期的三大套件有着如下特點:

門檻高,需要編程實現,並且編程態受限於MapReduce的兩階段約束。

以離散數據處理為主,對分析能力,查詢等常用數據分析功能支持不足。

沒有交互式客戶端,無法實現交互式探索。

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

下圖來自Hive官網,Hive整體架構如下:

Hive提供JDBC接口實現支持以編程形式進行交互,同時業內幾乎所有SQL Client、開源或商業BI工具都支持通過標準JDBC的方式連接Hive,可以支持數據探索的動作,極大的豐富了大數據生態圈下的組件多樣性,同時也降低了使用門檻,可以讓熟悉SQL的人員低成本遷移。

基於這些設計非常好的特效,加上Hive經過這多年的逐步完善,發展到今天已經是一個非常穩定成熟的生產環境可用的數據倉庫組件,甚至替代品都很難找到,因此使用Hive作為數據倉庫的構建基礎是一個非常好的選擇。

如上圖所示,其中有很多優點:

穩定:穩定性是Hive一個非常讓人稱道的特性,很多時候雖然Hive的性能,計算速度不及其他引擎,但是Hive的穩定性卻一直是非常好的。

低門檻:只需要掌握基本的SQL技能,便可使用Hive進行開發,相比其他分布式計算引擎引擎成本更低。

生態豐富:Hive和Hadoop生態圈緊密結合,而Hive自身的Metastore也成了大數據生態圈內的標準元數據服務,大部分引擎都支持直接適配MetaStore。

擴展方便:Hive自身的UDF機制可以快速基於業務需要擴展功能。

安全:Hive支持Kerberos/LDAP多種認證方式,並且和Ranger結合可以做到更細粒度的行列權限級別,擁有較好的數據安全。

集成成本低:MapReduce只支持編程態的接口,並且不支持迭代計算,Hive封裝了MapReduce提供SQL的接口,可以很低成本的和上層數據挖掘,數據分析工具進行集成。

所以雖然Hive出現已經非常有很長時間了,但是依舊是數倉構建的首選,在整個數倉構建中隨處可見Hive的身影。雖然Hive有種種優點,讓人難以割捨,但是並不等於能很好的支撐企業業務需求。很多時候選擇Hive僅僅是因為暫時沒有其他可選的組件,如果自己從頭開發一個,或者基於某個組件改造,成本又會遠超企業預期,因此不得不繼續選擇使用Hive。

Hive在構建企業數倉的局限

基於實踐來看,Hive在構建企業數倉過程中存在的主要局限圍繞在以下幾個方面:

性能:Hive基於MapReduce雖然帶來了非常好的穩定性,同時也降低了它的性能,雖然有TEZ做一定的優化,但是與同類的計算引擎Spark相比依舊有非常大的差距。

資源配置:由於Hive底層使用MapReduce作為計算引擎,而MapReduce對SQL不友好,因此Hive在HiveServer2層面實現了SQL的轉換處理,再生成基於MapReduce的物理計劃,從而導致HiveServer2需要非常高的配置,才能維持足夠好的穩定性。

並發:Hive的並發受限於HiveServer2,企業需要維護多個高配的HiveServer2實例才能支持更好的並非,通常Hive的瓶頸都在HiveServer2而不是更底層的分布式計算。

容錯成本:Hive基於HiveServer2進行SQL的分析處理,多個HiveServer2之間相互獨立不共享信息,因此當HiveServer2掛掉後,整個HiveServer2的任務都會結束,需要客戶端自行重試,為整個作業級別的容錯重啟。

事務支持:Hive的事務設置在HiveServer2上,一旦HiveServer2實例開啟事務後,整個通過該HiveServer2的請求都會開啟事務,整個事務成本過高。

部署:如果企業的計算引擎部署是基於K8S等容器架構,Hive on K8S將會帶來非常大的部署成本。

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

除了Hive之外,還有非常多的其他優秀的組件,但是從企業數倉技術選型的視角來看,適合用來構建數據倉庫的,目前只有Hive和Spark SQL相對更加合適,在這兩個組件中,Spark SQL相對Hive的優勢又更加明顯。

EMR

SparkSQL如何支撐企業級數倉

Spark引擎因為自身強大的生態和方便的編程接口被廣泛應用在數據處理場景下,Spark 提供的Spark SQL模塊更是將使用Spark支撐企業數據倉庫提供了一個良好的基礎設施。

如上圖所示,一個典型的數據倉庫架構需要包含不同層次的模型構建。由於數據量大,數據結構異構等多種原因,大數據架構下的企業數倉構建拋棄了基於關係型數據庫下的Cube設計,直接採用基於分布式任務進行處理來構建多層數據模型。因此對於構建企業數倉的服務來說,有着如下要求:

支持長時任務,通常是小時以上,天級別居多。

支持多任務,也就是高並發。

穩定性必須被保障。

速度快。

支持SQL的交互式接口。

易於集成。

支持任務的重跑和容錯以及快速任務失敗恢復。

基於以上特性可以發現,在目前可選擇的組件範圍內,Spark SQL相比其他組件,乃至Hive更加合適承擔這類任務。

但是很多企業在進行架構設計的時候割捨不掉Spark SQL帶來的豐富特性,又愁於Spark SQL缺乏類似Hive這樣的SQL服務器,於是退而求其次變成Hive與Spark SQL兩個組件共存的形態,Hive退化為僅僅提供MetaStore服務,因此從很多實踐的現象來看,Hive構建企業數倉已是過去式,採用Spark SQL進行數據倉庫的構建是眾多的選擇。

如上圖所示,企業在構建數倉的時候,通過一個Spark SQL Server提供基於SQL接口的常駐服務,同時也可以採用Spark Submit的方式直接提交Jar任務去運行,既能達到提供標準SQL交互式接口,又能提供更靈活的編程態接口。

Spark SQL優勢

從不同的企業級數倉構建視角來看,Hive帶來的約束都越來越大,而Spark SQL的成熟度和發展趨勢已經完全具備取代Hive來構建整個數倉,Spark SQL的優勢集中體現在如下方面:

豐富的生態:Spark不僅可以和很多組件集成,其自身擁有生態已經涵蓋各個方面,從數據分析到機器學習和圖計算。

開放:Spark架構設計上非常開放,可以快速整合其他產品,例如相比Hive,在集成Iceberg,Hudi等特性方面就會開放很多。

部署:Spark既可以部署在ECS虛擬機上,也可部署在K8S架構上,多種部署形態非常靈活。

性能:Spark的機制的流批處理性能非常合適用來構建企業數倉。

易於開發:Spark SQL既有SQL接口,也支持靈活的可迭代編程接口,非常方便不同場景下的數據開發。

安全:Spark SQL 可和不同的安全服務集成,實現細粒度的鑒權。

因此,完全基於使用Spark SQL來支撐企業級的數倉是完全可行的,並且在目前也被眾多企業實踐驗證。

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

如何提供一個交互服務用來支撐不同的客戶端來連接,包括交互式的beeline,以及編程態的JDBC和工具接口。

如何打通權限對接,如果是Ranger的話需要的是Spark SQL Ranger Plugin。

如何支持跨多個隊列的任務提交。

使用Spark SQL支撐企業級數倉的核心的地方還是在於如何提供一個好用的任務服務器,用來支撐任務的管理。任務管理服務器在邏輯上與HiveServer2相似,但是更加的輕量,沒有HiveServe2中複雜而繁重的SQL解析,同時又沒有Spark Thrift Server這種自身就是一個YARN作業的約束。企業可以基於自身的業務流程,開發一個輕量的服務器,在這方面字節有非常深的實踐經驗,同時也有自己的Spark SQL 引擎服務器,可關注後續的動態。

同時業界也有其他企業做了類似的工作,例如網易開源的Kyuubi。

備註:圖片來自kyuubi官網:https://github.com/apache/incubator-kyuubi

Kyuubi整個架構圖如上所示,Kyuubi基於Spark SQL之上,較好的彌補了Spark Thrift Server在多租戶、資源隔離和高可用等方面的不足,是一個真正可以滿足大多數生產環境場景的開源項目。但是Kyuubi在設計的時候考慮的是如何彌補Spark Thrift Server的不足,目的在於增強Spark SQL的能力,而不是對等設計一個可以替換Hive組件的服務。因此對於遺留項目來說遷移成本較高,Spark SQL與Hive有着兩套不兼容的SQL,在使用Kyuubi的時候如何是遺留系統遷移成本將是一個非常大的工作量。

而行業也有開源的Spark Thrift Server,該思路是非常優秀的,但是因為開發過程中有點太過於局限,導致依舊存在很多問題,主要體現在:

Driver單點:整個Spark thrift server以一個Spark任務的形式運行在YARN上,所有的請求都運行在一個Driver中,一旦Driver掛掉後,所有任務都會同時失敗。

資源隔離:因為Spark thrift server是以Spark任務的形式運行在YARN上,因此提交的任務如果有跨隊列提交需求的時候,Spark thrift server很難支撐,其次多個任務運行在同一個Driver之中,資源使用會相互影響,很難更精細化的進行資源的管理。

多租戶:Spark thrift server從請求層面是可以支持多用戶的,但是從架構層面來看Spark thrift server是一個運行在Yarn上的任務,它也有自己的Application Id有自己的任務提交者,因此它實際上是以一個超級管理員的身份運行,再做二次租戶隔離,必然存在一定的資源安全問題。

高可用:Spark thrift server本身是沒有高可用涉及的,因此它的高可用需要自行單獨設計,且還得考慮客戶端的兼容,例如Hive JDBC將HA信息存儲在ZK中,而Spark thrift server沒有這樣的機制,因此高可用的實施成本較高。

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

字節跳動的數倉在2020年全面從Hive遷移至Spark SQL,除了組件層面的源碼修改外,在使用層面也對Spark 做了非常多的優化。在下一次連載推送中,將重點介紹字節跳動數據平台在通過SparkSQL進行企業級數倉建設的實踐。

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()