Kyuubi 在小米大數據平臺的應用實踐
分享嘉賓:張耀東 小米 高級研發工程師
出品平臺:DataFunTalk
導讀: 今天分享的主題是《Kyuubi 在小米大數據平臺的應用實踐》,主要分爲四部分內容:
-
Kyuubi 在小米的落地過程
-
打造易用和高可用的 Kyuubi 服務
-
基於 kyuubi 的改進
-
kyuubi 的一些新特性在業務場景的應用
01 Kyuubi 在小米的落地過程
第一個主題:關於 Kyuubi 在小米的大數據平臺落地過程和實施路徑的分享。
1. 背景介紹
先介紹一下背景,小米的大數據體系在不斷更新和迭代,隨着業務架構、組織架構和技術架構的調整,內部大數據平臺逐漸出現一些狀況:
-
出現了多個基於 SQL 的大數據平臺服務,服務於各個業務部門,各自定位又有一定的差異,這樣就給用戶帶來了困擾,到底選擇哪個平臺好,而且我們在用戶支持的過程中發現,同一業務可能需要跨多個數據服務平臺,流程繁瑣。
-
對於底層表資源的使用存在多套賬號和權限體系:
a. MySQL/Doris: 系統的自有的 User&Password 認證和權限體系
b. Hive/Kudu 基於 Kerberos 認證和 Sentry 的權限體系
c. Talos 是基於小米內部平臺組織和團隊的認證與授權體系
- 給用戶使用和管理上帶來了麻煩,沒有統一的資源管理和權限管理視角,並且底層系統服務賬號會直接暴露給用戶,還會存在安全風險。
2. 構建一站式的大數據開發平臺
上述現象直接導致瞭如下問題:
①對用戶:
-
多個平臺和多體系給用戶體驗較差,開發數據流程長,不能快速上手。
-
開發管理效率成本高,資源成本結算和任務管理沒有統一的視圖。
②對平臺:
-
各自的側重點不同,都不能完全覆蓋大數據場景下的能力需求,同時還有能力重複建設問題,導致資源浪費。
-
出現問題排查和維護困難,需要堆人力解決。
面對數據平臺難用的情況,提出了構建統一易用的大數據服務平臺整體目標。整體架構能力圍繞數據鏈路解決方案、數倉解決方案、數據服務解決方案來進行建設,提供統一的元數據管理和權限管理體系。
在這個大背景和動機下,統一的數據入口服務成爲了一個非常重要的能力,它主要解決:
-
用戶的易用性(一致的入口體驗)
-
SQL 流量治理(代理多引擎)
-
數據訪問的安全性管控(入口收斂和降低安全風險)
3. 小米 SQL 服務歷史發展情況
從上面的背景問題中可以看到,小米內部有幾套大數據處理的 SQL 服務入口,總體還是圍繞經典的 SQL On Hadoop 架構體系來構建,逐步從 ThriftServer 演進到向上抽象一層的 SQL Proxy 服務,在底層集成了 Hive/Spark/Doris 等引擎爲 ETL 作業、Ad-Hoc 查詢提供支持。
抽離的 SparkThriftServer 的實現模塊作爲獨立的 SQL Proxy 服務,提供:
-
ETL 場景下的 HiveServer 和 Spark APP 代理(非常駐)
-
Ad-Hoc 場景下的 STS、Kylin、Druid 代理
從這裏可以看到 SQL Proxy 和 Kyuubi Server 的定位非常相似,但是存在很多不足:
a. SQL Proxy 沒有完全剝離 STS 的實現,通過反射的方式進行復用,代碼耦合很高,依賴 Spark 特定版本,升級困難
b. 底層引擎代理層沒有統一抽象,與其他引擎適配困難,對底層引擎擴展性差
c. 無法本地調試,依賴 hadoop 配置,在辦公和服務環境網絡隔離情況下,必須在開發機上完成完整的功能測試和調試,開發和部署路徑長
4. 基於 Kyuubi 構建統一 SQL 入口
(1) 爲什麼選擇 Kyuubi
通過上面的分析,我們發現在業務和架構上都存在着一些問題需要解決。
① 業務上:
-
在重新打造統一的大數據體系的推動下,構建統一的 SQL 入口服務勢在必行。
-
需要更快的分析引擎,這裏我們選擇了 Trino。
-
一套易用、高可用並可以持續演進的服務架構,提升大數據研發的生產力。
SQLProxy 架構需要升級:
-
完全兼容 HiveThrift 協議。
-
松耦合的實現,基於 STS 實現的完全剝離。
-
靈活可擴展的代理多引擎的適配。
Kyuubi 的優勢在於:
-
與 STS 和 HS2 的完全兼容一致
-
高可用和資源隔離
-
清晰簡潔的架構,可測試、可維護、可擴展
-
社區高質量實現和業界生產環境大量運用
SQLProxy 和 Kyuubi 的架構非常相似,切換成本低。在業務需求和架構升級的雙重推動下,我們選擇了 Kyuubi。
(2)架構升級
升級過程和效果與我們的預期一致,可以看到架構相比 SQLProxy 更加簡潔,擴展底層引擎非常容易,而且本地可測試可調試,極大提升了開發效率。從開發到上線新架構兩週時間就完成了平滑遷移。
升級新架構帶來的效果也非常明顯,相比之前的架構不論代碼質量、服務穩定性、可維護性和可擴展性上都有了重大提升:
-
多引擎的代理能力(主要支持 Spark/Trino/Hive/Doris)。
-
基於數據平臺 workspace 的體系在 Kyuubi Server 端實現了權限驗證和資源隔離。
-
更加規範化的 Hive Thrift API 支持,各種生態可視化工具(Redash/Datagrip 等)完美兼容。
(3) 統一 SQL 服務的現狀
經過半年的遷移推動,每日 SQL 有效處理量從 5W 提升到現在的 50W 規模,已經佔據了整個 SQL 流量的 80%。特別是 SparkSQL 的流量半年新增到 30W。大體流量分佈:Spark 36w/ Trino 12w / Hive 2.5w
各個引擎請求耗時:
-
Spark 和 Trino 持平,平均延時 30 秒左右,P50 在 5 秒左右
-
Hive 的執行效率明顯低於以上兩個引擎,跟 Hive 的大任務有關,ETL 偏多
目前 Kyuubi Server 承載真實的 SQL 流量日均 100w 左右,可用性仍然可達 99.9% 以上,非常穩定。
02 打造易用易維護高可用的 Kyuubi 服務
1. 構建符合業務需求的 Kyuubi
(1) 整體架構
整體架構和流程,主要分爲入口服務、認證和權限適配、底層引擎管理及服務的可觀測性:
-
Kyuubi Server 爲基礎構建了 SQL 統一入口服務
-
Kyuubi Engine 作爲 Spark SQL 執行引擎層
-
獨立 Engine Manager 服務管理各類計算引擎
-
Kyuubi Server 層集成 Ranger 服務,支持基於數據平臺的統一權限驗證
-
擴展適配 Trino/Hive/Doris 引擎服務指標和審計日誌的可視化
(2) 用戶使用交互
以工作空間(workspace)粒度來保計算資源的隔離的存儲資源(表)安全,與 Kyuubi Group 的多租戶類似,我們這裏擴展到了其他引擎。
一次完成交互過程:
WorkspaceA 下面的用戶使用平臺發放的 Token,選擇各類客戶端工具,向引擎提交 SQL 查詢,Kyuubi Server 會自動將用戶 SQL 提交到該空間所屬的計算引擎上去,來保證用戶使用資源的隔離性。與其他 workspace 用戶雖是同一入口,但是資源的使用上是隔離的。
Kyuubi Server 服務並不具體執行 SQL,同一的入口服務不會有太大壓力。
2. 提升用戶側的易用性
(1) 統一認證和表座標的統一
去 Kerberos 化,採用平臺統一 Token 方式,解決:
-
Kerberos 接入流程繁瑣
-
普通用戶對 kerberos 機制難以理解,出現問題排查困難
-
用戶管理不當,同一賬號下用戶膨脹問題
-
審計和追蹤不能精確定位到用戶個人
表資源命名的統一規範化,小米內部存在多區域和多類數據源,如果使用統一的 SQL 入口服務,需要統一 SQL 語句的表名規範來避免衝突和統一的管理:
-
採用 Catalog.Schema.Table 三級表名爲唯一表名
-
Kyuubi Server 端支持 JDBC URL 預設 Catalog/Schema,兼容之前 SQL 中二級或者一級表名
-
結合 URL 和 SQL Table 生成完整的三級表座標,以供用戶權限認證
(2) Kyuubi Engine 公共資源池
引入 Kyuubi Engine 公共池主要解決用戶首次進入空間提交 SparkSQL 的查詢性能問題。上面提到的用戶提交的 SQL 分析統計,50% 的 SQL 查詢延時都在 5 秒以下。在沒有提前分配的資源的情況下,用戶提交查詢會冷啓動一個 Kyuubi Engine,這是 Kyuubi 當前的機制。由於小米 Yarn 提交一個 APP 的延時在分鐘級別,用戶一個簡單的秒級查詢會延遲到分鐘級別,體感非常差。
因此,藉助 Kyuubi Engine Pool 的實現,對沒有提前配置和指定資源的 workspace 用戶,會將 SQL 路由到已經預先啓動好的 Kyuubi Engine Pool,以加快用戶的查詢速度,提升 SQL 查詢體驗。
3. 升級 Spark2.X 到 Kyuubi Engine
Kyuubi Engine 目前只支持 Spark3 以上,之前我們內部版本都是 Spark2,在升級到 Kyuubi Engine 之前做了相關對比測試,在 Kyuubi 架構和 SQLProxy 架構下,有明顯的性能提升:
-
在 TPC-DS 標準測試集上,P50 延時有 75% 的性能提升,長尾基本和 SQLProxy 性能持平。
-
在真實的業務場景下,P50 延時也有 37% 的性能提升,長尾也基本跟 SQLProxy 一致,也就是升級的 Kyuubi Engine 的性能在多數情況下要優於 Spark2,整體上不會比 Spark2 更差。
4. Kyuubi Server 的容器化
在 Kyuubi Server 的高可用上利用容器化的方式替換了當前 Kyuubi Client 端通過 ZK 進行服務發現的高可用模式:
-
在 K8s 上部署 Kyuubi Server 服務,充分利用 K8s 的彈性能力保障高可用。
-
Kyuubi Server 和 Kyuubi Engine 的部署徹底解耦,作爲一個單獨的 Thrift RPC 代理服務和 HTTP 服務,去除 Hadoop 相關的配置環境依賴,和普通業務服務一樣使用 LVS 做流量負載均衡。
-
同時藉助內部 K8s 平臺的 CI/CD 能力,實現了 Kyuubi Server 服務的全自動灰度發佈,支持一鍵升級和擴縮容。
5. 基於 Workspace 的計算資源管理
(1)Engine Manager
由於之前已經實現了對 Spark Engine 的管理服務,我們將 Kyuubi Engine 的管理直接從 Kyuubi Server 剝離,形成了單獨的 Engine Manager 服務,負責 Engine 的生命週期管理,配置上下文管理,同時提供服務發現和負載均衡能力。
-
爲管理入口提供引擎配置和生命週期管理。
-
爲 Kyuubi Server 提供 SQL 路由的能力。
-
爲運維提供可視化的監控能力,包括 Engine 的服務狀態、資源佔用以及繁忙程度等,便於快速運維。
用戶提交的 SQL 的流程:
-
首先經過 Kyuubi Server 入口的認證和權限驗證。
-
Kyuubi Server 向 EngineManager 可用的 Kyuubi Engine 地址。
-
EngineManager 向 ZK 獲取當前用戶空間下可用的 Engine,然後統計當前可用 Engine 的繁忙指標,返回相對空閒的 Engine 給 Kyuubi Server。
-
Kyuubi Server 將 SQL 提交到 EngineManager 建議的 Engine 上去執行。
(2) 用戶提交
圖上是我們的用戶平臺 SQL 查詢入口,在 workspace 下的用戶可以非常方便地啓動一個 Kyuubi Engine。爲降低用戶的門檻,只暴露了資源相關和排隊策略的配置。同時,用戶還可以配置多個 Kyuubi Engine 實例,來保障當前 workspace 下的 SQL 執行的高可用。
(3) Engine 的高可用
爲什麼需要 Kyuubi Engine 的高可用?因爲在實際環境中,Kyuubi Engine 是一直長時間運行的,Spark 的 SQL 執行過程非常複雜,時間一長其穩定性就有了問題:
-
開啓動態資源策略後丟事件的 Bug,導致資源無法釋放。
-
大任務佔用時間長,可能阻塞一些小任務的運行。
-
Driver 端 JVM Full GC 時間過長和 OOM。
-
SQL 不合理導致的 Engine 頻繁重啓。
因此實施了一些高可用的保障策略:
-
workspace 級別隔離 Engine 異常,避免影響其他用戶。
-
觀測 Engine 可用指標,通過繁忙和探活信息標記是否當前可用。
-
同一 workspace 下多個 Engine 實例(Kyuubi 的 Engine Pool 機制),提升整體可用性,同時提供基於負載的分發。
-
發現異常及時自動重啓。
-
頻繁重啓 Engine 通過告警機制,人工及時介入。
03 基於 Kyuubi 的改造
1. Trino 和 Doris 的代理
引入 Trino 和 Doris 主要解決 OLAP 場景的查詢效率問題。
-
Kyuubi 在 1.1.0 版本還未支持 Trino,我們在 kyuubi Server 端使用 Trino-JDBC 完成了對 Trino 引擎的適配。
-
Trino-JDBC 實現了流迭代器的模式,每次 nextResult 都會觸發一次對 Trino 引擎的請求。
-
當前社區 Trino-Client 實現,會一次性的拉取所有結果集可能導致 OOM 的風險。
對於 Doris 的適配也採用了 JDBC 的方式,由於 Doris 客戶端本身支持 Mysql JDBC,MySQL JDBC 的實現方式是全量拉取模式,Kyuubi Server 端有 OOM 的風險。目前通過限制 Doris 查詢的超時時間來降低大結果集導致 OOM 的風險。
如果大家後面要擴展 Kyuubi 代理其他 JDBC 的數據庫支持,一定謹慎處理。
2. SQL HTTP API 的支持
關於 HTTP API 的支持一共實現了 V1 版本和 V2 版本,相比社區還是有一些區別。
① V1 版本
-
簡化用戶的交互過程,簡化 Hive Thrift RPC 的調用流程,用戶直接在上層應用程序中通過 HTTP 請求就能提交 SQL,對一些研發用戶來說是非常友好的。提交 SQL 根據 QueryID,不斷輪詢獲取結果。
-
複用了 Thrift backend Service 的實現,水平擴展了一層 HTTP Fronted Service。底層實現跟 Thrift API 完全保持一致。
但是也存在一些問題:
-
Kyuubi Service 端是有 Session 狀態的,Step1 和 Step2 必須路由的同一個實例才能獲取到結果,採用 IP Hash 不能完全解決。
-
這樣也導致 Kyuubi Server HTTP 服務無法水平擴展和平滑升級。
②V2 版本
爲了徹底解決 V1 的水平擴展性問題,在 V2 版本中將 Kyuubi HTTP Server 完全無狀態化,通過 Kyuubi Engine 直接提供 HTTP SQL API。Kyuubi Server 只起到出代理的作用。
另外的兩點改進:
-
徹底解決大結果集的導致 Kyuubi Engine OOM 的問題,將查詢類的結果直接持久化到 HDFS,不經過 Spark Driver 端。
-
用戶在獲取結果的時候不經過 Kyuubi Engine,直接從 HDFS 層流式獲取結果集。
同時,也不用維持長鏈接,非常適合 ETL 的場景。
3. SQL 表列解析
我們在 Kyuubi Server 端做了權限認證,需要獲取用戶 SQL 的真實表名,單獨開發了一個純 SQL 的解析模塊:支持表列血緣關係和 SQL 類型的提取,支持 SparkSQL、Trino 兩種語法。
具體解析後的格式如圖,包括類型、輸入輸出表和隊列的列。
後續在具體實際場景中該模塊的也應用到了其業務場景,比如表血緣審計日誌,SQL 的統計請求分析等安全質量場景,完全複用了我們的 SQL 表列提取的能力。
04 Kyuubi 新特性的應用
1. 小文件合併
解決用戶寫場景可能導致的小文件過多的問題。用戶一般會提交兩個 SQL:一個是業務處理 SQL,一個是合併 SQL,通過通過 workflow 方式串聯起來,維護不變。
開啓也非常簡單,可以在 Kyuubi Engine 啓動階段,SQL 提交階段開啓開關。
2. 增量獲取和獲取結果集限制
-
主要是 JDBC 下用戶有結果集的查詢導致的 OOM 問題,開啓增量模式。但有些場景下會有部分分區的結果太大,導致取結果過程阻塞,導致有不好的用戶體驗。推薦採用 HTTP API 異步結果獲取方式解決。
-
對用戶一些預覽數據的 SQL,如果訪問的表非常大,限制查詢條數輸出是一個非常好的功能,避免不必要的開銷
3. Z-Ordering
在我們內部畫像場景做相關的測試,Z-Ordering 有顯著的提升。
-
業務查詢時間
-
存儲空間
-
查詢掃描數據量
-
文件數量
在具體應用中,Z-Ordering 的排序規則需要根據實際業務表的數據做相應調整:
-
我們畫像場景查詢頻次高的列進行排序,效果明顯
-
超過 3 個列後的優化並不理想
-
排序列應選擇基數較大且沒有傾斜的列
Kyuubi Engine Z-Ordering 的實現非常巧妙,沒有增加額外的列,直接複用了 parquet 的原生能力,所以一次生成可以支持多個引擎查詢(只要該引擎支持 parequet 格式的讀取)。
4. PlanOnly 模式
主要用於非 SQL 執行的 SQL 相關場景,比如:
-
爲數據平臺提供語法語義校驗服務
-
SQL 提交前的檢查
-
SQL 語法語義兼容性的檢查(Spark2.X->Spark3.X 的升級)
PlanOnly 模式下 SQL 不會真正執行,只會輸出解析後的 LogicalPlan/SparkPlan。目前爲數據平臺單獨提供了語法語義校驗服務,就是採用 Kyuubi Engine 的 PlanOnly 模式。
這種應用場景也爲我們提供了一種新思路:將 Kyuubi Engine 作爲 Yarn APP 的服務框架,提供其他場景的服務,比如校驗服務、血緣關係提取服務和 SQL 的預計算服務等。
5. Scala mode
Scala Code 模式完全解放了 Kyuubi Engine 能力,具備直接通過 JDBC 提交 Scala 代碼的能力,專門處理一些複雜邏輯的業務。
目前我們的應用場景在運維這塊做了一些嘗試,主要解決我們的運維效率。例如我們要在運行時動態加載用戶自定義的 jar 包,讀取 Thrift 格式化的數據。相比之前登錄到生產集羣機器打包代碼運行的流程大大簡化。
05 未來規劃和總結
規劃:
-
基於業務場景、SQL 規則和執行代價事前預測,實現多引擎下的自動路由能力。
-
HTTP API 代替 Thrift API 提交的 ETL 作業,異步化取代長連接的方式。
總結:
-
Kyuubi 是非常優秀開源實踐,已經成爲小米內部大 數據服務入口的重要基礎架構服務 。
-
非常感謝 Kyuubi 的社區的貢獻,加速了我們統一 SQL 服務的落地 。
-
相信未來 Kyuubi 會成爲大數據場景下的 SQL Gateway 標杆,與大家一起共建 Kyuubi 生態 。
今天的分享就到這裏,謝謝大家。
分享嘉賓
關於我們
DataFun: 專注於大數據、人工智能技術應用的分享與交流。發起於 2017 年,在北京、上海、深圳、杭州等城市舉辦超過 100 + 線下和 100 + 線上沙龍、論壇及峯會,已邀請超過 2000 位專家和學者參與分享。其公衆號 DataFunTalk 累計生產原創文章 700+,百萬 + 閱讀,14 萬 + 精準粉絲。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/m5OzwkBrEBcyRcCxIJesvA