ApacheFlink起源於Stratosphere項目,Stratosphere是在2010~2014年由3所地處柏林的大學和歐洲的一些其他的大學共同進行的研究項目,2014年4月Stratosphere的代碼被復制並捐贈給了Apache軟件基金會,參加這個孵化項目的初始成員是Stratosphere系統的核心開發人員,2014年12月,Flink一躍成為Apache軟件基金會的頂級項目。
在德語中,Flink一詞表示快速和靈巧,項目采用一只松鼠的彩色圖案作為logo,這不僅是因為松鼠具有快速和靈巧的特點,還因為柏林的松鼠有一種迷人的紅棕色,而Flink的松鼠logo擁有可愛的尾巴,尾巴的顏色與Apache軟件基金會的logo顏色相呼應,也就是說,這是一只Apache風格的松鼠。
圖 Flink Logo
Flink雖然誕生的早(2010年),但是其實是起大早趕晚集,直到2015年才開始突然爆發熱度。
在Flink被apache提升為頂級項目之后,阿里實時計算團隊決定在阿里內部建立一個 Flink 分支 Blink,並對 Flink 進行大量的修改和完善,讓其適應阿里巴巴這種超大規模的業務場景。
Blink由2016年上線,服務於阿里集團內部搜索、推薦、廣告和螞蟻等大量核心實時業務。與2019年1月Blink正式開源,目前阿里70%的技術部門都有使用該版本。
Blink比起Flink的優勢就是對SQL語法的更完善的支持以及執行SQL的性能提升。
2 Flink的重要特點
2.1 事件驅動型(Event-driven)
事件驅動型應用是一類具有狀態的應用,它從一個或多個事件流提取數據,並根據到來的事件觸發計算、狀態更新或其他外部動作。比較典型的就是以kafka為代表的消息隊列幾乎都是事件驅動型應用。
與之不同的就是SparkStreaming微批次,如圖:
事件驅動型:
2.2 流與批的世界觀
批處理的特點是有界、持久、大量,非常適合需要訪問全套記錄才能完成的計算工作,一般用於離線統計。
流處理的特點是無界、實時, 無需針對整個數據集執行操作,而是對通過系統傳輸的每個數據項執行操作,一般用於實時統計。
在spark的世界觀中,一切都是由批次組成的,離線數據是一個大批次,而實時數據是由一個一個無限的小批次組成的。
而在flink的世界觀中,一切都是由流組成的,離線數據是有界限的流,實時數據是一個沒有界限的流,這就是所謂的有界流和無界流。
無界數據流:無界數據流有一個開始但是沒有結束,它們不會在生成時終止並提供數據,必須連續處理無界流,也就是說必須在獲取后立即處理event。對於無界數據流我們無法等待所有數據都到達,因為輸入是無界的,並且在任何時間點都不會完成。處理無界數據通常要求以特定順序(例如事件發生的順序)獲取event,以便能夠推斷結果完整性。
有界數據流:有界數據流有明確定義的開始和結束,可以在執行任何計算之前通過獲取所有數據來處理有界流,處理有界流不需要有序獲取,因為可以始終對有界數據集進行排序,有界流的處理也稱為批處理。
這種以流為世界觀的架構,獲得的最大好處就是具有極低的延遲。
2.3 分層api
最底層級的抽象僅僅提供了有狀態流,它將通過過程函數(Process Function)被嵌入到DataStream API中。底層過程函數(Process Function) 與 DataStream API 相集成,使其可以對某些特定的操作進行底層的抽象,它允許用戶可以自由地處理來自一個或多個數據流的事件,並使用一致的容錯的狀態。除此之外,用戶可以注冊事件時間並處理時間回調,從而使程序可以處理復雜的計算。
實際上,大多數應用並不需要上述的底層抽象,而是針對核心API(Core APIs) 進行編程,比如DataStream API(有界或無界流數據)以及DataSet API(有界數據集)。這些API為數據處理提供了通用的構建模塊,比如由用戶定義的多種形式的轉換(transformations),連接(joins),聚合(aggregations),窗口操作(windows)等等。DataSet API 為有界數據集提供了額外的支持,例如循環與迭代。這些API處理的數據類型以類(classes)的形式由各自的編程語言所表示。
Table API 是以表為中心的聲明式編程,其中表可能會動態變化(在表達流數據時)。Table API遵循(擴展的)關系模型:表有二維數據結構(schema)(類似於關系數據庫中的表),同時API提供可比較的操作,例如select、project、join、group-by、aggregate等。Table API程序聲明式地定義了什么邏輯操作應該執行,而不是准確地確定這些操作代碼的看上去如何 。 盡管Table API可以通過多種類型的用戶自定義函數(UDF)進行擴展,其仍不如核心API更具表達能力,但是使用起來卻更加簡潔(代碼量更少)。除此之外,Table API程序在執行之前會經過內置優化器進行優化。
你可以在表與 DataStream/DataSet 之間無縫切換,以允許程序將 Table API 與 DataStream 以及 DataSet 混合使用。
Flink提供的最高層級的抽象是 SQL 。這一層抽象在語法與表達能力上與 Table API 類似,但是是以SQL查詢表達式的形式表現程序。SQL抽象與Table API交互密切,同時SQL查詢可以直接在Table API定義的表上執行。
2.4 支持有狀態計算
Flink在1.4版本中實現了狀態管理,所謂狀態管理就是在流失計算過程中將算子的中間結果保存在內存或者文件系統中,等下一個事件進入算子后可以讓當前事件的值與歷史值進行匯總累計。
2.5 支持exactly-once語義
在分布式系統中,組成系統的各個計算機是獨立的。這些計算機有可能fail。
一個sender發送一條message到receiver。根據receiver出現fail時sender如何處理fail,可以將message delivery分為三種語義:
At Most once: 對於一條message,receiver最多收到一次(0次或1次).
可以達成At Most Once的策略:
sender把message發送給receiver.無論receiver是否收到message,sender都不再重發message.
At Least once: 對於一條message,receiver最少收到一次(1次及以上).
可以達成At Least Once的策略:
sender把message發送給receiver.當receiver在規定時間內沒有回復ACK或回復了error信息,那么sender重發這條message給receiver,直到sender收到receiver的ACK.
Exactly once: 對於一條message,receiver確保只收到一次
2.6 支持事件時間(EventTime)
目前大多數框架時間窗口計算,都是采用當前系統時間,以時間為單位進行的聚合計算只能反應數據到達計算引擎的時間,而並不是實際業務時間