在近期的 Apache Kylin Meetup 深圳站上,我們邀請到騰訊的程廣旭與 T3 出行的楊華分享了 Kylin 在騰訊的應用。本次分享分為兩個部分,第一部分介紹了 Kylin 的平臺化改造實踐及改造後的預期效果,第二部分會介紹 Flink Cube Engine 的原理、使用方法及獨特優勢。
Kylin 平臺化實踐
首先,介紹下我們為什麼進行平臺化改造?
我們部門為公司內其他業務線提供了各種大數據平臺,如 Kylin、HBase、Spark、Flink 等等,提供公共統一的平臺系統勢必會牽扯到用戶管理、資源隔離、部門內各個平臺的融合等問題,而 Kylin 現有的用戶管理、資源隔離機制並不能滿足我們需求,基於此,我們對 Kylin 進行了平臺化改造。平臺化改造完成後,我希望在以下幾個方面,能夠有一些改進:
- 用戶管理
- 資源隔離
- 易用性提升
- 方便運維
1. 用戶管理
為了便於系統的管理及安全,公司內部有一套自己的認證系統,而且需要用個人賬號去驗證,所以 Kylin 作為一個平臺對外提供服務的話,也需要接入到該系統。所以,我們新增了一個用戶管理界面,該界面展示了 Kylin 平臺內的所有用戶。管理員可以新增任一用戶到 Kylin 平臺,新增用戶時會填寫企業微信名、用戶角色以及是否激活用戶。當用戶登錄系統時,會自動檢測用戶賬號以及該賬號是否在平臺內註冊,如果沒有註冊則無權限,反之自動登錄系統。
2. 內部 Hive 兼容
由於歷史原因,我們部門內的 Hive 版本(THive)與 Kylin 不兼容,這就導致 Kylin 無法正常訪問 Kylin 集群,所以我們採用了上圖所示的兼容方案。首先,我們使用社區 Hive 版本搭建一個全新的 Hive,並作為 Kylin 的默認 Hive;其次,當 kylin 加載源表時,我們是通過內部的 UPS 系統讀取 THive 的元數據信息;最後,在 Load 源表到 Kylin 時,我們根據表的元數據信息在 Kylin 的 Hive 上創建一張相同的表,但該表的存儲路徑依舊指向 THive 的路徑,而用戶在構建 cube 時,則訪問新創建的表,至此就解決了 Kylin 訪問 THive 的問題。
3. 計算資源可配置化
目前,Kylin 配置計算資源信息有兩種方式:一是在 Kylin 配置文件中配置一個全局的計算集群及隊列;二是在創建工程或者 Cube 時,在擴展參數中指定集群配置。這兩種配置方式在靈活性及便捷性方面都比較差,而在我們內部是有接口可以獲取到某一個用戶有計算資源的計算集群及計算隊列的,所以,在創建工程或者 Cube 時,我們使用了下拉框選擇式的方式,讓用戶選擇提交任務的計算資源及隊列,從而大大簡化了用戶的使用流程。
4. 通知機制
Kylin 只提供了發郵件通知的功能,而作為目前使用最廣泛的工具,微信、企業微信在實時性及便捷性方面都遠遠勝於郵件,所以,我們提供了郵件、微信、企業微信三種方式,供用戶選擇。
5. 定時調度
Kylin 系統自身並沒有提供定時調度功能,但基本上每家公司都有自己的統一調度平臺,我們也不例外。我們通過 Kylin 提供的API接口,將 Cube 定時構建的功能作為一個插件集成到了公司內部的統一調度平臺上。
6. 業務接入
做完以上平臺化改造後,Kylin 平臺基本具備了接入不同類型業務的能力,用戶申請接入流程如上圖所示。
業務使用情況:
我們團隊是在今年初才開始引入 Kylin,目前已經在使用的業務主要有 QQ 音樂、騰訊視頻、廣點通、財付通等,Cube 的數量有 10 個,單份數據存儲總量是 5 T,數據規模在 30 億條左右。
Flink Cube Engine 原理及實踐
目前,Kylin 已經支持使用 MapReduce 和 Spark 作為構建引擎,而作為目前比較火的流批一體的大數據計算引擎怎能缺席?所以我使用 Flink 開發了一個高性能的構建引擎:Flink Cube Engine。
Flink Cube Engine 是騰訊基於 Kylin 插件化的 Cube Engine 架構開發的一個高性能構建引擎,目前已具備了上線使用的能力,感興趣的同學可以體驗一下,目前該引擎已經在騰訊生產環境上線 1 個月+,非常穩定而且效果不錯。
Umbrella issue:
https://issues.apache.org/jira/browse/KYLIN-3758
分支:
https://github.com/apache/kylin/tree/engine-flink
1. 支持 Flink Engine 的子任務
Kylin 的一次 Cube 構建任務,包含了很多個子任務,而最重要的莫過於 Cube 構建這一步驟,所以,我們在 build 和 merge Cube 這兩種任務中,優先實現了Cube 構建這一步驟,其他計算步驟依舊通過使用 MapReduce 來實現。
2. 如何使用 Flink Cube Engine
選擇使用 Flink Cube Engine 的方式也和選擇 Map Reduce 和 Spark 任務類似,我們提供了前臺可視化的界面,供用戶選擇。
3. Flink Cube Engine 與 Spark (線上業務)
上圖是我們內部業務上線 Flink Cube Engine 之後的性能對比,從圖中可見,該步驟的構建耗時從 49 分鐘降到了 13 分鐘,優化效果比較明顯。兩種情況的資源配置如下:
Flink 配置為:
-ytm 4G -yjm 2G -ys 1 -p 100 -yn 100
Spark 採用的動態分配資源如下:
kylin.engine.spark-conf.spark.dynamicAllocation.enabled=true
kylin.engine.spark-conf.spark.dynamicAllocation.minExecutors=2
kylin.engine.spark-conf.spark.dynamicAllocation.maxExecutors=1000
kylin.engine.spark-conf.spark.dynamicAllocation.executorIdleTimeout=300
kylin.engine.spark-conf.spark.shuffle.service.enabled=true
kylin.engine.spark-conf.spark.shuffle.service.port=7337
雖然,Spark 採用的是動態分配資源,但在任務執行過程中,我們觀察到 Spark實際分配的資源遠比 Flink 要多的多。
那為什麼性能提升會那麼明顯呢?
4. Flink Cube Engine 的優化
性能的提升,無非有兩方面的原因,一是參數的優化,二是代碼的優化。
1) 調參
影響 Flink 任務性能主要有幾個核心參數:並行度、單個 TM slot 數目、TM container 數目,其中單個 TM container 數目=並行度/單個 TM slot 數目。
我們調優的過程採用了控制變量法,即:固定並行度不變、固定 Job 總內存數不變。通過不斷的調整單個 TM 的 slot 數目,我們發現如果單個 TM 的 slot 數目減少,拉起更多的 TM container 性能會更好。
此外,我們還使用了對象複用、內存預分配等方法,發現沒有對性能提升起到太大的效果。
2) 代碼優化(合併計算)
在實現 Flink Cube Engine 的時候,一開始我們使用了 Map/Reduce 兩個算子,發現性能很差,比 Spark 的性能還要差很多,後來我們通過調整使用了 Flink 的 mapPartition/reduceGroup 兩個算子,性能就有了明顯的提升。
Flink Cube Engine 下一步的計劃:
1. 全鏈路 Flink
如上所述,目前 Cube 構建過程中,只有最關鍵的 cube 構建這一子任務使用了 Flink,而其他子任務仍然使用的是 MapReduce,我們下一步會繼續完善 Flink Cube Engine,將所有的子任務都使用 Flink 來構建。
2. Flink 升級到 1.9
Flink 最近發佈了 1.9.0,該版本包含了很多重要特性且性能也有了一定提升,所以,我們會把 Flink Cube Engine 使用的 Flink 版本升級到1.9.0。
閱讀更多 大數據與機器學習 的文章