滴滴是如何從零構建集中式實時計算平臺的?

滴滴出行作爲一家出行領域的互聯網公司,其核心業務是一個實時在線服務。因此具有豐富的實時數據和實時計算場景。本文將介紹滴滴實時計算髮展之路以及平臺架構實踐。

01 實時計算演進

隨着滴滴業務的發展,滴滴的實時計算架構也在快速演變。到目前爲止大概經歷了三個階段,第一階段是業務方自建小集羣;第二階段是集中式大集羣、平臺化;第三階段是SQL化。圖1標識了其中重要的里程碑,下面給出詳細闡述。

image

在2017年以前滴滴並有沒有統一的實時計算平臺,而是各個業務方自建小集羣。其中用到的引擎有Storm、JStorm、Spark Streaming、Samza等。業務方自建小集羣模式存在如下弊端:

(1)需要預先採購大量機器,由於單個業務獨佔,資源利用率通常比較低;

(2)缺乏有效的監控報警體系;

(3)維護難度大,需要牽涉業務方大量精力來保障集羣的穩定性;

(4)缺乏有效技術支持,且各自沉澱的東西難以共享。

爲了有效解決以上問題,滴滴從2017年年初開始構建統一的實時計算集羣及平臺。技術選型上,我們基於滴滴現狀選擇了內部用以大規模數據清洗的Spark Streaming引擎,同時引入On-YARN模式。利用YARN的多租戶體系構建了認證、鑑權、資源隔離、計費等機制。相對於離線計算,實時計算任務對於穩定性有着更高的要求,爲此我們構建了兩層資源隔離體系。

第一層是基於CGroup做進程(Container)級別的CPU及內存隔離。第二層是物理機器級別的隔離。我們通過改造YARN的FairScheduler使其支持Node Label。達到的效果如圖2所示:普通業務的任務混跑在同一個Label機器上,而特殊業務的任務跑在專用Label的機器上。

image

通過集中式大集羣和平臺化建設,基本消除了業務方自建小集羣帶來的弊端,實時計算也進入了第二階段。伴隨着業務的發展,我們發現Spark Streaming的Micro Batch模式在一些低延時的報警業務及在線業務上顯得捉襟見肘。於是我們引入了基於Native Streaming模式的Flink作爲新一代實時計算引擎。Flink不僅延時可以做到毫秒級,而且提供了基於Process Time/Event Time豐富的窗口函數。基於Flink我們聯合業務方構架了滴滴流量最大的業務網關監控系統,並快速支持了諸如乘客位置變化通知、軌跡異常檢測等多個線上業務。

02 實時計算平臺架構

爲了最大程度方便業務方開發和管理流計算任務,我們構建瞭如圖3所示的實時計算平臺。在流計算引擎基礎上提供了StreamSQL IDE、監控報警、診斷體系、血緣關係、任務管控等能力。以下分別介紹各自的作用:

(1)StreamSQL IDE。下文會介紹,是一個Web化的SQL IDE;

(2)監控報警。提供任務級的存活、延時、流量等監控以及基於監控的報警能力;

(3)診斷體系。包括流量曲線、Checkpoint、GC、資源使用等曲線視圖,以及實時日誌檢索能力。

(4)血緣關係。我們在流計算引擎中內置了血緣上報能力,進而在平臺上呈現流任務與上下游的血緣關係;

(5)任務管控。實現了多租戶體系下任務提交、啓停、資產管理等能力。通過Web化任務提交消除了傳統客戶機模式,使得平臺入口完全可控,內置參數及版本優化得以快速上線。

image

03 實時規則匹配服務建設

在滴滴內部有大量的實時運營場景,比如“某城市乘客冒泡後10秒沒有下單”。針對這類檢測事件之間依賴關係的場景,用Fink的CEP是非常合適的。但是社區版本的CEP不支持描述語言,每個規則需要開發一個應用,同時不支持動態更新規則。爲了解決這些問題,滴滴做了大量功能擴展及優化工作。功能擴展方面主要改動有:

(1)支持wait算子。對於剛纔例子中的運營規則,社區版本是表達不了的。滴滴通過增加wait算子,實現了這類需求;

(2)支持DSL語言。基於Groovy和Aviator解析引擎,我們實現瞭如圖4所示的DSL描述規則能力。

image

(3)單任務多規則及規則動態更新。由於實時運營規則由一線運營同學來配置,所以規則數量,規則內容及規則生命週期會經常發生變化。這種情況每個規則一個應用是不太現實的。爲此我們開發了多規則模式且支持了動態更新。

除了功能拓展之外,爲了應對大規模運營規則的挑戰,滴滴在CEP性能上也做了大量優化,主要有:

(1)SharedBuffer重構。基於Flink MapState重構SharedBuffer,減少每次數據處理過程中的狀態交互。同時剝離規則和用戶數據極大降低每次匹配的時候從狀態中反序列化的數據量;

(2)增加訪問緩存(已貢獻社區)。緩存SharedBuffer數據中每次處理所需要更新的引用計數,延緩更新;

(3)簡化event time語義處理。避免key在很分散情況下每次watermark更新時要遍歷所有key的數據;

(4)複用conditionContext(已貢獻社區)。減少條件查詢時對partialMatch元素的反覆查詢。

以上優化將CEP性能提升了多個數量級。配合功能擴展,我們在滴滴內部提供瞭如圖5所示的服務模式。業務方只需要清洗數據並提供規則列表API即可具備負責規則的實時匹配能力。

image

目前滴滴CEP已經在快車個性化運營、實時異常工單檢測等業務上落地,取得了良好的效果。

04 StreamSQL建設

正如離線計算中Hive之於MapReduce一樣,流式SQL也是必然的發展趨勢。通過SQL化可以大幅度降低業務方開發流計算的難度,業務方不再需要學習Java/Scala,也不需要理解引擎執行細節及各類參數調優。爲此我們在2018年啓動了StreamSQL建設項目。我們在社區Flink SQL基礎上拓展了以下能力:

(1)擴展DDL語法。如圖6所示,打通了滴滴內部主流的消息隊列以及實時存儲系統。通過內置常見消息格式(如json、binlog、標準日誌)的解析能力,使得用戶可以輕鬆寫出DDL語法,並避免重複寫格式解析語句。

image

(2)拓展UDF。針對滴滴內部常見處理邏輯,內置了大量UDF,包括字符串處理、日期處理、Map對象處理、空間位置處理等。

(3)支持分流語法。單個輸入源多個輸出流在滴滴內部非常常見,爲此我們改造了Calcite使其支持分流語義。

(4)支持基於TTL的join語義。傳統的Window Join因爲存在window邊界數據突變情況,不能滿足滴滴內部的需求。爲此我們引入了TTL State,並基於此開發了基於TTL Join的雙流join以及維表join。

(5)StreamSQL IDE。前文提到平臺化之後我們沒有提供客戶機,而是通過Web提交和管控任務。因此我們也相應開發了StreamSQL IDE,實現Web上開發StreamSQL,同時提供了語法檢測、DEBUG、診斷等能力。

目前StreamSQL在滴滴已經成功落地,流計算開發成本得到大幅度降低。預期未來將承擔80%的流計算業務量。

05 總結

作爲一家出行領域的互聯網公司,滴滴對實時計算有天然的需求。過去的一年多時間裏,我們從零構建了集中式實時計算平臺,改變了業務方自建小集羣的局面。爲滿足低延時業務的需求,成功落地了Flink Streaming,並基於Flink構建了實時規則匹配(CEP)服務以及StreamSQL,使得流計算開發能力大幅度降低。未來將進一步拓展StreamSQL,並在批流統一、IoT、實時機器學習等領域探索和建設。

本文轉載自公衆號“滴滴技術“。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章