深度剖析阿里巴巴對Flink的優化與改進

摘要: 做者 | 阿里巴巴實時計算團隊 導讀:隨着人工智能時代的降臨,數據量的爆發,阿里巴巴的商品數據處理就常常須要面對增量和全量兩套不一樣的業務流程問題,因此阿里巴巴就在想:能不能有一套統一的大數據引擎技術,用戶只須要根據本身的業務邏輯開發一套代碼。這樣在各類不一樣的場景下,無論是全量數據仍是增量數據,亦或者實時處理,一套方案便可所有支持,這就是阿里巴巴選擇 Flink 的背景和初衷。彼時的 Fl算法

做者 | 阿里巴巴實時計算團隊導讀:隨着人工智能時代的降臨,數據量的爆發,阿里巴巴的商品數據處理就常常須要面對增量和全量兩套不一樣的業務流程問題,因此阿里巴巴就在想:能不能有一套統一的大數據引擎技術,用戶只須要根據本身的業務邏輯開發一套代碼。這樣在各類不一樣的場景下,無論是全量數據仍是增量數據,亦或者實時處理,一套方案便可所有支持,這就是阿里巴巴選擇 Flink 的背景和初衷。

彼時的 Flink 無論是規模仍是穩定性還沒有經歷實踐,成熟度有待商榷。阿里巴巴實時計算團隊決定在阿里內部創建一個 Flink 分支 Blink,並對 Flink 進行大量的修改和完善,讓其適應阿里巴巴這種超大規模的業務場景。那麼,阿里巴巴對 Flink 究竟作了哪些優化呢?

Apache Flink 概述數據庫

Apache Flink(如下簡稱 Flink)是誕生於歐洲的一個大數據研究項目,原名 StratoSphere。該項目是柏林工業大學的一個研究性項目,早期專一於批計算。2014 年,StratoSphere 項目中的核心成員孵化出 Flink,並在同年將 Flink 捐贈 Apache,後來 Flink 順利成爲 Apache 的頂級大數據項目。同時 Flink 計算的主流方向被定位爲流計算,即用流式計算來作全部大數據的計算工做,這就是 Flink 技術誕生的背景。網絡

2014 年 Flink 做爲主攻流計算的大數據引擎開始在開源大數據行業內嶄露頭角。區別於 Storm、Spark Streaming 以及其餘流式計算引擎的是:它不只是一個高吞吐、低延遲的計算引擎,同時還提供不少高級功能。好比它提供有狀態的計算,支持狀態管理,支持強一致性的數據語義以及支持 Event Time,WaterMark 對消息亂序的處理等。數據結構

Flink 的受歡迎還離不開它身上的衆多標籤,其中包括性能優秀(尤爲在流計算領域)、高可擴展性、支持容錯,是一種純內存式的一個計算引擎,作了內存管理方面的大量優化,另外也支持 eventime 的處理、支持超大狀態的 Job(在阿里巴巴中做業的 state 大小超過 TB 的是很是常見的)、支持 exactly-once 的處理。多線程

阿里巴巴與 Flink架構

隨着人工智能時代的降臨,數據量的爆發,在典型的大數據的業務場景下數據業務最通用的作法是:選用批處理的技術處理全量數據,採用流式計算處理實時增量數據。在絕大多數的業務場景之下,用戶的業務邏輯在批處理和流處理之中每每是相同的。可是,用戶用於批處理和流處理的兩套計算引擎是不一樣的。機器學習

所以,用戶一般須要寫兩套代碼。毫無疑問,這帶來了一些額外的負擔和成本。阿里巴巴的商品數據處理就常常須要面對增量和全量兩套不一樣的業務流程問題,因此阿里巴巴就在想:能不能有一套統一的大數據引擎技術,用戶只須要根據本身的業務邏輯開發一套代碼。這樣在各類不一樣的場景下,無論是全量數據仍是增量數據,亦或者實時處理,一套方案便可所有支持,這就是阿里巴巴選擇 Flink 的背景和初衷。異步

基於 Flink 在阿里巴巴搭建的平臺於 2016 年正式上線,並從阿里巴巴的搜索和推薦這兩大場景開始實現。目前阿里巴巴全部的業務,包括阿里巴巴全部子公司都採用了基於 Flink 搭建的實時計算平臺。同時 Flink 計算平臺運行在開源的 Hadoop 集羣之上。採用 Hadoop 的 YARN 作爲資源管理調度,以 HDFS 做爲數據存儲。所以,Flink 能夠和開源大數據軟件 Hadoop 無縫對接。數據結構和算法

目前,這套基於 Flink 搭建的實時計算平臺不只服務於阿里巴巴集團內部,並且經過阿里雲的雲產品 API 向整個開發者生態提供基於 Flink 的雲產品支持。分佈式

彼時的 Flink 無論是規模仍是穩定性還沒有經歷實踐,成熟度有待商榷。阿里巴巴實時計算團隊決定在阿里內部創建一個 Flink 分支 Blink,並對 Flink 進行大量的修改和完善,讓其適應阿里巴巴這種超大規模的業務場景。在這個過程中,該團隊不只對 Flink 在性能和穩定性上作出了不少改進和優化,同時在覈心架構和功能上也進行了大量創新和改進,並將逐漸推回給社區,例如:Flink 新的分佈式架構,增量 Checkpoint 機制, 基於 Credit-based 的網絡流控機制和 Streaming SQL 等。接下來,咱們主要從兩個層面深度剖析阿里巴巴對 Flink 究竟作了哪些優化?

取之開源,用之開源1、    SQL 層

爲了可以真正作到用戶根據本身的業務邏輯開發一套代碼,可以同時運行在多種不一樣的場景,Flink 首先須要給用戶提供一個統一的 API。在通過一番調研以後,阿里巴巴實時計算認爲 SQL 是一個很是適合的選擇。在批處理領域,SQL 已經經歷了幾十年的考驗,是公認的經典。在流計算領域,近年來也不斷有流表二象性、流是表的 ChangeLog 等理論出現。在這些理論基礎之上,阿里巴巴提出了動態表的概念,使得流計算也能夠像批處理同樣使用 SQL 來描述,而且邏輯等價。這樣一來,用戶就可使用 SQL 來描述本身的業務邏輯,相同的查詢語句在執行時能夠是一個批處理任務,也能夠是一個高吞吐低延遲的流計算任務,甚至是先使用批處理技術進行歷史數據的計算,而後自動的轉成流計算任務處理最新的實時數據。在這種聲明式的 API 之下,引擎有了更多的選擇和優化空間。接下來,咱們將介紹其中幾個比較重要的優化。

首先是對 SQL 層的技術架構進行升級和替換。調研過 Flink 或者使用過 Flink 的開發者應該知道,Flink 有兩套基礎的 API,一套是 DataStream,另外一套是 DataSet。DataStream API 是針對流式處理的用戶提供,DataSet API 是針對批處理用戶提供,可是這兩套 API 的執行路徑是徹底不同的,甚至須要生成不一樣的 Task 去執行。Flink 原生的 SQL 層在通過一系列優化以後,會根據用戶但願是批處理仍是流處理的不一樣選擇,去調用 DataSet 或者是 DataStream API。這就會形成用戶在平常開發和優化中,常常要面臨兩套幾乎徹底獨立的技術棧,不少事情可能須要重複的去作兩遍。這樣也會致使在一邊的技術棧上作的優化,另一邊就享受不到。所以阿里巴巴在 SQL 層提出了全新的 Quyer Processor,它主要包括一個流和批能夠儘可能作到複用的優化層(Query Optimizer)以及基於相同接口的算子層(Query Executor)。這樣一來, 80% 以上的工做能夠作到兩邊複用,好比一些公共的優化規則,基礎數據結構等等。同時,流和批也會各自保留本身一些獨特的優化和算子,以知足不一樣的做業行爲。

在 SQL 層的技術架構統一以後,阿里巴巴開始尋求一種更高效的基礎數據結構,以便讓 Blink 在 SQL 層的執行更加高效。在原生 Flink SQL 中,都統一使用了一種叫 Row 的數據結構,它徹底由 JAVA 的一些對象構成關係數據庫中的一行。假如如今的一行數據由一個整型,一個浮點型以及一個字符串組成,那麼 Row 當中就會包含一個 JAVA 的 Integer、Double 和 String。衆所周知,這些 JAVA 的對象在堆內有很多的額外開銷,同時在訪問這些數據的過程當中也會引入沒必要要的裝箱拆箱操做。基於這些問題,阿里巴巴提出了一種全新的數據結構 BinaryRow,它和原來的 Row 同樣也是表示一個關係數據中的一行,但與之不一樣的是,它徹底使用二進制數據來存儲這些數據。在上述例子中,三個不一樣類型的字段統一由 JAVA 的 byte[] 來表示。這會帶來諸多好處:

  • 首先在存儲空間上,去掉了不少無謂的額外消耗,使得對象的存儲更爲緊湊;

  • 其次在和網絡或者狀態存儲打交道的時候,也能夠省略掉不少沒必要要的序列化反序列化開銷;

  • 最後在去掉各類沒必要要的裝箱拆箱操做以後,整個執行代碼對 GC 也更加友好。

經過引入這樣一個高效的基礎數據結構,整個 SQL 層的執行效率獲得了一倍以上的提高。

在算子的實現層面,阿里巴巴引入了更廣範圍的代碼生成技術。得益於技術架構和基礎數據結構的統一,不少代碼生成技術得以達到更廣範圍的複用。同時因爲 SQL 的強類型保證,用戶能夠預先知道算子須要處理的數據的類型,從而能夠生成更有針對性更高效的執行代碼。在原生 Flink SQL 中,只有相似 a > 2 或者 c + d 這樣的簡單表達式纔會應用代碼生成技術,在阿里巴巴優化以後,有一些算子會進行總體的代碼生成,好比排序、聚合等。這使得用戶能夠更加靈活的去控制算子的邏輯,也能夠直接將最終運行代碼嵌入到類當中,去掉了昂貴的函數調用開銷。一些應用代碼生成技術的基礎數據結構和算法,好比排序算法,基於二進制數據的 HashMap 等,也能夠在流和批的算子之間進行共享和複用,讓用戶真正享受到了技術和架構的統一帶來的好處。在針對批處理的某些場景進行數據結構或者算法的優化以後,流計算的性能也可以獲得提高。接下來,咱們聊聊阿里巴巴在 Runtime 層對 Flink 又大刀闊斧地進行了哪些改進。

2、Runtime 層

爲了讓 Flink 在 Alibaba 的大規模生產環境中生根發芽,實時計算團隊如期遇到了各類挑戰,首當其衝的就是如何讓 Flink 與其餘集羣管理系統進行整合。Flink 原生集羣管理模式還沒有完善,也沒法原生地使用其餘其餘相對成熟的集羣管理系統。基於此,一系列棘手的問題接連浮現:多租戶之間資源如何協調?如何動態的申請和釋放資源?如何指定不一樣資源類型?

爲了解決這個問題,實時計算團隊經歷大量的調研與分析,最終選擇的方案是改造 Flink 資源調度系統,讓 Flink 能夠原生地跑在 Yarn 集羣之上;而且重構 Master 架構,讓一個 Job 對應一個 Master,今後 Master 再也不是集羣瓶頸。以此爲契機,阿里巴巴和社區聯手推出了全新的 Flip-6 架構,讓 Flink 資源管理變成可插拔的架構,爲 Flink 的可持續發展打下了堅實的基礎。現在 Flink 能夠無縫運行在 YARN、Mesos 和 K8s 之上,正是這個架構重要性的有力說明。

解決了 Flink 集羣大規模部署問題後,接下來的就是可靠和穩定性,爲了保證 Flink 在生產環境中的高可用,阿里巴巴着重改善了 Flink 的 FailOver 機制。首先是 Master 的 FailOver,Flink 原生的 Master FailOver 會重啓全部的 Job,改善後 Master 任何 FailOver 都不會影響 Job 的正常運行;其次引入了 Region-based 的 Task FailOver,儘可能減小任何 Task 的 FailOver 對用戶形成的影響。有了這些改進的保駕護航,阿里巴巴的大量業務方開始把實時計算遷移到 Flink 上運行。

Stateful Streaming 是 Flink 的最大亮點,基於 Chandy-Lamport 算法的 Checkpoint 機制讓 Flink 具有 Exactly Once 一致性的計算能力,但在早期 Flink 版本中 Checkpoint 的性能在大規模數據量下存在必定瓶頸,阿里巴巴也在 Checkpoint 上進行了大量改進,好比:

  • 增量 Checkpoint 機制:阿里巴巴生產環境中遇到大 JOB 有幾十 TB State 是常事,作一次全量 CP 地動山搖,成本很高,所以阿里巴巴研發了增量 Checkpoint 機制,今後以後 CP 從狂風暴雨變成了細水長流;

  • Checkpoint 小文件合併:都是規模惹的禍,隨着整個集羣 Flink JOB 愈來愈多,CP 文件數也水漲船高,最後壓的 HDFS  NameNode 不堪重負,阿里巴巴經過把若干 CP 小文件合併成一個大文件的組織方式,最終把 NameNode 的壓力減小了幾十倍。

雖說全部的數據能夠放在 State 中,但因爲一些歷史的緣由,用戶依然有一些數據須要存放在像 HBase 等一些外部 KV 存儲中,用戶在 Flink Job 須要訪問這些外部的數據,可是因爲 Flink 一直都是單線程處理模型,致使訪問外部數據的延遲成爲整個系統的瓶頸,顯然異步訪問是解決這個問題的直接手段,可是讓用戶在 UDF 中寫多線程同時還要保證 ExactlyOnce 語義,卻並不是易事。阿里巴巴在 Flink 中提出了 AsyncOperator,讓用戶在 Flink JOB 中寫異步調用和寫「Hello Word」同樣簡單 ,這個讓 Flink Job 的吞吐有了很大的飛躍。

Flink 在設計上是一套批流統一的計算引擎,在使用過快如閃電的流計算以後,批用戶也開始有興趣入住 Flink 小區。但批計算也帶來了新的挑戰,首先在任務調度方面,阿里巴巴引入了更加靈活的調度機制,可以根據任務之間的依賴關係進行更加高效的調度;其次就是數據 Shuffle,Flink 原生的 Shuffle Service 和 TM 綁定,任務執行完以後要依舊保持 TM 沒法釋放資源;還有就是原有的 Batch shuffle 沒有對文件進行合併,因此基本沒法在生產中使用。阿里巴巴開發了 Yarn Shuffle Service 功能的同時解決了以上兩個問題。在開發 Yarn Shuffle Service 的時候,阿里巴巴發現開發一套新的 Shuffle Service 很是不便,須要侵入 Flink 代碼的不少地方,爲了讓其餘開發者方便的擴展不一樣 Shuffle,阿里巴巴同時改造了 Flink Shuffle 架構,讓 Flink 的 Shuffle 變成可插拔的架構。目前阿里巴巴的搜索業務已經在使用 Flink Batch Job,而且已經開始服務於生產。

通過 3 年多打磨,Blink 已經在阿里巴巴開始茁壯生長,可是對 Runtime 的優化和改進是永無止境的,一大波改進和優化正在路上。

Flink 的將來方向

目前 Flink 已經成爲一個主流的流計算引擎,社區下一步很重要的工做是讓 Flink 在批計算上有所突破,在更多的場景下落地,成爲一種主流的批計算引擎。而後進一步在流和批之間進行無縫切換,使流和批的界限愈來愈模糊。用 Flink,在一個計算中,既能夠有流計算,又能夠有批計算。

接下來阿里巴巴還將致力於推進 Flink 在生態上獲得更多語言的支持,不只僅是 Java、Scala 語言,甚至是機器學習下用的 Python、Go 語言。

另外一點不得不說 AI,由於如今不少大數據計算的需求和數據量都是在支持很火爆的 AI 場景,因此 Flink 在流批生態完善的基礎上,將繼續完善上層的 Machine Learning 算法庫,同時 Flink 也會向更成熟的機器學習、深度學習去集成。好比能夠作 Tensorflow On Flink, 讓大數據的 ETL 數據處理和機器學習的 Feature 計算和特徵計算,訓練的計算等進行集成,讓開發者可以同時享受到多種生態給你們帶來的好處。

最後,從生態、社區的活躍來講,阿里巴巴目前在推動的一件事情是籌備 2018 年 12 月 20 日 -21 日在國家會議中心舉辦的首屆 Flink Forward China 峯會(千人規模),參與者將有機會了解阿里巴巴、騰訊、華爲、滴滴、美團、字節跳動等公司爲什麼將 Flink 做爲首選的流處理引擎。

原文連接

相關文章
相關標籤/搜索