
Kyuubi是網易有數的大數據開源項目,於2021年6月全票通過進入世界頂級開源基金會 Apache Software Foundation 孵化器。
Kyuubi 的命名源自中國神話《山海經》,意為「九尾狐」。狐會噴火,象徵Spark;狐有九尾,類比多租戶,在Spark上實現多租戶是系統設計之初的主要目的。然後取了動漫《火影忍者》中角色九尾的羅馬音['kju:bi:],作為項目名稱。
Kyuubi 的目標是讓「大數據平民化」。為實現這個目標,我們遵循「專業人做專業事」的準則,通過 Kyuubi的 C/S 架構,服務端大數據專家可以將 Spark 等大數據算力極致優化並高度封裝後提供出來,業務端可通過該算力直接在自己擅長的業務領域處理數據產生價值,兩者之間通過簡單的接口進行必要且有效的直接交互。
Kyuubi 使用場景:
替換 HiveServer2,輕鬆獲得 10~100 倍性能提升
構建 Serverless Spark 平台
構建統一數據湖探索分析管理平台
CDH 最後一個免費版 6.3.2 發布一年有餘,離線計算核心組件版本停在了 Hadoop 3.0.0,Hive 2.1.1,Spark 2.4.0。
隨着 Spark 3.0 的重磅發布,在性能方面又迎來了一次飛躍,本文將描述把 Spark 3 集成到 CDH 6.3.1(未開啟 Kerberos) 的過程,並使用 Kyuubi 替換 HiveServer2,實現 OLAP、ETL 等場景下從 HiveQL 到 SparkSQL 的無縫遷移,享受 10x-100x 的性能紅利。
CDH 缺陷修復
[ORC-125] 修復 Hive 不能讀取高版本 ORC 寫入的數據
當使用 Hive 讀取由 Presto 或者 Spark 等寫入的 ORC 文件時,會出現以下錯誤。
該問題在 ORC 上游被修復 [ORC-125] Correct OrcFile.WriterVersion to correctly use FUTURE。
ORC 最早是 Hive 的一個子項目,在 CDH 6 集成的 Hive 2.1 這個版本里,ORC 還沒有分離出去,所以這個問題要在 Hive 源碼里修復。
我做了一個打包好的修復版本,GitHub 傳送門①,下載更換 /opt/cloudera/parcels/CDH/lib/hive/lib 路徑下的 hive-exec-2.1.1-cdh6.3.1.jar, hive-orc-2.1.1-cdh6.3.1.jar即可。(至少需要更換 Hadoop Client、HiveServer2 節點,如果你不知道我在說什麼,就把所有節點都換掉)
Spark 3.1
[SPARK-33212] Spark 使用 Hadoop Shaded Client
Hadoop 3.0 提供了 Shaded Client,用於下游項目規避依賴衝突 [HADOOP-11656] Classpath isolation for downstream clients。
Spark 3.2 在 hadoop-3.2profile 中切換到了 Hadoop Shaded Client [SPARK-33212] Upgrade to Hadoop 3.2.2 and move to shaded clients for Hadoop 3.x profile。
該更改不是必須的,但個人建議從 Spark 主線將該補丁移植到 branch-3.1 使用,以規避潛在的依賴衝突。
[CDH-71907] Spark HiveShim 適配 CDH Hive
Spark 通過反射和隔離的類加載器來實現對多版本 Hive Metastore 的支持,詳情參考 Interacting with Different Versions of Hive Metastore - Spark Documentation。
CDH 6 使用修改過的 Hive 2.1.1 版本,其方法簽名與 Apache 版本有所不同,故 Spark HiveShim 反射調用會出現找不到方法簽名,需要手動將 CDH-71907 補丁打到 branch-3.1。
Spark External Shuffle Service 協議兼容
Spark shuffle 時,mapper 會將數據寫入到本地磁盤而非 HDFS,引入 ESS 後,會將文件信息註冊到 ESS 中,將 mapper 與 reducer 解耦。CDH 中,默認會啟用 Spark Yarn External Shuffle Service,作為 YARN AUX Service 在所有 Yarn Node 上啟動。
Spark 3 修改了 shuffle 通信協議,在與 CDH 2.4 版本的 ESS 交互時,需要設置 spark.shuffle.useOldFetchProtocol=true,否則可能報如下錯誤。[SPARK-29435] Spark 3 doesn't work with older shuffle service
Spark 版本遷移指南
如果你有現存的基於 CDH Spark 2.4 的 Spark SQL/Job,在將其遷移至 Spark 3 版本前,請參閱完整的官方遷移指南。
Migration Guide: Spark Core - Spark Documentation②
Migration Guide: SQL, Datasets and DataFrame - Spark Documentation③
Spark 部署
官方文檔 Running Spark on YARN - Documentation中提到
TomakeSparkruntimejarsaccessiblefromYARNside,youcanspecifyspark.yarn.archiveorspark.yarn.jars.FordetailspleaserefertoSparkProperties.Ifneitherspark.yarn.archivenorspark.yarn.jarsisspecified,Sparkwillcreateazipfilewithalljarsunder$SPARK_HOME
因此,無需在 CDH 所有節點上部署 Spark 3,只需在 Hadoop Client 節點上部署 Spark 3 即可。
如果你對集群權限管理沒有十分嚴格的要求,請使用 hive 用戶以避免權限問題。
我基於 Spark 3.1.2 製作了一個適配 CDH 6 的版本, GitHub 傳送門 ,下載解壓至 /opt,並軟鏈至 /opt/spark3。
配置 Hadoop、Hive
CDH 會將配置文件自動分發到所有節點 /etc 目錄下,建立軟鏈即可。
配置 Spark 環境變量 /opt/spark3/conf/spark-env.sh
配置 Spark 默認參數 /opt/spark3/conf/spark-defaults.conf
請參考 Configuration - Spark Documentation 根據集群環境實際情況進行微調
驗證 spark-shell 工作正常
至此,Spark 3 on CDH 6 已經部署完成,可以像 CDH 自帶的 Spark 2.4 一樣,正常的使用 spark-submit、spark-shell,但依舊不支持 spark-sql,spark-thriftserver。
相比略顯雞肋的 spark-sql,spark-thriftserver,Kyuubi 是更好的選擇,因此我故意移除了這兩個功能。
注意:我提供的構建版,沒有啟用 spark-thriftserver 模塊,為正常使用 Kyuubi,請下載hive-service-rpc-3.1.2.jar 添加到 /opt/spark3/jars路徑。
Kyuubi —— 解鎖 Spark SQL 更多場景
簡言之,Apache Kyuubi (Incubating) 之於 Spark,類似 HiveServer2 之於 Hive。
Kyuubi 通過將 Spark 暴露一個與 HiveServer2 完全兼容的 Thrift API,可以兼容現有的 Hive 生態,如 beeline,hive-jdbc-driver,HUE,Superset 等。
可以通過以下文檔來了解 Kyuubi 的架構,Kyuubi 與 HiveServer2 和 Spark Thrift Server 的異同。
Welcome to Kyuubi’s documentation④
Kyuubi Architecture — Kyuubi documentation ⑤
Kyuubi v.s. HiveServer2 — Kyuubi documentation⑥
Kyuubi v.s. Spark Thrift JDBC/ODBC Server (STS) — Kyuubi documentation⑦
Kyuubi 部署
Kyuubi 無需任何修改即可適配 CDH 6,下面給出關鍵步驟,詳情可以參考 Deploy Kyuubi engines on Yarn — Kyuubi documentation ⑧
同樣的,如果你對集群權限管理沒有十分嚴格的要求,請使用 hive 用戶以避免權限問題。
解壓部署
下載 kyuubi-1.3.0-incubating-bin.tgz 解壓至 /opt,並創建軟鏈到 /opt/kyuubi。
修改配置
按需修改/opt/kyuubi/conf/kyuubi-env.sh
參考Kyuubi Configurations System — Kyuubi documentation⑨
按需修改/opt/kyuubi/conf/kyuubi-defaults.conf
注意:kyuubi-defaults.conf 中的 spark 配置優先級高於 spark-defaults.conf
性能調優
How To Use Spark Dynamic Resource Allocation (DRA) in Kyuubi — Kyuubi documentation⑩
How To Use Spark Adaptive Query Execution (AQE) in Kyuubi — Kyuubi documentation ⑪
啟動
使用/opt/kyuubi/bin/kyuubi 在前台或後台啟動 Kyuubi Server。
Beeline 連接
使用默認參數連接 Kyuubi
使用自定義參數連接 Kyuubi
詳細配置參考 Access Kyuubi with Hive JDBC and ODBC Drivers — Kyuubi documentation⑫
HUE 連接
簡單說,在 Cloudera Manager 中修改 HUE 配置項 Hue Service Advanced Configuration Snippet 如下,即可在 HUE 中開啟 Spark SQL 引擎。
詳細配置參考 Getting Started with Kyuubi and Cloudera Hue — Kyuubi documentation⑬
Kyuubi engine 共享級別與應用場景
Kyuubi Spark engine 即一個 Spark driver,通過控制 engine 的共享策略,可以在隔離性和資源利用率上取得平衡。Kyuubi 提供 3 種 engine 共享級別,分別為 CONNECTION,USER(默認),SERVER。
下面的討論均假設使用 YARN Cluster 模式啟動 Kyuubi Spark engine。
我們首先補充一些時間開銷和 Spark 操作執行的信息。
Kyuubi Spark engine 在冷啟動時,會由 Kyuubi Server 通過spark-submit 命令向 YARN 提交一個 Spark App,即 engine,該過程從提交到 Spark driver 啟動約需要 5-6s,然後 engine 將自己註冊到 Zookeeper,Kyuubi Server 監聽 Zookeeper 發現 engine 並建立連接,該過程約 1-2s,如此算來,在 YARN 資源空閒時,整個 engine 冷啟動時間約 6-8s;Client 連接到存在的 engine,通常耗時 1s 內。
如果啟動了 Spark 的 executor 動態伸縮特性,真正執行 SQL 任務時,如果資源有富餘,會動態創建 executor,每個 executor 創建耗時約為 2-3s。
元數據、DDL 等操作,如獲取 database 列表,CREATE TABLE語句等,會在 driver 上執行;計算任務如 JOIN、COUNT() 等,會由 driver 生成執行計劃,在 executor 上執行。
在我們的生產環境中,大概有如下三種使用場景:
(1)使用 HUE 進行 ad-hoc 查詢
該場景中,會有多個用戶進行查詢,一般會運行相對較大的查詢任務,用戶對連接創建時間以及元數據加載時間較為敏感,但對查詢結果響應時間有一定的容忍性。在這種場景中,使用默認的 USER 共享級別,每個用戶只使用一個 Spark engine,配合使用 Spark 的動態伸縮特性,動態的創建和銷毀 executor,在保證用戶之間隔離的基礎上,降低啟動時間和資源占用。建議的關鍵配置如下:
(2)使用 Beeline 運行批任務
SQL 該場景會使用統一的 batch 賬號提交 SQL 任務,對響應時間敏感度低,但對穩定性要求非常要,並且應儘可能的最大化利用集群資源。推薦在該場景下將共享級別調整為 CONNECTION,這樣每個 SQL 執行將會使用獨立的 Spark driver,並且 SQL 執行完畢後 Spark driver 立即退出,保障離線任務互不干擾,並且資源及時釋放。建議的關鍵配置如下:
(3)使用 Superset 進行多數據源聯邦查詢
該場景中,只有一個 service 賬號,會定時同時刷新大量的圖表,對連接創建時間、查詢結果響應時間、並發度都有較高的要求。該場景中,driver 和 executor 的啟動時間都是不容忽視的,因此在 ad-hoc 查詢配置的基礎上,應延長 driver、executor 的閒置等待時間,並且設定最小的 executor 保活數量,保證時刻有 executor 常駐,能快速響應較小的查詢。建議的關鍵配置如下:
我們可以啟動三個 Kyuubi Server(單機或集群)來分別應對如上的三種場景,但也可以僅啟動一個 Kyuubi Server(單機或集群)來滿足不同的場景。
一種建議的實踐方式是 Kyuubi Server 配置使用默認的 USER 共享級別,這樣客戶端連接時,會使用默認配置;當 ETL 跑批場景時,可以通過 beeline 參數將本次連接共享級別調整為 CONNECTION;類似的,在 Superset 連接中配置獨立參數。
結語
現在去跑一些 SQL,體驗 Spark SQL 帶來的性能飛躍吧!
參考鏈接:
①https://github.com/pan3793/cdh-hive/releases/tag/v2.1.1-cdh6.3.1-fix
②https://spark.apache.org/docs/latest/core-migration-guide.html
③https://spark.apache.org/docs/latest/sql-migration-guide.html
④https://kyuubi.readthedocs.io/en/latest/index.html
⑤https://kyuubi.apache.org/docs/latest/overview/architecture.html
⑥https://kyuubi.apache.org/docs/latest/overview/kyuubi_vs_hive.html
⑦https://kyuubi.apache.org/docs/latest/overview/kyuubi_vs_thriftserver.html
⑧https://kyuubi.apache.org/docs/latest/deployment/on_yarn.html
⑨https://kyuubi.apache.org/docs/latest/deployment/settings.html
⑩https://kyuubi.apache.org/docs/latest/deployment/spark/dynamic_allocation.html
⑪https://kyuubi.apache.org/docs/latest/deployment/spark/aqe.html
⑫https://kyuubi.apache.org/docs/latest/client/hive_jdbc.html
⑬https://kyuubi.apache.org/docs/latest/quick_start/quick_start_with_hue.html#for-cdh-6-x-users
潘成,來自 Apache Kyuubi 社區
贈書福利
