Apache Flink在滴滴的應(yīng)用與實踐
分享嘉賓:梁李印 滴滴出行 高級技術(shù)專家
出品平臺:DataFunTalk
導(dǎo)讀:Apache Flink 是一個分布式大數(shù)據(jù)處理引擎,可對有限數(shù)據(jù)流和無限數(shù)據(jù)流進(jìn)行有狀態(tài)計算。可部署在各種集群環(huán)境,對各種大小的數(shù)據(jù)規(guī)模進(jìn)行快速計算。
滴滴基于 Apache Flink 做了大量的優(yōu)化,也增加了更多的功能,比如擴(kuò)展 DDL、內(nèi)置消息格式解析、擴(kuò)展 UDX 等,使得 Flink 能夠在滴滴的業(yè)務(wù)場景中發(fā)揮更大的作用。本文中,滴滴出行實時計算負(fù)責(zé)人、高級技術(shù)專家梁李印分享了 Apache Flink 在滴滴的應(yīng)用與實踐。
主要內(nèi)容包括:
-
服務(wù)化概述
-
StreamSQL 實踐
-
平臺化建設(shè)
-
挑戰(zhàn)及規(guī)則
1. 滴滴大數(shù)據(jù)服務(wù)架構(gòu)
滴滴基于開源的生態(tài)構(gòu)建了比較完整的大數(shù)據(jù)體系,包括離線、實時系統(tǒng),如 HBase 生態(tài)、數(shù)據(jù)檢索 Elastic Search、消息隊列 Kafka 等。在 Flink 基礎(chǔ)上滴滴主要發(fā)展 StreamSQL,之后會有詳細(xì)介紹。
2. 滴滴流計算發(fā)展歷程
在2017年之前,滴滴流計算主要依靠業(yè)務(wù)方自建小集群的方式,技術(shù)選型也多種多樣,包括 Storm、jstrom、Spark、Samza 等。2017年開始進(jìn)行業(yè)務(wù)收斂,保留了8個 Spark Streaming 并構(gòu)建了一個平臺化、服務(wù)化的大集群,并且引入了 Flink。引入 Flink 的原因是部分業(yè)務(wù)對實時性要求較高,Spark Streaming 無法支持。2018年滴滴構(gòu)建了基于 Flink SQL 的名為 StreamSQL 的 SQL 化服務(wù),并且使用 Flink CEP 解決了一些網(wǎng)約車實時運營問題。2019年,滴滴完成了流計算引擎的統(tǒng)一,絕大部分任務(wù)以 Flink 為基礎(chǔ),通過 StreamSQL 開發(fā)流計算任務(wù)成為主流開發(fā)方式,達(dá)到了50%以上。
3. 滴滴流計算業(yè)務(wù)規(guī)模和場景
在業(yè)務(wù)規(guī)模方面,目前滴滴流計算服務(wù)業(yè)務(wù)線達(dá)到50多個,集群規(guī)模在千級別,流計算任務(wù)數(shù)達(dá)到3000+,每天處理的數(shù)據(jù)量達(dá)到萬億條。
在業(yè)務(wù)場景上,主要包括以下四類:
實時監(jiān)控:實時監(jiān)控包括交易指標(biāo)監(jiān)控、導(dǎo)航及 POI 準(zhǔn)確率監(jiān)控、業(yè)務(wù)健康度監(jiān)控 ( 例如業(yè)務(wù)壓測中的水位線、當(dāng)前水位同水位線的實時差距監(jiān)控 ) 和車輛網(wǎng)監(jiān)控等。
實時同步:實時同步主要作用是把數(shù)據(jù)實時地從一個地方轉(zhuǎn)移到另一個地方,數(shù)據(jù)包括業(yè)務(wù)日志、數(shù)據(jù)庫日志、軌跡數(shù)據(jù)、埋點數(shù)據(jù)。軌跡數(shù)據(jù)放在 HBase。
實時特征:實時特征是比較關(guān)鍵的業(yè)務(wù),它會影響派單,例如派單的導(dǎo)航和準(zhǔn)確性。這些特征包括司機(jī)乘客特征、上下車特征、導(dǎo)航軌跡特征、工單特征。滴滴每天的客戶量在百萬級別,如果檢測到高危,需要立刻觸發(fā)報警和客服介入。
實時業(yè)務(wù):實時業(yè)務(wù)會影響業(yè)務(wù)行為,包括司乘位置語義同步 ( 接單過程中司機(jī)可以實時知道乘客位置變化、乘客也可以知道司機(jī)位置變化 )、異常停留監(jiān)測、高危行程監(jiān)測、個性化發(fā)券、路線偏移監(jiān)測等。
4. 滴滴流計算多集群體系
滴滴隨著業(yè)務(wù)發(fā)展機(jī)房越來越多,為了更好地管理,對業(yè)務(wù)提供統(tǒng)一視圖,滴滴在集群體系做了三方面的改進(jìn)。
-
在 YARN 的基礎(chǔ)上構(gòu)建了路由層。路由層的職責(zé)是屏蔽多個物理集群,對業(yè)務(wù)方提供單一的邏輯集群。通過 YARN 上 queue 的劃分來決定業(yè)務(wù)運行在機(jī)房的不同集群上。
-
在物理集群內(nèi)部劃分 label,通過 label 可以進(jìn)行隔離,專門服務(wù)那些重要的不希望受到其他業(yè)務(wù)影響的業(yè)務(wù)。
-
同時定制了 YARN 調(diào)度器。由于實時和離線業(yè)務(wù)調(diào)度差異較大,所以兩類業(yè)務(wù)調(diào)度完全分開。對于離線業(yè)務(wù),希望盡可能把機(jī)器資源全部應(yīng)用起來,吞吐越大越好。而實時業(yè)務(wù)對均衡性要求更高,所以將調(diào)度改為基于 CPU 調(diào)度,并且可以智能過濾繁忙節(jié)點 ( 如 CPU 使用較高的節(jié)點 ),也做了動態(tài)資源推薦,并將推薦值告知用戶。
1. StreamSQL 的優(yōu)勢
StreamSQL 是在 Flink SQL 基礎(chǔ)上做一些完善后形成的一個產(chǎn)品。使用 StreamSQL 具有多個優(yōu)勢:
-
描述性語言:業(yè)務(wù)方不需要關(guān)心底層實現(xiàn),只需要將業(yè)務(wù)邏輯描述出來即可。
-
接口穩(wěn)定:Flink 版本迭代過程中只要 SQL 語法不發(fā)生變化就非常穩(wěn)定。
-
問題易排查:邏輯性較強(qiáng),用戶能看懂語法即可調(diào)查出錯位置。
-
批流一體化:批處理主要是 HiveSQL 和 Spark SQL,如果 Flink 任務(wù)也使用 SQL 的話,批處理任務(wù)和流處理任務(wù)在語法等方面可以進(jìn)行共享,最終實現(xiàn)一體化的效果。
-
入門門檻低:StreamSQL 的學(xué)習(xí)入門的門檻比較低,因此受到了廣大開發(fā)者的歡迎。
2. StreamSQL 相對于 Flink SQL 的完善
完善 DDL:
包括上游的消息隊列、下游的消息隊列和各種存儲如 Druid、HBase 都進(jìn)行了打通,用戶方只需要構(gòu)建一個 source 就可以將上游或者下游描述出來。
內(nèi)置消息格式解析:
用戶消費數(shù)據(jù)后需要將數(shù)據(jù)進(jìn)行提取,但數(shù)據(jù)格式往往非常復(fù)雜,如數(shù)據(jù)庫日志 binlog,每個用戶單獨實現(xiàn),難度較大。StreamSQL 將提取庫名、表名、提取列等函數(shù)內(nèi)置,用戶只需創(chuàng)建 binlog 類型 source。并內(nèi)置了去重能力。
對于 business log 業(yè)務(wù)日志 StreamSQL 內(nèi)置了提取日志頭,提取業(yè)務(wù)字段并組裝成 Map 的功能。對于 json 數(shù)據(jù),用戶無需自定義 UDF,只需通過 jsonPath 指定所需字段。
擴(kuò)展 UDX:
豐富內(nèi)置 UDX,如對 JSON、MAP 進(jìn)行了擴(kuò)展,這些在滴滴業(yè)務(wù)使用場景中較多。支持自定義 UDX,用戶自定義 UDF 并使用 jar 包即可。兼容 Hive UDX,例如用戶原來是一個 Hive SQL 任務(wù),則轉(zhuǎn)換成實時任務(wù)不需要較多改動,有助于批流一體化。
Join 能力:
① 基于 TTL 的雙流 join:
在滴滴的流計算業(yè)務(wù)中有的 join 操作數(shù)據(jù)對應(yīng)的跨度比較長,例如順風(fēng)車業(yè)務(wù)發(fā)單到接單的時間跨度可能達(dá)到一個星期左右,如果這些數(shù)據(jù)的 join 基于內(nèi)存操作并不可行,通常將 join 數(shù)據(jù)放在狀態(tài)中,窗口通過 TTL 實現(xiàn),過期自動清理。
② 維表 join 能力:
維表支持 HBase、KVStore、Mysql 等,同時支持 inner、left、right、full join 等多種方式。
1. StreamSQL IDE
滴滴對于 StreamSQL 構(gòu)建了 StreamSQL IDE,除了基本的 StreamSQL editor 外,還主要包含多個其他功能:
-
SQL 模板:如果用戶想要開發(fā)流式 SQL 時不需要從零開始,只需要選擇一個 SQL 模板,并在這個模板之上進(jìn)行修修改改即可達(dá)到期望的結(jié)果。
-
UDF 函數(shù)說明:StreamSQL IDE 還提供了 UDF 的庫,相當(dāng)于一個庫如果不知道具有什么含義以及如何使用,用戶只需要在 IDE 上搜索到這個庫,就能夠找到使用說明以及使用案例。
-
語法檢測與智能提示:用戶輸入 DB 名字可以顯示表名,對錯誤語法提示。
-
DEBUG:在線 DEBUG 能力,可以上傳本地測試數(shù)據(jù)或者采樣少量 Kafka 等 source 數(shù)據(jù) debug,此功能對流計算任務(wù)非常重要。
-
版本管理:因為業(yè)務(wù)版本需要不斷升級,而升級時也可能需要回退,因此 StreamSQL IDE 也提供了版本管理功能。
2. 任務(wù)管控
滴滴的所有流計算全部是通過 Web 化入口進(jìn)行提交,提供了整個任務(wù)生命周期管理,包括任務(wù)提交、任務(wù)停止、任務(wù)升級和回滾。同時只需要在 web 化服務(wù)臺進(jìn)行參數(shù)修改即可實現(xiàn)對內(nèi)置參數(shù) ( 如 task manager memory 等 ) 進(jìn)行調(diào)優(yōu)。
3. 任務(wù)運維
任務(wù)運維主要分為四個方面:
日志檢索:Flink UI 上查詢?nèi)罩倔w驗非常糟糕,滴滴將 Flink 任務(wù)日志進(jìn)行了采集,存儲在 ES 中,通過 WEB 化的界面進(jìn)行檢索,方便調(diào)查。
指標(biāo)監(jiān)控:Flink 指標(biāo)較多,通過 Flink UI 查看體驗糟糕,因此滴滴構(gòu)建了一個外部的報表平臺,可以對指標(biāo)進(jìn)行監(jiān)控。
報警:報警需要做一個平衡,如重啟報警有多類如 ( 機(jī)器宕機(jī)報警、代碼錯誤報警 ),通過設(shè)置一天內(nèi)單個任務(wù)報警次數(shù)閾值進(jìn)行平衡,同時也包括存活報警 ( 如 kill、start )、延遲報警、重啟報警和 Checkpoint 頻繁失敗報警 ( 如 checkpoint 周期配置不合理 ) 等。
血緣追蹤:實時計算任務(wù)鏈路較長,從采集到消息通道,流計算,再到下游的存儲經(jīng)常包括4-5個環(huán)節(jié),如果無法實現(xiàn)追蹤,容易產(chǎn)生災(zāi)難性的問題。例如發(fā)現(xiàn)某流式任務(wù)流量暴漲后,需要先查看其消費的 topic 是否增加,topic 上游采集是否增加,采集的數(shù)據(jù)庫 DB 是否產(chǎn)生不恰當(dāng)?shù)嘏坎僮骰蛘吣硞€業(yè)務(wù)在不斷增加日志。這類問題需要從下游到上游、從上游到下游多方向的血緣追蹤,方便調(diào)查原因。
4. Meta 化建設(shè)
對比批處理任務(wù),流計算 Flink 任務(wù)需要先定義好 Source、Sink,需要先定義好 MetaStore,因此滴滴目前正在做實時 Meta,將實時數(shù)據(jù)如 Kafka 的數(shù)據(jù)流定義成實時表,存儲在 MetaStore 中,用戶在 IDE 中只需要寫 DML ( 數(shù)據(jù)操縱語言 Data Manipulation Language ) 語句,系統(tǒng)在執(zhí)行時自動填補(bǔ) DDL ( 數(shù)據(jù)定義語言 Data Definition Language ) 語句,將完整的 StreamSQL 提交到 Flink 中去,該工作可以極大的降低 Flink 的使用門檻。
5. 批流一體化
雖然 Flink 具備批流一體化能力,但滴滴目前并沒有完全批流一體化,希望先從產(chǎn)品層面實現(xiàn)批流一體化。通過 Meta 化建設(shè),實現(xiàn)整個滴滴只有一個 MetaStore,無論是 Hive、Kafka topic、還是下游的 HBase、ES 都定義到 MetaStore 中,所有的計算引擎包括 Hive、Spark、Presto、Flink 都查詢同一個 MetaStore,實現(xiàn)整個 SQL 開發(fā)完全一致的效果。根據(jù) SQL 消費的 Source 是表還是流,來區(qū)分批處理任務(wù)和流處理任務(wù),從產(chǎn)品層面上實現(xiàn)批流一體化效果。
1. 面臨的挑戰(zhàn)
大狀態(tài)管理:
-
Flink 作為一個有狀態(tài)的計算引擎,狀態(tài)有時會非常大,在記錄 checkpoint 過程中需要數(shù)據(jù)線對齊,磁盤 IO 變大,導(dǎo)致機(jī)器負(fù)載增大,checkpoint 效率的高低會影響服務(wù)穩(wěn)定性。
-
目前 checkpoint 是一個黑盒,如何做狀態(tài)診斷是一個挑戰(zhàn)。
-
通過內(nèi)置系統(tǒng)解決了上游不重復(fù)問題,但 Flink 本身問題沒有解決,希望構(gòu)建一個端到端的 Exactly Once。
業(yè)務(wù)高可用:
-
滴滴很多內(nèi)部業(yè)務(wù)是通過 golang 或者 java 開發(fā),遷移到 Flink 后,可以解決容錯問題、拓展問題、算法模型問題等。在升級時業(yè)務(wù)不可停,需要實現(xiàn)透明升級。
-
快速診斷解決問題。
-
資源伸縮,如滴滴的早晚高峰時流量突增情況下如何保持系統(tǒng)穩(wěn)定。
多語言:
-
雖然今天在滴滴大部分實時任務(wù)都是通過 SQL 來開發(fā)的,但是依舊不能100%覆蓋全部的場景,有些場景下是需要寫代碼的。Flink 提供了 Java 和 Scala 這兩種 API,但這對于業(yè)務(wù)人員而言依然是不夠的,因為業(yè)務(wù)大部分是 Go 語言系或者 Python 語言系的,因此滴滴希望根據(jù)社區(qū)來提供多語言的開發(fā) Flink 的能力,比如寫 SQL,而 UDF 也可以通過多語言來開發(fā)。
2. 未來規(guī)劃
-
提供高可用的流計算服務(wù):使 Flink 具備支持完整線上業(yè)務(wù)能力的機(jī)制。
-
探索實時機(jī)器學(xué)習(xí):借助 Flink 已經(jīng)具備了10-15分鐘的模型更新能力,接下來希望實現(xiàn)秒級別的模型更新。
-
實時數(shù)倉:目前的數(shù)倉系統(tǒng)大部分還是 T+1 級別,如何構(gòu)建實時數(shù)倉,得到實時化報表,同時口徑和離線保持一致,實現(xiàn)實時數(shù)據(jù)和離線數(shù)據(jù)互補(bǔ)。例如最長保存3個月的實時存儲系統(tǒng)在3個月后將數(shù)據(jù)搬至離線倉庫時,和離線產(chǎn)生數(shù)據(jù)保持一致,是一個較大的挑戰(zhàn)和希望。
本次的分享就到這里,謝謝大家。
特別推薦一個分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:
![]()
長按訂閱更多精彩▼
![]()
如有收獲,點個在看,誠摯感謝
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!





