Apache Flink靠什么征服阿里工程師?
伴隨著海量增長(zhǎng)的數(shù)據(jù),數(shù)字化時(shí)代的未來(lái)感撲面而至。不論是結(jié)繩記事的小數(shù)據(jù)時(shí)代,還是我們正在經(jīng)歷的大數(shù)據(jù)時(shí)代,計(jì)算的邊界正在被***拓寬,而數(shù)據(jù)的價(jià)值再也難以被計(jì)算。
時(shí)下,談及大數(shù)據(jù),不得不提到熱門(mén)的下一代大數(shù)據(jù)計(jì)算引擎 Apache Flink(以下簡(jiǎn)稱(chēng) Flink)。
本文將結(jié)合 Flink 的前世今生,從業(yè)務(wù)角度出發(fā),向大家娓娓道來(lái):為什么阿里選擇了 Flink?
為什么阿里選擇了 Flink
隨著人工智能時(shí)代的降臨,數(shù)據(jù)量的爆發(fā),在典型的大數(shù)據(jù)的業(yè)務(wù)場(chǎng)景下數(shù)據(jù)業(yè)務(wù)最通用的做法是:選用批處理的技術(shù)處理全量數(shù)據(jù),采用流式計(jì)算處理實(shí)時(shí)增量數(shù)據(jù)。
在絕大多數(shù)的業(yè)務(wù)場(chǎng)景之下,用戶(hù)的業(yè)務(wù)邏輯在批處理和流處理之中往往是相同的。
但是,用戶(hù)用于批處理和流處理的兩套計(jì)算引擎是不同的。因此,用戶(hù)通常需要寫(xiě)兩套代碼。毫無(wú)疑問(wèn),這帶來(lái)了一些額外的負(fù)擔(dān)和成本。
阿里巴巴的商品數(shù)據(jù)處理就經(jīng)常需要面對(duì)增量和全量?jī)商撞煌臉I(yè)務(wù)流程問(wèn)題,所以阿里就在想,我們能不能有一套統(tǒng)一的大數(shù)據(jù)引擎技術(shù),用戶(hù)只需要根據(jù)自己的業(yè)務(wù)邏輯開(kāi)發(fā)一套代碼。
這樣在各種不同的場(chǎng)景下,不管是全量數(shù)據(jù)還是增量數(shù)據(jù),亦或者實(shí)時(shí)處理,一套方案即可全部支持,這就是阿里選擇 Flink 的背景和初衷。
目前開(kāi)源大數(shù)據(jù)計(jì)算引擎有很多選擇,流計(jì)算如 Storm、Samza、Flink、Kafka Stream 等,批處理如 Spark、Hive、Pig、Flink 等。
而同時(shí)支持流處理和批處理的計(jì)算引擎,只有兩種選擇:
- Apache Spark。
- Apache Flink。
從技術(shù),生態(tài)等各方面的綜合考慮。首先,Spark 的技術(shù)理念是基于批來(lái)模擬流的計(jì)算。而 Flink 則完全相反,它采用的是基于流計(jì)算來(lái)模擬批計(jì)算。
從技術(shù)發(fā)展方向看,用批來(lái)模擬流有一定的技術(shù)局限性,并且這個(gè)局限性可能很難突破。
而 Flink 基于流來(lái)模擬批計(jì)算,在技術(shù)上有更好的擴(kuò)展性。從長(zhǎng)遠(yuǎn)來(lái)看,阿里決定用 Flink 做一個(gè)統(tǒng)一的、通用的大數(shù)據(jù)引擎作為未來(lái)的選型。
Flink 是一個(gè)低延遲、高吞吐、統(tǒng)一的大數(shù)據(jù)計(jì)算引擎。在阿里巴巴的生產(chǎn)環(huán)境中,F(xiàn)link 的計(jì)算平臺(tái)可以實(shí)現(xiàn)毫秒級(jí)的延遲情況下,每秒鐘處理上億次的消息或者事件。
同時(shí) Flink 提供了一個(gè) Exactly-once 的一致性語(yǔ)義,保證了數(shù)據(jù)的正確性。這樣就使得 Flink 大數(shù)據(jù)引擎可以提供金融級(jí)的數(shù)據(jù)處理能力。
Flink 在阿里的現(xiàn)狀
基于 Apache Flink 在阿里巴巴搭建的平臺(tái)于 2016 年正式上線(xiàn),并從阿里巴巴的搜索和推薦這兩大場(chǎng)景開(kāi)始實(shí)現(xiàn)。
目前阿里巴巴所有的業(yè)務(wù),包括阿里巴巴所有子公司都采用了基于 Flink 搭建的實(shí)時(shí)計(jì)算平臺(tái)。同時(shí) Flink 計(jì)算平臺(tái)運(yùn)行在開(kāi)源的 Hadoop 集群之上。
采用 Hadoop 的 YARN 做為資源管理調(diào)度,以 HDFS 作為數(shù)據(jù)存儲(chǔ)。因此,F(xiàn)link 可以和開(kāi)源大數(shù)據(jù)軟件 Hadoop 無(wú)縫對(duì)接。
目前,這套基于 Flink 搭建的實(shí)時(shí)計(jì)算平臺(tái)不僅服務(wù)于阿里巴巴集團(tuán)內(nèi)部,而且通過(guò)阿里云的云產(chǎn)品 API 向整個(gè)開(kāi)發(fā)者生態(tài)提供基于 Flink 的云產(chǎn)品支持。
Flink 在阿里巴巴的大規(guī)模應(yīng)用,表現(xiàn)如何?具體如下:
- 規(guī)模:一個(gè)系統(tǒng)是否成熟,規(guī)模是重要指標(biāo)。Flink 最初上線(xiàn)時(shí),阿里巴巴只有數(shù)百臺(tái)服務(wù)器,目前規(guī)模已達(dá)上萬(wàn)臺(tái),此等規(guī)模在全球范圍內(nèi)也是***。
- 狀態(tài)數(shù)據(jù):基于 Flink,內(nèi)部積累起來(lái)的狀態(tài)數(shù)據(jù)已經(jīng)是 PB 級(jí)別規(guī)模。
- Events:如今每天在 Flink 的計(jì)算平臺(tái)上,處理的數(shù)據(jù)已經(jīng)超過(guò)萬(wàn)億條。
PS:在峰值期間可以承擔(dān)每秒超過(guò) 4.72 億次的訪(fǎng)問(wèn),最典型的應(yīng)用場(chǎng)景是阿里巴巴雙 11 大屏。
Flink 的發(fā)展之路
接下來(lái)從開(kāi)源技術(shù)的角度,來(lái)談一談 Apache Flink 是如何誕生的,它是如何成長(zhǎng)的?以及在成長(zhǎng)的這個(gè)關(guān)鍵的時(shí)間點(diǎn)阿里是如何進(jìn)入的?并對(duì)它做出了那些貢獻(xiàn)和支持?
Flink 誕生于歐洲的一個(gè)大數(shù)據(jù)研究項(xiàng)目 StratoSphere。該項(xiàng)目是柏林工業(yè)大學(xué)的一個(gè)研究性項(xiàng)目。
早期,F(xiàn)link 是做 Batch 計(jì)算的,但是在 2014 年,StratoSphere 里面的核心成員孵化出 Flink,同年將 Flink 捐贈(zèng) Apache,并在后來(lái)成為 Apache 的***大數(shù)據(jù)項(xiàng)目。
同時(shí) Flink 計(jì)算的主流方向被定位為 Streaming,即用流式計(jì)算來(lái)做所有大數(shù)據(jù)的計(jì)算,這就是 Flink 技術(shù)誕生的背景。
2014 年 Flink 作為主攻流計(jì)算的大數(shù)據(jù)引擎開(kāi)始在開(kāi)源大數(shù)據(jù)行業(yè)內(nèi)嶄露頭角。
區(qū)別于 Storm,Spark Streaming 以及其他流式計(jì)算引擎的是:它不僅是一個(gè)高吞吐、低延遲的計(jì)算引擎,同時(shí)還提供很多高級(jí)的功能。
比如它提供了有狀態(tài)的計(jì)算,支持狀態(tài)管理,支持強(qiáng)一致性的數(shù)據(jù)語(yǔ)義以及支持 Event Time,WaterMark 對(duì)消息亂序的處理。
Flink 核心概念以及基本理念
Flink 最區(qū)別于其他流計(jì)算引擎的,其實(shí)就是狀態(tài)管理。什么是狀態(tài)?
例如開(kāi)發(fā)一套流計(jì)算的系統(tǒng)或者任務(wù)做數(shù)據(jù)處理,可能經(jīng)常要對(duì)數(shù)據(jù)進(jìn)行統(tǒng)計(jì),如 Sum、Count、Min、Max 這些值是需要存儲(chǔ)的。
因?yàn)橐粩喔?,這些值或者變量就可以理解為一種狀態(tài)。如果數(shù)據(jù)源是在讀取 Kafka,RocketMQ,可能要記錄讀取到什么位置,并記錄 Offset,這些 Offset 變量都是要計(jì)算的狀態(tài)。
Flink 提供了內(nèi)置的狀態(tài)管理,可以把這些狀態(tài)存儲(chǔ)在 Flink 內(nèi)部,而不需要把它存儲(chǔ)在外部系統(tǒng)。
這樣做有兩大好處:
- 降低了計(jì)算引擎對(duì)外部系統(tǒng)的依賴(lài)以及部署,使運(yùn)維更加簡(jiǎn)單。
- 對(duì)性能帶來(lái)了極大的提升:如果通過(guò)外部去訪(fǎng)問(wèn),如 Redis、HBase 它一定是通過(guò)網(wǎng)絡(luò)及 RPC。如果通過(guò) Flink 內(nèi)部去訪(fǎng)問(wèn),它只通過(guò)自身的進(jìn)程去訪(fǎng)問(wèn)這些變量。
同時(shí) Flink 會(huì)定期將這些狀態(tài)做 Checkpoint 持久化,把 Checkpoint 存儲(chǔ)到一個(gè)分布式的持久化系統(tǒng)中,比如 HDFS。
這樣的話(huà),當(dāng) Flink 的任務(wù)出現(xiàn)任何故障時(shí),它都會(huì)從最近的一次 Checkpoint 將整個(gè)流的狀態(tài)進(jìn)行恢復(fù),然后繼續(xù)運(yùn)行它的流處理。對(duì)用戶(hù)沒(méi)有任何數(shù)據(jù)上的影響。
Flink 是如何做到在 Checkpoint 恢復(fù)過(guò)程中沒(méi)有任何數(shù)據(jù)的丟失和數(shù)據(jù)的冗余?來(lái)保證精準(zhǔn)計(jì)算的?
這其中原因是 Flink 利用了一套非常經(jīng)典的 Chandy-Lamport 算法,它的核心思想是把這個(gè)流計(jì)算看成一個(gè)流式的拓?fù)?,定期從這個(gè)拓?fù)涞念^部 Source 點(diǎn)開(kāi)始插入特殊的 Barries,從上游開(kāi)始不斷的向下游廣播這個(gè) Barries。
每一個(gè)節(jié)點(diǎn)收到所有的 Barries,會(huì)將 State 做一次 Snapshot,當(dāng)每個(gè)節(jié)點(diǎn)都做完 Snapshot 之后,整個(gè)拓?fù)渚退阃暾淖鐾炅艘淮?Checkpoint。接下來(lái)不管出現(xiàn)任何故障,都會(huì)從最近的 Checkpoint 進(jìn)行恢復(fù)。
Flink 利用這套經(jīng)典的算法,保證了強(qiáng)一致性的語(yǔ)義。這也是 Flink 與其他無(wú)狀態(tài)流計(jì)算引擎的核心區(qū)別。
下面介紹 Flink 是如何解決亂序問(wèn)題的。比如星球大戰(zhàn)的播放順序,如果按照上映的時(shí)間觀看,可能會(huì)發(fā)現(xiàn)故事在跳躍。
在流計(jì)算中,與這個(gè)例子是非常類(lèi)似的。所有消息到來(lái)的時(shí)間,和它真正發(fā)生在源頭,在線(xiàn)系統(tǒng) Log 當(dāng)中的時(shí)間是不一致的。
在流處理當(dāng)中,希望是按消息真正發(fā)生在源頭的順序進(jìn)行處理,不希望是真正到達(dá)程序里的時(shí)間來(lái)處理。
Flink 提供了 Event Time 和 Water Mark 的一些先進(jìn)技術(shù)來(lái)解決亂序的問(wèn)題,使得用戶(hù)可以有序的處理這個(gè)消息。這是 Flink 一個(gè)很重要的特點(diǎn)。
接下來(lái)要介紹的是 Flink 啟動(dòng)時(shí)的核心理念和核心概念,這是 Flink 發(fā)展的***個(gè)階段;第二個(gè)階段時(shí)間是 2015 年和 2017 年,這個(gè)階段也是 Flink 發(fā)展以及阿里巴巴介入的時(shí)間。
故事源于 2015 年年中,我們?cè)谒阉魇聵I(yè)部的一次調(diào)研。當(dāng)時(shí)阿里有自己的批處理技術(shù)和流計(jì)算技術(shù),有自研的,也有開(kāi)源的。
但是,為了思考下一代大數(shù)據(jù)引擎的方向以及未來(lái)趨勢(shì),我們做了很多新技術(shù)的調(diào)研。
結(jié)合大量調(diào)研結(jié)果,我們***得出的結(jié)論是:解決通用大數(shù)據(jù)計(jì)算需求,批流融合的計(jì)算引擎,才是大數(shù)據(jù)技術(shù)的發(fā)展方向,并且最終我們選擇了 Flink。
但 2015 年的 Flink 還不夠成熟,不管是規(guī)模還是穩(wěn)定性尚未經(jīng)歷實(shí)踐。***我們決定在阿里內(nèi)部建立一個(gè) Flink 分支,對(duì) Flink 做大量的修改和完善,讓其適應(yīng)阿里巴巴這種超大規(guī)模的業(yè)務(wù)場(chǎng)景。
在這個(gè)過(guò)程當(dāng)中,我們團(tuán)隊(duì)不僅對(duì) Flink 在性能和穩(wěn)定性上做出了很多改進(jìn)和優(yōu)化,同時(shí)在核心架構(gòu)和功能上也進(jìn)行了大量創(chuàng)新和改進(jìn),并將其貢獻(xiàn)給社區(qū)。
例如:Flink 新的分布式架構(gòu),增量 Checkpoint 機(jī)制,基于 Credit-based 的網(wǎng)絡(luò)流控機(jī)制和 Streaming SQL 等。
阿里巴巴對(duì) Flink 社區(qū)的貢獻(xiàn)
我們舉兩個(gè)設(shè)計(jì)案例,***個(gè)是阿里巴巴重構(gòu)了 Flink 的分布式架構(gòu),將 Flink 的 Job 調(diào)度和資源管理做了一個(gè)清晰的分層和解耦。這樣做的首要好處是 Flink 可以原生的跑在各種不同的開(kāi)源資源管理器上。
經(jīng)過(guò)這套分布式架構(gòu)的改進(jìn),F(xiàn)link 可以原生地跑在 Hadoop Yarn 和 Kubernetes 這兩個(gè)最常見(jiàn)的資源管理系統(tǒng)之上。
同時(shí)將 Flink 的任務(wù)調(diào)度從集中式調(diào)度改為了分布式調(diào)度,這樣 Flink 就可以支持更大規(guī)模的集群,以及得到更好的資源隔離。
另一個(gè)是實(shí)現(xiàn)了增量的 Checkpoint 機(jī)制,因?yàn)?Flink 提供了有狀態(tài)的計(jì)算和定期的 Checkpoint 機(jī)制,如果內(nèi)部的數(shù)據(jù)越來(lái)越多,不停地做 Checkpoint,Checkpoint 會(huì)越來(lái)越大,***可能導(dǎo)致做不出來(lái)。
提供了增量的 Checkpoint 后,F(xiàn)link 會(huì)自動(dòng)地發(fā)現(xiàn)哪些數(shù)據(jù)是增量變化,哪些數(shù)據(jù)是被修改了。同時(shí)只將這些修改的數(shù)據(jù)進(jìn)行持久化。
這樣 Checkpoint 不會(huì)隨著時(shí)間的運(yùn)行而越來(lái)越難做,整個(gè)系統(tǒng)的性能會(huì)非常地平穩(wěn),這也是我們貢獻(xiàn)給社區(qū)的一個(gè)很重大的特性。
經(jīng)過(guò) 2015 年到 2017 年對(duì) Flink Streaming 的能力完善,F(xiàn)link 社區(qū)也逐漸成熟起來(lái)。
Flink 也成為在 Streaming 領(lǐng)域最主流的計(jì)算引擎。因?yàn)?Flink 最早期想做一個(gè)流批統(tǒng)一的大數(shù)據(jù)引擎,2018 年已經(jīng)啟動(dòng)這項(xiàng)工作。
為了實(shí)現(xiàn)這個(gè)目標(biāo),阿里巴巴提出了新的統(tǒng)一 API 架構(gòu),統(tǒng)一 SQL 解決方案,同時(shí)流計(jì)算的各種功能得到完善后,我們認(rèn)為批計(jì)算也需要各種各樣的完善。
無(wú)論在任務(wù)調(diào)度層,還是在數(shù)據(jù) Shuffle 層,在容錯(cuò)性,易用性上,都需要完善很多工作。
下面主要和大家分享兩點(diǎn):
- 統(tǒng)一 API Stack
- 統(tǒng)一 SQL 方案
先來(lái)看下目前 Flink API Stack 的一個(gè)現(xiàn)狀,調(diào)研過(guò) Flink 或者使用過(guò) Flink 的開(kāi)發(fā)者應(yīng)該知道。Flink 有 2 套基礎(chǔ)的 API,一套是 DataStream,一套是 DataSet。
DataStream API 是針對(duì)流式處理的用戶(hù)提供,DataSet API 是針對(duì)批處理用戶(hù)提供,但是這兩套 API 的執(zhí)行路徑是完全不一樣的,甚至需要生成不同的 Task 去執(zhí)行。
所以這跟得到統(tǒng)一的 API 是有沖突的,而且這個(gè)也是不完善的,不是最終的解法。
在 Runtime 之上首先是要有一個(gè)批流統(tǒng)一融合的基礎(chǔ) API 層,我們希望可以統(tǒng)一 API 層。
因此,我們?cè)谛录軜?gòu)中將采用一個(gè) DAG(有限無(wú)環(huán)圖)API,作為一個(gè)批流統(tǒng)一的 API 層。
對(duì)于這個(gè)有限無(wú)環(huán)圖,批計(jì)算和流計(jì)算不需要涇渭分明的表達(dá)出來(lái)。只需要讓開(kāi)發(fā)者在不同的節(jié)點(diǎn),不同的邊上定義不同的屬性,來(lái)規(guī)劃數(shù)據(jù)是流屬性還是批屬性。
整個(gè)拓?fù)涫强梢匀诤吓鹘y(tǒng)一的語(yǔ)義表達(dá),整個(gè)計(jì)算無(wú)需區(qū)分是流計(jì)算還是批計(jì)算,只需要表達(dá)自己的需求。有了這套 API 后,F(xiàn)link 的 API Stack 將得到統(tǒng)一。
除了統(tǒng)一的基礎(chǔ) API 層和統(tǒng)一的 API Stack 外,同樣在上層統(tǒng)一 SQL 的解決方案。
流和批的 SQL,可以認(rèn)為流計(jì)算有數(shù)據(jù)源,批計(jì)算也有數(shù)據(jù)源,我們可以將這兩種源都模擬成數(shù)據(jù)表。
可以認(rèn)為流數(shù)據(jù)的數(shù)據(jù)源是一張不斷更新的數(shù)據(jù)表,對(duì)于批處理的數(shù)據(jù)源可以認(rèn)為是一張相對(duì)靜止的表,沒(méi)有更新的數(shù)據(jù)表。
整個(gè)數(shù)據(jù)處理可以當(dāng)做 SQL 的一個(gè) Query,最終產(chǎn)生的結(jié)果也可以模擬成一個(gè)結(jié)果表。
對(duì)于流計(jì)算而言,它的結(jié)果表是一張不斷更新的結(jié)果表。對(duì)于批處理而言,它的結(jié)果表是相當(dāng)于一次更新完成的結(jié)果表。
從整個(gè) SOL 語(yǔ)義上表達(dá),流和批是可以統(tǒng)一的。此外,不管是流式 SQL,還是批處理 SQL,都可以用同一個(gè) Query 來(lái)表達(dá)復(fù)用。
這樣以來(lái)流批都可以用同一個(gè) Query 優(yōu)化或者解析。甚至很多流和批的算子都是可以復(fù)用的。
Flink 的未來(lái)方向
首先,阿里巴巴還是要立足于 Flink 的本質(zhì),去做一個(gè)全能的統(tǒng)一大數(shù)據(jù)計(jì)算引擎。將它在生態(tài)和場(chǎng)景上進(jìn)行落地。
目前 Flink 已經(jīng)是一個(gè)主流的流計(jì)算引擎,很多互聯(lián)網(wǎng)公司已經(jīng)達(dá)成了共識(shí):Flink 是大數(shù)據(jù)的未來(lái),是***的流計(jì)算引擎。
下一步很重要的工作是讓 Flink 在批計(jì)算上有所突破。在更多的場(chǎng)景下落地,成為一種主流的批計(jì)算引擎。
然后進(jìn)一步在流和批之間進(jìn)行無(wú)縫的切換,流和批的界限越來(lái)越模糊。用 Flink,在一個(gè)計(jì)算中,既可以有流計(jì)算,又可以有批計(jì)算。
第二個(gè)方向就是 Flink 的生態(tài)上有更多語(yǔ)言的支持,不僅僅是 Java,Scala 語(yǔ)言,甚至是機(jī)器學(xué)習(xí)下用的 Python,Go 語(yǔ)言。
未來(lái)我們希望能用更多豐富的語(yǔ)言來(lái)開(kāi)發(fā) Flink 計(jì)算的任務(wù),來(lái)描述計(jì)算邏輯,并和更多的生態(tài)進(jìn)行對(duì)接。
***不得不說(shuō) AI,因?yàn)楝F(xiàn)在很多大數(shù)據(jù)計(jì)算的需求和數(shù)據(jù)量都是在支持很火爆的 AI 場(chǎng)景。
所以在 Flink 流批生態(tài)完善的基礎(chǔ)上,將繼續(xù)往上走,完善上層 Flink 的 Machine Learning 算法庫(kù),同時(shí) Flink 往上層也會(huì)向成熟的機(jī)器學(xué)習(xí),深度學(xué)習(xí)去集成。
比如可以做 Tensorflow On Flink,讓大數(shù)據(jù)的 ETL 數(shù)據(jù)處理和機(jī)器學(xué)習(xí)的 Feature 計(jì)算和特征計(jì)算,訓(xùn)練的計(jì)算等進(jìn)行集成,讓開(kāi)發(fā)者能夠同時(shí)享受到多種生態(tài)給大家?guī)?lái)的好處。