原文連接
Apache Flink是一個用於對無邊界和有邊界數據流進行有狀態計算的框架和分佈式處理引擎。Flink設計爲運行在全部常見的集羣環境中,而且之內存速度和任意規模執行計算。html
在這裏,咱們解釋Flink架構的相關重要內容。java
任何類型的數據都是做爲事件流產生的。信用卡交易事務,傳感器測量,機器日誌以及網站或移動應用程序上的用戶交互行爲,全部這些數據都生成流。web
數據能夠做爲無邊界或有邊界流處理。正則表達式
Apache Flink是一個分佈式系統,須要計算資源才能執行應用程序。Flink與全部常見的集羣資源管理器(如Hadoop YARN,Apache Mesos和Kubernetes)集成,但也能夠做爲獨立集羣運行。
Flink旨在很好地適用於以前列出的每一個資源管理器。這是經過特定於資源管理器的部署模式實現的,這些模式容許Flink以其慣用的方式與每一個資源管理器進行交互。
部署Flink應用程序時,Flink會根據應用程序配置的並行度自動識別所需資源,並從資源管理器請求它們。若是發生故障,Flink會經過請求新的資源來替換髮生故障的容器。提交或控制應用程序的全部通訊都經過REST調用進行。這簡化了Flink在許多環境中的集成。算法
Flink旨在以任意規模運行有狀態流式應用程序。應用程序能夠並行化爲數千個在集羣中分佈和同時執行的任務。所以,應用程序能夠利用幾乎無限量的CPU,內存,磁盤和網絡IO。並且,Flink能夠輕鬆維護很是大的應用程序的狀態。其異步和增量檢查點算法確保對延遲處理的影響最小,同時保證精確一次的狀態一致性。
用戶報告了在其生產環境中運行的Flink應用程序的擴展數字使人印象十分深入,例如:數據庫
有狀態的Flink應用程序針對本地狀態訪問進行了優化。任務狀態始終駐留在內存中,或者,若是狀態大小超過可用內存,則保存在訪問高效的磁盤上的數據結構中。所以,任務經過訪問本地(一般是內存中)狀態來執行全部計算,從而產生很是低的處理延遲。Flink經過按期和異步檢查點將本地狀態到持久存儲來保證在出現故障時的精確一次的狀態一致性。apache
原文連接
Apache Flink是一個用於對無邊界和有邊界數據流進行有狀態計算的框架。Flink在不一樣的抽象級別提供多個API,併爲常見用例提供專用庫。
在這裏,咱們介紹Flink易於使用以及富有表現力的API和庫。
後端
流式計算框架構建和運行的應用程序的類型,由框架控制流、狀態以及時間的程度來定義。在下文中,咱們描述了流處理應用程序的這些構建塊,並解釋了Flink處理他們的方法。api
顯然,流是流式處理的一個基本方面。然而,流能夠有不一樣的特徵,這些特徵會影響流的處理方式。Flink是一個多功能的處理框架,它能夠處理任意類型的流。網絡
每一個非凡的流式應用都是有狀態的。只有對個別事件應用轉換的應用程序纔不須要狀態。運行基本業務邏輯的任何應用程序都須要記住事件或中間結果,以便在以後的時間點訪問它們,例如在收到下一個事件時或在特定持續時間以後。
應用程序的狀態在Flink中是一等公民。您能夠經過查看Flink在狀態處理環境(上下文context)中提供的全部功能(函數)來查看。
時間是流式應用的另外一個重要組成成分。大多數事件流都具備固定的時間語義,由於每一個事件都是在特定的時間點生成的。此外,許多常見的流計算基於時間,例如窗口聚合、會話化、模式監測和基於時間的鏈接。流處理的一個重要方面是應用程序如何測量時間,即時間時間和處理時間之間的差別。
Flink提供了一組豐富的與時間相關的功能。
Flink提供三層API。每一個API在簡潔性和表達性之間提供不一樣的權衡,並針對不一樣的用例。
咱們簡要介紹每一個API,討論它的應用程序,並展現一個代碼示例。
ProcessFunctions是Flink提供的最具表現力的功能接口。Flink提供ProcessFunctions來處理來自一個或兩個輸入流中的單個事件或分組到一個窗口的事件。ProcessFunctions提供對時間和狀態的細粒度控制。ProcessFunction能夠任意修改其狀態並註冊將在將來觸發回調函數的定時器。所以,ProcessFunctions能夠實現許多有狀態事件驅動應用程序所需的複雜的每一個事件業務邏輯。
如下示例顯示了KeyedProcessFunction對KeyedStream,匹配START以及END事件進行操做的示例。當一個START事件被接收時,該函數在記住其狀態時間戳和而且註冊四個小時的計時器。若是在計時器觸發以前收到END事件,則該函數計算事件END和START事件之間的持續時間,清除狀態並返回值。不然,計時器只會觸發並清除狀態。
package com.longyun.flink.processfuncs; import org.apache.flink.api.common.state.ValueState; import org.apache.flink.api.common.state.ValueStateDescriptor; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.configuration.Configuration; import org.apache.flink.streaming.api.functions.KeyedProcessFunction; import org.apache.flink.util.Collector; /** * @author lynnyuan * @ClassName com.longyun.flink.processfuncs.StartEndDuration * @Description TODO * K key * IN input * OUT output * @Date 2018/12/3 15:02 * @Version 1.0 **/ public class StartEndDuration extends KeyedProcessFunction<String, Tuple2<String, String>, Tuple2<String, Long>> { private ValueState<Long> startTime; @Override public void open(Configuration configuration) throws Exception { //obtain state handle startTime = getRuntimeContext().getState( new ValueStateDescriptor<Long>("startTIme", Long.class)); } /** * called for each processed event * @param in * @param context * @param out * @throws Exception */ @Override public void processElement(Tuple2<String, String> in, Context context, Collector<Tuple2<String, Long>> out) throws Exception { switch (in.f1){ case "START": //set the start time if we receive a start event. startTime.update(context.timestamp()); //register a timer in four hours from the start event. context.timerService() .registerEventTimeTimer(context.timestamp() + 4 * 60 * 60 * 1000); break; case "END": //emit the duration between start and end event Long sTime = startTime.value(); if(sTime != null){ out.collect(Tuple2.of(in.f0, context.timestamp() - sTime)); //clear the state startTime.clear(); } break; default: break; } } /** Called when a timer fires */ @Override public void onTimer(long timestamp, OnTimerContext ctx, Collector<Tuple2<String, Long>> out) throws Exception { //Time out interval exceeded. Cleaning up the state. startTime.clear(); } }
這個例子說明了KeyedProcessFunction的表達能力,但也強調了它是一個至關冗長的接口。
DataStream API提供了許多通用流處理操做原語。如窗口,record-at-a-time轉換,查詢外部數據存儲豐富事件原語。DataStream API可用於Java和Scala且它是基於函數的,如map()、reduce()以及aggregate()。能夠經過擴展接口或lambda函數來定義函數參數。
如下示例展現如何對點擊流進行會話化以及記錄每一個session的點擊次數。
// a stream of website clicks DataStream<Click> clicks = ... DataStream<Tuple2<String, Long>> result = clicks // project clicks to userId and add a 1 for counting .map( // define function by implementing the MapFunction interface. new MapFunction<Click, Tuple2<String, Long>>() { @Override public Tuple2<String, Long> map(Click click) { return Tuple2.of(click.userId, 1L); } }) // key by userId (field 0) .keyBy(0) // define session window with 30 minute gap .window(EventTimeSessionWindows.withGap(Time.minutes(30L))) // count clicks per session. Define function as lambda function. .reduce((a, b) -> Tuple2.of(a.f0, a.f1 + b.f1));
Flink有兩種關係化API特性, Table API和SQL。這兩個API都是用於批處理和流處理的統一API,即,在無邊界的實時流或有邊界的記錄流上以相同的語義執行查詢,併產生相同的結果。Table API和SQL利用Apache Calicite來解析,校驗以及查詢優化。它們能夠與DataStream和DataSet API無縫集成,並支持用戶定義的標量,聚合以及表值函數。
Flink的關係化API旨在簡化數據分析,數據流水線和ETL應用程序的定義。
如下示例展現如何對點擊流進行會話化以及記錄每一個session的點擊次數。與DataStream API中的示例是相同的用例。
SELECT userId, COUNT(*) FROM clicks GROUP BY SESSION(clicktime, INTERVAL '30' MINUTE), userId
Flink具備幾個用於常見數據處理用例的庫。這些庫一般嵌入在API中,而不是徹底獨立的。所以,它們能夠從API的全部特性中受益,並與其餘庫集成。
Apache Flink是一個用於對無邊界和有邊界數據流進行有狀態計算的框架。因爲許多流應用程序設計爲以最短的停機時間連續運行,所以流處理器必須提供出色的故障恢復,以及在應用程序運行時監控和維護應用程序的工具。
Apache Flink很是關注流處理的操做方面。在這裏,咱們將解釋Flink的故障恢復機制,並介紹其管理和監督正在運行的應用程序的特性。
機器和處理故障在分佈式系統中無處不在。像Flink這樣的分佈式流處理器必須從故障中恢復,以便可以全天候運行流應用程序。顯然,這不只意味着在故障發生後從新啓動應用程序,並且還要確保其內部狀態保持一致,以便應用程序能夠繼續處理,就像從未發生過故障同樣。
Flink提供了多種特性,以確保應用程序保持運行並保持一致:
須要維護爲關鍵業務服務提供支持的流應用程序。須要修復錯誤,而且須要實現改進或新功能特性。可是,更新有狀態流應用程序並不是易事。一般,咱們不能簡單地中止應用程序並從新啓動固定版本或改進版本,由於沒法承受丟失應用程序的狀態。
Flink的Savepoints是一個獨特而強大的功能特性,能夠解決更新有狀態應用程序和許多其餘相關挑戰的問題。保存點是應用程序狀態的一致快照,所以它與檢查點很是類似。可是,與檢查點相比,須要手動觸發保存點,而且在應用程序中止時不會自動刪除保存點。保存點可用於啓動狀態兼容的應用程序並初始化其狀態。保存點可啓用如下功能:
與任何其餘服務同樣,持續運行的流應用程序須要受到監督並集成到組織的運營(operations)基礎架構(即監控和日誌記錄服務)中。監控有助於預測問題並提早作出反應。日誌記錄讓咱們能夠依據根緣由分析來調查故障。最後,控制運行應用程序的易於訪問的界面也是一個重要特性。
Flink與許多常見的日誌記錄和監視服務已經很好地集成,並提供REST API來控制應用程序和查詢信息。