T3出行是一家基于車聯(lián)網驅動的智慧出行平臺,擁有海量且豐富的數(shù)據源。因為車聯(lián)網數(shù)據的多樣性,T3出行構建了以 Apache Hudi 為基礎的企業(yè)級數(shù)據湖,提供強有力的業(yè)務支撐。而對于負責數(shù)據價值挖掘的終端用戶而言,平臺的技術門檻是另一種挑戰(zhàn)。如果能將平臺的能力統(tǒng)合,并不斷地優(yōu)化和迭代,讓用戶能夠通過 JDBC 和 SQL 這種最普遍最通用的技術來使用,數(shù)據生產力將可以得到進一步的提升。T3出行選擇了基于網易數(shù)帆主導開源的 Apache Kyuubi(以下簡稱Kyuubi)來搭建這樣的能力。在2021 中國開源年會(COSCon'21)上,T3出行高級大數(shù)據工程師李心愷詳細解讀了選擇?Kyuubi 的原因,以及基于 Kyuubi 的深度實踐和實現(xiàn)的價值。
T3出行整個數(shù)據湖體系,由數(shù)據存儲與計算、數(shù)據查詢與分析和應用服務層組成。其中數(shù)據計算分為離線和實時。
數(shù)據存儲
OBS 對象存儲,格式化數(shù)據存儲格式以 Hudi 格式為主。
數(shù)據計算
離線數(shù)據處理:利用 Hive on Spark 批處理能力,在 Apache Dolphin?Scheduler 上定時調度,承擔所有的離線數(shù)倉的 ETL 和數(shù)據模型加工的工作。
實時數(shù)據處理:建設了以 Apache Flink ?引擎為基礎的開發(fā)平臺,開發(fā)部署實時作業(yè)。
數(shù)據查詢與分析
OLAP 層主要為面向管理和運營人員的報表,對接報表平臺,查詢要求低時延響應,需求多變快速響應。面向數(shù)據分析師的即席查詢,更是要求 OLAP 引擎能支持復雜 SQL 處理、從海量數(shù)據中快速甄選數(shù)據的能力。
應用服務層
數(shù)據應用層主要對接各個業(yè)務系統(tǒng)。離線 ETL 后的數(shù)據寫入不同業(yè)務不同數(shù)據庫中,面向下游提供服務。?
現(xiàn)有架構痛點
跨存儲
數(shù)據分布在 Hudi、ClickHouse、MongoDB 等不同存儲,需要寫代碼關聯(lián)分析增加數(shù)據處理門檻和成本。
SQL不統(tǒng)一
Hive 不支持通過 upsert、update、delete 等語法操作 Hudi 表,同時 MongoDB、ClickHouse 等語法又各不相同,開發(fā)轉換成本較高。
資源管控乏力
Hive on Spark、Spark ThriftServer 沒有較好的資源隔離方案,無法根據租戶權限做并發(fā)控制。
Apache Kyuubi 是一個 Thrift JDBC/ODBC 服務,對接了 Spark 引擎,支持多租戶和分布式的特性,可以滿足企業(yè)內諸如 ETL、BI 報表等多種大數(shù)據場景的應用。Kyuubi?可以為企業(yè)級數(shù)據湖探索提供標準化的接口,賦予用戶調動整個數(shù)據湖生態(tài)的數(shù)據的能力,使得用戶能夠像處理普通數(shù)據一樣處理大數(shù)據。項目已于2021年 6 月 21 號正式進入 Apache 孵化器。于T3出行而言,Kyuubi 的角色是一個面向 Serverless ?SQL on Lakehouse 的服務。
HiveServer 是一個廣泛應用的大數(shù)據組件。因傳統(tǒng)的 MR 引擎處理效率已經較為落后,Hive 引擎替換為了 Spark,但是為了和原本的 MR 及 TEZ 引擎共存,Hive 保留了自己的優(yōu)化器,這使得Hive Parse 性能在大多數(shù)場景下都落后于 Spark Parse。STS(Spark Thrift Server)支持HiveServer 的接口和協(xié)議,允許用戶直接使用 Hive 接口提交 SQL 作業(yè)。但是 STS 不支持多租戶,同時所有 Spark SQL 查詢都走唯一一個 Spark Thrift 節(jié)點上的同一個 Spark Driver,并發(fā)過高,并且任何故障都會導致這個唯一的 Spark Thrift 節(jié)點上的所有作業(yè)失敗,從而需要重啟 Spark Thrift Server,存在單點問題。對比 Apache Kyuubi 和 Hive、STS,我們發(fā)現(xiàn),Kyuubi 在租戶控制,任務資源隔離,引擎升級對接,性能等方面擁有諸多優(yōu)勢。詳情見下圖。
AD-HOC場景
Hue 整合 Kyuubi,替代 Hive 為分析師和大數(shù)據開發(fā)提供服務。我們在 hue_safety_valve.ini 配置文件中,增加如下配置:[notebook][[interpreters]][[[cuntom]]]name=Kyuubiinterface=hiveserver2[spark]sql_server_host=Kyuubi Server IPsql_server_port=Kyuubi Port
ETL場景
DS 配置 Kyuubi 數(shù)據源,進行離線 ETL 作業(yè)。因為 Kyuubi Server 的接口、協(xié)議都和 HiveServer2 完全一致,所以 DS 只需要數(shù)據源中 Hive 數(shù)據源類型配置為 Kyuubi 多數(shù)據源,就可以直接提交 SQL 任務。目前,Kyuubi 在T3出行支撐了80%的離線作業(yè),日作業(yè)量在1W+。
聯(lián)邦查詢場景
公司內部使用多種數(shù)據存儲系統(tǒng),這些不同的系統(tǒng)解決了對應的使用場景。除了傳統(tǒng)的 RDBMS (比如 MySQL) 之外,我們還使用 Apache Kafka 來獲取流和事件數(shù)據,還有 HBase、MongoDB,以及數(shù)據湖對象存儲和 Hudi 格式的數(shù)據源。我們知道,要將不同存儲來源的數(shù)據進行關聯(lián),我們需要對數(shù)據進行提取,并放到同一種存儲介質中,比如 HDFS,然后進行關聯(lián)操作。這種數(shù)據割裂,會給我們的數(shù)據關聯(lián)分析帶來很大的麻煩,如果我們能夠使用一種統(tǒng)一的查詢引擎分別查詢不同數(shù)據源的數(shù)據,然后直接進行關聯(lián)操作,這將帶來巨大的效率提升。所以,我們利用 Spark DatasourceV2 實現(xiàn)了統(tǒng)一語法的跨存儲聯(lián)邦查詢。其提供高效,統(tǒng)一的 SQL 訪問。這樣做的優(yōu)勢如下:
基于 Spark DatasourceV2 ,對于讀取程序,我們只需定義一個 DefaultSource 的類,實現(xiàn) ReadSupport 相關接口,就可以對接外部數(shù)據源,同時 SupportsPushDownFilters、SupportsPushDownRequiredColumns、SupportsReportPartitioning 等相關的優(yōu)化,實現(xiàn)了算子下推功能。由此我們可以將查詢規(guī)則下推到 JDBC 等數(shù)據源,在不同數(shù)據源層面上進行一些過濾,再將計算結果返回給 Spark,這樣可以減少數(shù)據的量,從而提高查詢效率。現(xiàn)有方案是通過建立外部表,利用 HiveMeta Server 管理外部數(shù)據源的元信息, 對表進行統(tǒng)一多權限管理。CREATE?EXTERNALTABLE?mongo_test
USING com.mongodb.spark.sql
OPTIONS (
spark.mongodb.input.uri "mongodb://用戶名:密碼@IP:PORT/庫名?authSource=admin",
spark.mongodb.input.database "庫名",
spark.mongodb.input.collection "表名",
spark.mongodb.input.readPreference.name?"secondaryPreferred",
spark.mongodb.input.batchSize "20000"
);
后續(xù)升級 Spark3.X ,引入了 namespace 的概念后,DatasouceV2 可實現(xiàn)插件形式的Multiple Catalog 模式,這將大大提高聯(lián)邦查詢的靈活度。我們基于 TPC-DS 生成了 500GB 數(shù)據量進行了測試。選用部分事實表和維度表,分別在 Hive 和 Kyuubi 上進行性能壓測。主要關注場景有:
單用戶和多用戶場景
聚合函數(shù)性能對比
Join 性能對比
單 stage 和多 stage 性能對比
壓測結果對比,Kyuubi 基于 Spark 引擎大多數(shù)場景比 Hive 性能提升了3-6倍,同時多租戶、并發(fā)的場景更加高效穩(wěn)定。
我們對 Kyuubi 的改進和優(yōu)化主要包括如下幾個方面:Kyuubi Web:啟動一個獨立多 web 服務,監(jiān)控管理 Kyuubi Server。?
Kyuubi EventBus:定義了一個全局的事件總線。
Kyuubi Router:路由模塊,可以將專有語法的 SQL 請求轉發(fā)到不同的原生 JDBC 服務上。
Kyuubi Spark Engine:修改原生 Spark Engine。
Kyuubi Lineage:數(shù)據血緣解析服務,將執(zhí)行成功多 SQL 解析存入圖數(shù)據庫,提供 API 調用。
Kyuubi Web 服務功能
當前運行的 SparkContext 和 SQL 數(shù)量
各個 Kyuubi Server 實例狀態(tài)
Top 20: 1天內最耗時的 SQL
用戶提交 SQL 排名(1天內)
展示各用戶 SQL 運行的情況和具體語句
SQL 狀態(tài)分為:closed,cancelled,waiting和running。其中waiting和running 的 SQL 可取消
根據管理租戶引擎對應隊列和資源配置、并發(fā)量
可以在線查看、修改 Kyuubi Server、Engine 相關配置
Kyuubi EventBus
Server 端引入了 RESTful Service。在Server應用進程中,事件總線監(jiān)聽了包括應用停止時間、JDBC 會話關閉、JDBC 操作取消等事件。引入事件總線的目的,是為了在單個應用中和不同的子服務間進行通信。否則不同的子服務對象需要包含對方的實例依賴,服務對象的模型會非常復雜。Kyuubi Router
增加了 Kyuubi JDBC Route 模塊,JDBC 連接會先打向此服務。該服務根據既定策略轉發(fā)到不同服務。下圖為具體策略。
Kyuubi Spark Engine
將 Kyuubi-Spark-Sql-Engine 的 Spark 3.X 版本改成了 Spark 2.4.5,適配集群版本,后續(xù)集群升級會跟上社區(qū)版本融合
增加了Hudi datasource 模塊,使用 Spark datasource 計劃查詢 Hudi,提高對 Hudi 的查詢效率
集成 Hudi 社區(qū)的 update、delete 語法,新增了 upsert 語法和 Hudi 建表語句

Kyuubi Lineage
基于 ANTLR 的 SQL 血緣解析功能。現(xiàn)有提供了兩個模式,一個是定時調度,解析一定時間范圍內的執(zhí)行成功的 SQL 語句,將解析結果存儲到 HugeGraph 圖庫中,用于數(shù)據治理系統(tǒng)等調用。另一個模式為提供 API 調用,查詢時用戶直接調用,SQL 復雜時可以直觀理清自己的 SQL 邏輯,方便修改和優(yōu)化自己的 SQL。
T3出行大數(shù)據平臺基于 Apache Kyuubi 0.8,實現(xiàn)了數(shù)據服務統(tǒng)一化,大大簡化了離線數(shù)據處理鏈路,同時也能保障查詢時延要求,之后我們將用來提升更多業(yè)務場景的數(shù)據服務和查詢能力。最后,感謝 Apache Kyuubi 社區(qū)的相關支持。后續(xù)計劃升級到社區(qū)的新版本跟社區(qū)保持同步,同時基于T3出行場景做的一些功能點,也會陸續(xù)回饋給社區(qū),共同發(fā)展。也期望 Apache kyuubi 作為 Serverless SQL on Lakehouse 引領者越來越好!https://kyuubi.apache.org/
https://github.com/apache/incubator-kyuubi