Apache Kyuubi及在移動雲湖倉一體中的實踐(附應用案例合集下載)

語言: CN / TW / HK

分享嘉賓 :姚琴 網易數帆 技術專家

洪鼕鼕 中國移動雲能力中心 軟體開發工程師

編輯整理 :牛紅豔

出品平臺:DataFunTalk

導讀: 在雲原生+大資料的時代,隨著業務資料量的爆炸式增長以及對高時效性的要求,雲原生大資料分析技術,經歷了從傳統數倉到資料湖,再到湖倉一體的演進。 本文主要介紹Apache Kyuubi技術架構,及 Kyuubi在移動雲的應用場景。

今天的介紹會圍繞下面五點展開:

  • Kyuubi系統簡介

  • Kyuubi架構解析

  • Kyuubi使用場景

  • Kyuubi開放社群

  • Kyuubi在移動雲的實踐

本文已收錄至DataFunTalk202205期月刊——一線企業及高校技術乾貨分享共計28篇495頁,覆蓋搜尋、推薦、廣告、智慧風控、大資料等模組,實踐豐富案例詳實,感興趣的讀者可以掃碼或點選閱讀原文 免費下載

01

Kyuubi系統 簡介

首先,讓我們來認識一下 Kyuubi。

Kyuubi 的中文譯名是“九尾狐”,狐會噴火,用來致敬 Apache Spark,九代表多租戶能力,最後的BI揭示我們最初面向的是大資料的BI場景。所以我們的圖示是一隻狐狸。

Kyuubi 是一個 Thrift JDBC/ODBC 服務,目前對接了 Apache Spark 計算框架,支援多租戶和分散式等特性,可以滿足企業內諸如 ETL、BI 報表等多種大資料場景的應用。

Kyuubi 的服務層提供JDBC等標準化的介面,隱藏底層計算框架、儲存系統,開箱即用,使用者無需編寫和配置 Spark 程式,大大降低使用者使用門檻。

我們通過 Kyuubi 的引擎層封裝完整的 Spark SQL 能力,提供高效能的大資料分析處理能力。首先,它可以Run anywhere,既可以支援跑在傳統的 YARN 叢集上,也支援 K8s 叢集;其次,通過 Spark SQL DataSource API 的強大能力,可以讓我們輕鬆的將傳統大資料數倉和資料湖框架串聯起來,構建湖倉一體。最後,通過服務化,SQL 化的方式提供大資料處理能力,也可以大大提升底層開發運維同學的工作效率。一方面可以更加方便的去診斷和調優,另一方面可以做充分的鑑權認證,保證資料安全,也可以簡化部署、升級等日常運維工作。

所以,從現階段的核心能力來說,Kyuubi 提供了一個相容 HiveServer2 協議的介面,加上在Spark SQL 之上構建多租戶、多應用服務的能力,可以讓使用者以“服務化”的方式執行 Spark 的各種資料計算任務。

從社群當前階段的發展目標來看,它的主要方向是依託本身的架構設計,圍繞各類主流計算框架,打造一個面向 Serverless SQL on Lakehouse 的服務,支援更加豐富的大資料場景應用。在接入側,社群除了完整對接了傳統 Hive 數倉生態,也在嘗試提供REST API 和 MySQL 協議的支援。在計算側,也在嘗試對 Flink 、Presto 等計算框架的支援。在儲存側,我們也對所有的資料湖框架完成了支援。大家可以前往我們的 Github 地址進一步瞭解社群的動態。

02

Kyuubi架構解析

接下來,介紹 Kyuubi 的實現架構。

在這之前,我們先來看看 Spark Thrift Server 的實現和存在的問題。從狹義的角度來講,我們可以認為 Kyuubi 是 Spark Thrift Server 的增強版本。在易用性上,Spark 社群一路用 RDD 替換Map Reduce,簡化了大資料程式設計邏輯,接著又上了 Data Frame 來遮蔽了 RDD 的底層細節,進一步降低程式設計難度,而 Thrift Server 的出現則進一步讓它變得“開箱即用”, 使用者無需 Spark 程式設計基礎,直接用 SQL 就可以進行互動式資料分析。

但是,它在帶來便利的同時,不足之處也是比較明顯的。

  • 首先,它是“服務”於“計算引擎”完全耦合的“單”應用。它響應客戶端Session 和 Operation 等請求,完成對SparkSession 例項的新建及SQL API的呼叫,然後所有的計算排程交給一個 SparkContext 單例來完成。單應用導致了它只能在使用單條佇列的資源,無法通過YARN、K8s這類資源管理器做資源隔離。這與我們線上普遍為不同的產品線或者團隊劃分不同佇列是大相徑庭的。同時它只有一個 Spark Driver,負責所有的 SQL 編譯,DAG 排程,容易過載,任務之間很容易相互影響。

  • 一個Spark 應用只有一個全域性的使用者,所以它本質上是一個單租戶系統,對於一些資料安全級別比較高的場景,它並不適配。

  • 此外,作為一個“常駐”的服務,沒有“高可用”的支援導致了它客戶端併發能力受限,且容易造成單點故障,不適用於大規模的生產落地。

為了突破 Spark Thrift Server 架構上的限制,實現“服務”與“計算引擎”的解耦,並引入多租戶及高可用等能力,我們引入了常駐的 KyuubiServer程序,可定義生命週期的Kyuubi引擎,及兩層的服務發現模組。Kyuubi引擎的實現邏輯和 Spark Thrift Server 如出一轍,不同的是它可以通過client/cluster模式提交,IP和埠都是隨機的,所以額外加上了做服務發現的客戶端,用於將自己暴露給Server和對應的租戶。KyuubiServer本質上也共用了引擎的設計和抽象。在具體的實現上,針對連線請求,我們在 Server 端裂變成了兩類操作,一個是引擎型別的操作,包括髮現邏輯和新建邏輯,這為多應用提供了基礎。另一個 Session 本身的連線邏輯,我們將它重定向至被發現的引擎上。服務發現模組目前也支援外接的 Zookeeper,Server 就可以負載均衡的方式實現高可用。

前面講到了對服務端Session請求的特殊處理讓 Kyuubi 架構獲得了多應用多引擎的能力。而 Kyuubi 多租戶的設計則是為了在保證租戶隔離的大前提下,合理的隔離和共享這些引擎。資料結構 Engine Space,是一個簡單KV,其中 value 是引擎的隨機地址,key 則包含多個部分,ServerSpace 用於隔離不同的 Kyuubi 叢集,Version 用於版本隔離,防止相容性問題,ShareLevel 是共享策略,應對不同工作負載,EngineType 用於隔離不同計算框架,EngineUser用於隔離租戶,Subdomain 是使用者自定義的隔離欄位。KyuubiServer拿著客戶端連線請求中的認證資訊、配置資訊生成對應的 Key,當我們能通過 key 獲取到對應的引擎例項,就可以實現對該引擎實現共享,否則,就會進入引擎啟動的邏輯,這個過程中,服務端會把 Key 傳遞給引擎端,引擎完成初始化後,會在 Engine Space 中插入自己的資訊,這時服務端就可以拿到這個資訊完成對應的連線了。

Kyuubi 通過服務註冊發現實現負載均衡,來獲得高可用能力和高客戶端併發能力。作為一個常駐的服務,不可避免的會遇到各種計劃內或者計劃外的停服事件,比如服務端的各類硬體或者軟體故障,升級操作等。通過服務註冊發現機制,我們對計劃內的維護升級操作,可以實現“平滑下線”。對計劃外的單點故障,可以提供客戶端重試的機制,保證任務的容錯能力。同時,在高可用模式下,引擎依然遵循 Kyuubi 多租戶的對應關係來實現隔離和共享。

綜合引擎啟動耗時、單引擎的負載能力,叢集整體資源利用率等因素,併為了滿足不同大資料工作負載對資源隔離共享,穩定性效能、響應時間的不同訴求,我們引入了不同粒度的引擎隔離共享策略。分別是基於連線、使用者、使用者組和Server 四個粒度。舉例來說,基於連線的共享模式,連線和引擎是一對一的關係,每個連線都有一個自己的獨立引擎,其他任何人或連線都無法訪問。這種模式可以提供良好的隔離性使得它也可以勝任一些大型的批處理作業。在這種模式下,連線關閉時,引擎會及時關閉,釋放所有計算資源。再比如,基於使用者的共享模式,預設情況下,使用者和引擎是一對一的關係,每個使用者都有一個自己的獨立引擎,其他任何人都無法訪問,而來自同一使用者的連線則可以複用這個引擎。對於一個分析師來講,他所有的連線只有一次包含比較耗時的引擎啟動,其他的都可以快速響應,可以比較愉快的進行互動式分析。

對於一個多租戶叢集而言,為了較好提升叢集整體的資源利用率,除了可以充分利用YARN 和 K8s 等資源排程管理服務的能力之外,對於單個引擎而言,我們也實現了二級的資源彈效能力。在引擎之上,我們合理設定引擎的空閒 TTL 時間,來實現它的資源複用和回收。在引擎之內,我們可以開啟 Spark 提供的動態資源分配功能,合理設定最大可分配 Executor 個數及Executor 空閒 TTL,來實現 Executor 的資源複用和回收。

從服務化的角度,彈性資源的能力讓我們可以根據作業實際的負載去申請和使用資源,而 Spark 3.0 之後引入的自適應查詢引擎則可以讓這個過程更加的“智慧”。 它可以利用中間計算結果的統計資訊,進一步優化後續的執行計劃,實現動態合併 Shuffle 分割槽、動態選擇 Join 策略、動態的處理 Join 中的資料傾斜問題等。 我們內部在實踐和落地這個特性的時候,也發現了不少的問題,很多優化根據“上游優先”的開源玩法,我們都推到了 Spark 社群中。 而一些更加符合 Kyuubi 場景的特性或者暫時合不進去的,都以可擴充套件外掛的方式在 Kyuubi 社群中維護。 比如對於合併分割槽規則,一個靜態的推薦合併大小引數,一方面很難在各種複雜運算元間取得平衡,另一方面對於寫場景,通常我們期望一個較大的引數值來規避小檔案的產生,在這種情況下,中間過程的並行度也會到影響,影響整個作業的效能。 對於這個問題,Kyuubi 引入了 Stage 級別的配置隔離策略,單獨對最後 Stage 的引數進行配置,同時保證中間併發和最終檔案的輸出大小。 其他,我們還引入增加資料傾斜命中的規則、Z-Order 索引等拓展。 此外,Kyuubi 也支援使用者在 Spark 所提供的可擴充套件點上的任意自定義擴充套件。

03

Kyuubi使用場景

在第三部分,我們簡單介紹下 Kyuubi 的使用場景

我們在社群的Github討論區有一個編號為925的的單獨討論帖,來收集使用者的使用場景。總的來說,大部分的使用者都採用 Kyuubi 來替換 HiveServer2 來提升效能,彌補 Spark Thrift Server在場景和拓展能力上的不足。其次,是基於 Kyuubi 加 Spark on K8s 的能力提供大資料上雲的能力,實現離線線上業務混部,降低IT設施的總擁有成本。最後,是整合 Hudi、Iceberg 等資料湖框架,搭建資料湖分析平臺。從目前的討論帖登記情況來看,Kyuubi在不同行業的很多公司都有成功的落地實踐,比如影片領域的 B 站和愛奇藝,提供雲上大資料服務的騰訊雲和中國移動移動雲,T3 出行的 Apache Hudi PMC 楊華老師團隊也整合 Kyuubi 和 Hudi 打造了 T3 的資料湖平臺。這些社群使用者中,也湧現了不少社群貢獻者,同時,我們在這些案例分享中,也吸收了不少靈感。歡迎大家來使用 Kyuubi 專案並與社群分享你們的實踐案例。

04

Kyuubi開放社群

最後,我們來簡單回顧下 Kyuubi 開放社群的建設和發展。

Kyuubi 最早在2018年從網易魔改的內部 Spark 分支中獨立出來並開源,一直遵循 Apache Licence 2.0 版本開源協議。 最初的目的是為了引入多租戶能力,滿足 Spark 許可權控制的需求。 2020年,完成了新架構的設計和對 Spark 3.0 的支援,應用場景也更加豐富,這些變化帶來了不少新使用者和貢獻者。 Apache軟體基金會是全球最大的開源組織之一,很多知名的大資料專案如 Hadoop / Spark / Hive 等都在其指導下孵化成為頂級專案,Kyuubi 和這些專案的生態關係,也了社群的進一步發展,讓我們社群有了進入 Apache 社群孵化的想法。 2021年6月,這個想法成為現實,我們順利進入 Apache 軟體基金會孵。 Kyuubi 進入 Apache 基金會的目的是希望在 Apache 基金會的幫助下,構建一個廠商中立的多元化社群,推動 Kyuubi 專案的發展。 在2021年的上半年,在社群小夥伴的共同努力下,我們成功釋出了1.3.0、1.3.1 和的1.4.0 一共3 個 Apache release 版本。

“Community Over Code”/ “社群大於程式碼”是 Apache 不變的宗旨,它是一種鼓勵長期協作和保持專案穩定的方式。Apache Kyuubi 社群希望有興趣的小夥伴可以加入我們,你可以分享你的實踐案例,訂閱郵件列表關注社群動態,提個問題報個BUG,當然也可以直接來幫助我們修復文件,測試和程式碼。對英文文件有一定障礙的同學,可以關注我們的公眾號,我們也在努力生產中文指南。

05

Kyuubi在移動雲的實踐

1. 專案背景

私有云專案需要一個支援多使用者Spark的能力,移動雲Lakehouse需要提供jdbc能力,因Hive on Spark對Spark版本有較強的依賴,所以調研了Spark Thrift Server on k8s和Apache Kyuubi。

  • Spark Thrift Server, 本質上就是一個 Spark 應用在多執行緒場景下的應用。它在執行時啟動一個由 Driver 和 Executor 組成的分散式 SQL 引擎。在 SQL 解析層,該服務可充分利用 Spark SQL 優化器的能力,在計算執行層,由於 Spark Thrift Server是常駐型別的應用,沒有啟動開銷,當沒有開啟動態分配的情況下,整個 SQL 的計算過程為純的執行緒排程模式,效能極佳。其本質上是一個 Spark Application。用一個 Spark Application 去響應成千上萬的客戶端請求,一般會存在較大限制。

  • Apache Kyuubi ,Kyuubi是對Spark Thrift Server的加強版,Kyuubi 在統一介面基礎上,拓展了 Spark Thrift Server 在多租戶模式下的使用場景,並依託多租戶概念獲得了完善的資源隔離共享能力和資料安全隔離的能力。而得益於 Kyuubi Server 和 Engine 松耦合的架構極大提升了服務自身的併發能力和服務穩定性。

對比 Apache Kyuubi 和 Spark Thrift Server我們發現,Kyuubi 在租戶控制,任務資源隔離,引擎升級對接,效能等方面擁有諸多優勢。

2. 架構位置

Lakehouse中和Kyuubi相關的服務大致可以分為4類。

  • 服務提供:Lakehouse面向使用者層面的服務介面,Kyuubi提供JDBC能力。

  • 管理服務:Job manager主要處理由console和Open api提交的離線批處理任務,resouce manager負責使用者例項的資源分配,log manager服務日誌採集並提供SQL審計介面。

  • 計算引擎:為使用者提供OLAP、即席查詢以及資料遷移。

  • 資料儲存:底層儲存主要為HDFS和移動雲EOS物件儲存,格式上支援Hive表和Hudi表。

3. 移動雲端實踐

① Kyuubi on ecloud

社群版Kyuubi是由使用者決定自己需要多少資源,Kyuubi在k8s或yarn上啟動spark。

由於在移動場景中每個例項的資源是有限制的,我們基於移動雲使用場景做了改進:

  • 資源管理 :資源統一由Lakehouse資源排程管理,和console共用例項資源;所有的資源由resource schedule分配和控制;禁止使用者指定引擎相關引數。

  • 使用者認證 :在自定義認證的基礎上,實現基於移動雲AccessKey、SecretKey方式認證授權。

  • 日誌審計 :對接lakehouse SQL審計平臺。

  • SQL分析與攔截 :通過Kyuubi擴充套件外掛實現了SQL前置分析、語法限制以及物件儲存資訊的動態載入。 

② Kyuubi on kubernetes部署方式 

  • 使用Helm3管理Kyuubi相關服務

  • 使用Depolyment方式部署Kyuubi server

  • 使用LoadBalancer service提供server高可用和負載均衡

  • 與ZooKeeper解耦,使用etcd提供ServiceDiscovery

③ Kyuubi with trino

Kyuubi通過gateway的方式實現對trino叢集的訪問。Trino engine會以Client的形式通過http請求與叢集通訊,獲取計算結果。與Spark engine類似,獲取到結果資料後,會將其轉換為hiveserver2對應的資料型別。最後,通過thrift協議將結果返回給Kyuubi srever並提供給使用者。 其結構如上圖所示。

Kyuubi with trino的優點如下:

  • 引擎和服務解耦,在kyuubi中統一實現使用者認證、SQL預處理,審計等工作,引擎只需要關注核心優化,便於升級;

  • 統一JDBC服務,只需要有一個JDBCserver,使用者只需在連線時指定engine型別,通過引數指定所需要的引擎:spark、trino、flink。

今天的分享就到這裡,謝謝大家。

分享嘉賓:

本文已收錄至DataFunTalk202205期月刊——其中包含20篇人工智慧文章,8篇大資料文章,由來自騰訊、百度、美團、京東、虎牙、阿里巴巴、獅橋集團、網易、北大等企業與高校的30位技術人員、教授的經驗分享組成,覆蓋搜尋、推薦、廣告、智慧風控、大資料等模組,實踐豐富案例詳實,感興趣的讀者可以掃碼或點選閱讀原文 免費下載

資料目錄