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