一. 應(yīng)用
二. 抽象
三. 時(shí)間與窗口??
四. 類型與序列化
五. 內(nèi)存管理??
六. 狀態(tài)管理
七. 作業(yè)提交
八. 資源管理
九. 作業(yè)調(diào)度
十. 作業(yè)執(zhí)行
十一. 數(shù)據(jù)交換
十二. 應(yīng)用容錯
十三. SQL
十四. 運(yùn)維監(jiān)控
應(yīng)用
一. Flink應(yīng)用開發(fā)
- 獲取參數(shù)
- 初始化stream執(zhí)行環(huán)境
- 配置參數(shù)
- 讀取外部數(shù)據(jù)
- 數(shù)據(jù)處理
- 將處理結(jié)果寫入外部
- 觸發(fā)執(zhí)行
二. API層次

三. 數(shù)據(jù)流
- DataStream
- DataStreamSource
- DataStreamSink
- KeyedStream
- WindowedStream & AllWindowedStream
- JoinedStreams & CoGroupedStreams:Join是CoGroup的一種特例,JoinedStreams底層使用CoGroupedStreams來實(shí)現(xiàn)。兩者的區(qū)別如下。CoGrouped側(cè)重的是Group,對數(shù)據(jù)進(jìn)行分組,是對同一個(gè)key上的兩組集合進(jìn)行操作
- ConnectedStreams
- BroadcastStream & BroadcastConnectedStream
- IterativeStream:IterativeDataStream是對一個(gè)DataStream的迭代操作,從邏輯上來說,包含IterativeStream的Dataflow是一個(gè)有向有環(huán)圖,在底層執(zhí)行層面上,F(xiàn)link對其進(jìn)行了特殊處理。
- AsyncDataStream:AsyncDataStream是個(gè)工具,提供在DataStream上使用異步函數(shù)的能力
四. 數(shù)據(jù)流API
- 數(shù)據(jù)讀取
從內(nèi)存中讀取數(shù)據(jù)(直接在內(nèi)存中生成數(shù)據(jù),方便測試和演示),文件讀取數(shù)據(jù)(文件讀取的模式有一次性讀取FileProcessingMode.PROCESS_ONCE和持續(xù)讀取FileProcessingMode.PROCESS_CONTINUOUSLY。),Socket接入數(shù)據(jù),自定義讀取(自定義數(shù)據(jù)讀取就是使用Flink連接器、自定義數(shù)據(jù)讀取函數(shù),與外部存儲交互,讀取數(shù)據(jù),如從Kafka、JDBC、HDFS等讀取) -
處理數(shù)據(jù)
Datastream相互轉(zhuǎn)換的關(guān)系 - 數(shù)據(jù)寫入
-
旁路輸出
旁路輸出示意圖
只有在特定的函數(shù)中才能使用旁路輸出,具體如下
1)ProcessFunction。
2)KeyedProcessFunction。
3)CoProcessFunction。
4)ProcessWindowFunction。
5)ProcessAllWindowFunction。
6)ProcessJoinFunction。
7)KeyedCoProcessFunction。
核心抽象
一. 執(zhí)行環(huán)境

- LocalStreamEnvironment:本地執(zhí)行環(huán)境,在單個(gè)JVM中使用多線程模擬Flink集群
- RemoteStreamEnvironment:在大規(guī)模數(shù)據(jù)中心中部署的Flink生成集群的執(zhí)行環(huán)境
- StreamContextEnvironment:在Cli命令行或者單元測試時(shí)候會被使用
- StreamPlanEnvironment:在Flink Web UI管理界面中可視化展現(xiàn)Job的時(shí)候,專門用來生成執(zhí)行計(jì)劃(實(shí)際上就是StreamGraph)
- ScalaShellStreamEnvironment:這是Scala Shell執(zhí)行環(huán)境,可以在命令行中交互式開發(fā)Flink作業(yè)
二. 運(yùn)行時(shí)環(huán)境

- RuntimeEnvironment:在Task開始執(zhí)行時(shí)進(jìn)行初始化,把Task運(yùn)行相關(guān)的信息都封裝到該對象中,其中不光包含了配置信息,運(yùn)行時(shí)的各種服務(wù)也會被包裝到其中
.....
public class RuntimeEnvironment implements Environment {
private final JobID jobId;
private final JobVertexID jobVertexId;
private final ExecutionAttemptID executionId;
private final TaskInfo taskInfo;
private final Configuration jobConfiguration;
private final Configuration taskConfiguration;
private final ExecutionConfig executionConfig;
private final UserCodeClassLoader userCodeClassLoader;
private final MemoryManager memManager;
private final IOManager ioManager;
private final BroadcastVariableManager bcVarManager;
private final TaskStateManager taskStateManager;
private final GlobalAggregateManager aggregateManager;
private final InputSplitProvider splitProvider;
private final ExternalResourceInfoProvider externalResourceInfoProvider;
private final Map<String, Future<Path>> distCacheEntries;
private final ResultPartitionWriter[] writers;
private final IndexedInputGate[] inputGates;
private final TaskEventDispatcher taskEventDispatcher;
private final CheckpointResponder checkpointResponder;
private final TaskOperatorEventGateway operatorEventGateway;
private final AccumulatorRegistry accumulatorRegistry;
private final TaskKvStateRegistry kvStateRegistry;
private final TaskManagerRuntimeInfo taskManagerInfo;
private final TaskMetricGroup metrics;
private final Task containingTask;
- SavepointEnvironment
三. 運(yùn)行時(shí)上下文
RuntimeContext是Function運(yùn)行時(shí)的上下文,封裝了Function運(yùn)行時(shí)可能需要的所有信息,讓Function在運(yùn)行時(shí)能夠獲取到作業(yè)級別的信息,如并行度相關(guān)信息、Task名稱、執(zhí)行配置信息(ExecutionConfig)、State等

四. 數(shù)據(jù)流元素
- StreamRecord
StreamRecord包含數(shù)據(jù)的值本身,事件戳(可選)也叫作數(shù)據(jù)記錄。 - LatencyMarker
LatencyMarker用來近似評估延遲,LatencyMarker在Source中創(chuàng)建,并向下游發(fā)送,繞過業(yè)務(wù)處理邏輯,在Sink節(jié)點(diǎn)中使用LatencyMarker估計(jì)數(shù)據(jù)在整個(gè)DAG圖中流轉(zhuǎn)花費(fèi)的時(shí)間,用來近似地評估總體上的處理延遲。LatencyMarker包含周期性地在數(shù)據(jù)源算子中創(chuàng)造出來的時(shí)間戳,算子編號,數(shù)據(jù)源算子所在的Task編號 - Watermark
Watermark是一個(gè)時(shí)間戳,用來告訴算子所有時(shí)間早于等于Watermark的事件或記錄都已經(jīng)到達(dá),不會再有比Watermark更早的記錄,算子可以根據(jù)Watermark觸發(fā)窗口的計(jì)算、清理資源等 - StreamStatus
用來通知Task是否會繼續(xù)接收到上游的記錄或者Watermark。StreamStatus在數(shù)據(jù)源算子中生成,向下游沿著Dataflow傳播,StreamStatus可以表示兩種狀態(tài):空閑狀態(tài)(IDLE),活動狀態(tài)(ACTIVE)
五. 數(shù)據(jù)轉(zhuǎn)換
-
物理Transformation
transformation類體系
物理Transformation一共有4種,具體如下 SourceTransformation,SinkTransformation,OneInputTransformation,TwoInputTransformation
- 虛擬Transformation
SideOutputTransformation(SideOutputTransformation在旁路輸出中轉(zhuǎn)換而來,表示上游Transformation的一個(gè)分流,上游Transformation可以有多個(gè)下游SideOutputTransformation),SplitTransformation,SelectTransformation,PartitionTransformation,UnionTransformation(Union運(yùn)算要求其直接上游輸入的數(shù)據(jù)的結(jié)構(gòu)必須是完全相同的),FeedbackTransformation,CoFeedbackTransformation
六. 算子
所有的算子都包含了生命周期管理、狀態(tài)與容錯管理、數(shù)據(jù)處理3個(gè)方面的關(guān)鍵行為。
生命周期管理
1)setup:初始化環(huán)境、時(shí)間服務(wù)、注冊監(jiān)控等。
2)open:該行為由各個(gè)具體的算子負(fù)責(zé)實(shí)現(xiàn),包含了算子的初始化邏輯,如狀態(tài)初始化等。算子執(zhí)行該方法之后,才會執(zhí)行Function進(jìn)行數(shù)據(jù)的處理。
3)close:所有的數(shù)據(jù)處理完畢之后關(guān)閉算子,此時(shí)需要確保將所有的緩存數(shù)據(jù)向下游發(fā)送。
4)dispose:該方法在算子生命周期的最后階段執(zhí)行,此時(shí)算子已經(jīng)關(guān)閉,停止處理數(shù)據(jù),進(jìn)行資源的釋放。
狀態(tài)與容錯管理
算子負(fù)責(zé)狀態(tài)管理,提供狀態(tài)存儲,觸發(fā)檢查點(diǎn)的時(shí)候,保存狀態(tài)快照,并且將快照異步保存到外部的分布式存儲。當(dāng)作業(yè)失敗的時(shí)候算子負(fù)責(zé)從保存的快照中恢復(fù)狀態(tài)
數(shù)據(jù)處理
算子對數(shù)據(jù)的處理,不僅會進(jìn)行數(shù)據(jù)記錄的處理,同時(shí)也會提供對Watermark和LatencyMarker的處理。算子按照單流輸入和雙流輸入,定義了不同的行為接口
七. 函數(shù)體系
-
函數(shù)層次
UDF在DataStream API層使用,F(xiàn)link提供的函數(shù)體系從接口的層級來看,從高階Function到低階Function
function層次
RichFunction相比無狀態(tài)Function,有兩方面的增強(qiáng):
1)增加了open和close方法來管理Function的生命周期,在作業(yè)啟動時(shí),F(xiàn)unction在open方法中執(zhí)行初始化,在Function停止時(shí),在close方法中執(zhí)行清理,釋放占用的資源等。無狀態(tài)Function不具備此能力。
2)增加了getRuntimeContext和setRuntimeContext。通過RuntimeContext,RichFunction能夠獲取到執(zhí)行時(shí)作業(yè)級別的參數(shù)信息,而無狀態(tài)Function不具備此能力。
無狀態(tài)Function天然是容錯的,作業(yè)失敗之后,重新執(zhí)行即可,但是有狀態(tài)的Function(RichFunction)需要處理中間結(jié)果的保存和恢復(fù),待有了狀態(tài)的訪問能力,也就意味著Function是可以容錯的,執(zhí)行過程中,狀態(tài)會進(jìn)行快照然后備份,在作業(yè)失敗,F(xiàn)unction能夠從快照中恢復(fù)回來。 -
處理函數(shù)
ProcessFunction:單流輸入函數(shù)。CoProcessFunction:雙流輸入函數(shù)。KeyedProcessFunction:單流輸入函數(shù)。KeyedCoProcessFunction:雙流輸入函數(shù)。
processfunction類體系 -
廣播函數(shù)
廣播函數(shù)體系 異步函數(shù)
-
數(shù)據(jù)源函數(shù)
SourceFunction體系 輸出函數(shù)
檢查點(diǎn)函數(shù)
八. 數(shù)據(jù)分區(qū)

- 自定義分區(qū)
- ForwardPartitioner
- ShufflePartitioner
- ReblancePartitioner
- RescalingPartitioner
- BroadcastPartitioner
- KeyGroupStreamPartitioner
九. 連接器
連接器在Flink中叫作Connector。Flink本身是計(jì)算引擎,并不提供數(shù)據(jù)存儲能力,所以需要訪問外部數(shù)據(jù),外部數(shù)據(jù)源類型繁多,連接器因此應(yīng)運(yùn)而生,它提供了從數(shù)據(jù)源讀取數(shù)據(jù)和寫入數(shù)據(jù)的能力?;赟ourceFunction和SinkFunction構(gòu)建出了種類繁多的連接器
十. 分布式ID
在分布式計(jì)算中,F(xiàn)link對所有需要進(jìn)行唯一標(biāo)識的組件、對象提供了抽象類AbstractID,因?yàn)樾枰缇W(wǎng)絡(luò)進(jìn)行傳遞,所以該類實(shí)現(xiàn)了Serializable接口,需要比較唯一標(biāo)識是否相同,所以也實(shí)現(xiàn)了Comparable接口

時(shí)間與窗口
如果想了解流處理系統(tǒng)中如何實(shí)現(xiàn)強(qiáng)一致性,可以參考MillWheel:Fault-Tolerant Stream Processing at Internet Scale和Discretized Streams:Fault-Tolerant Streaming Computation at Scale兩篇論文
一. 時(shí)間類型
- 事件時(shí)間:事件時(shí)間指事件發(fā)生時(shí)的時(shí)間,一旦確定之后再也不會改變。例如,事件被記錄在日志文件中,日志中記錄的時(shí)間戳就是事件時(shí)間。通過事件時(shí)間能夠還原出來事件發(fā)生的順序。使用事件時(shí)間的好處是不依賴操作系統(tǒng)的時(shí)鐘,無論執(zhí)行多少次,可以保證計(jì)算結(jié)果是一樣的,但計(jì)算邏輯稍微復(fù)雜,需要從每一條記錄中提取時(shí)間戳
- 處理時(shí)間處理時(shí)間指消息被計(jì)算引擎處理的時(shí)間,以各個(gè)計(jì)算節(jié)點(diǎn)的本地時(shí)間為準(zhǔn),使用處理時(shí)間依賴于操作系統(tǒng)的時(shí)鐘,重復(fù)執(zhí)行基于窗口的統(tǒng)計(jì)作業(yè),結(jié)果可能是不同的。處理時(shí)間的計(jì)算邏輯非常簡單,性能好于事件時(shí)間,延遲低于事件時(shí)間,只需要獲取當(dāng)前系統(tǒng)的時(shí)間戳即可。
- 攝取時(shí)間攝取時(shí)間指事件進(jìn)入流處理系統(tǒng)的時(shí)間,對于與一個(gè)事件來說,使用其被讀取的那一刻的時(shí)間戳作作為攝取時(shí)間。
二. 窗口類型
- Count Window
Tumble Count Window:累積固定個(gè)數(shù)的元素就視為一個(gè)窗口,該類型的窗口無法像時(shí)間窗口一樣事先切分好。
Sliding Count Window:累積固定個(gè)數(shù)的元素視為一個(gè)窗口,每超過一定個(gè)數(shù)的原則個(gè)數(shù),則產(chǎn)生一個(gè)新的窗口。 - Time Window
Tumble Time Window:表示在時(shí)間上按照事先約定的窗口大小切分的窗口,窗口之間不會相互重疊。
Sliding Time Window:表示在時(shí)間上按照事先約定的窗口大小、滑動步長切分的窗口,滑動窗口之間可能會存在相互重疊的情況。 - Session Window
Session Window是一種特殊的窗口,當(dāng)超過一段時(shí)間,該窗口沒有收到新的數(shù)據(jù)元素,則視為該窗口結(jié)束,所以無法事先確定窗口的長度、元數(shù)個(gè)數(shù),窗口之間也不會相互重疊。
三. 窗口原理與機(jī)制

-
WindowAssigner
Streaming中的WindowAssigner類體系
Blink中的WindowAssigner體系 WindowTrigger
Trigger觸發(fā)器決定了一個(gè)窗口何時(shí)能夠被計(jì)算或清除,每一個(gè)窗口都擁有一個(gè)屬于自己的Trigger,Trigger上會有定時(shí)器,用來決定一個(gè)窗口何時(shí)能夠被計(jì)算或清除。每當(dāng)有元素加入該窗口,或者之前注冊的定時(shí)器超時(shí)時(shí),Trigger都會被調(diào)用。Trigger觸發(fā)的結(jié)果如下。
1)Continue:繼續(xù),不做任何操作。
2)Fire:觸發(fā)計(jì)算,處理窗口數(shù)據(jù)。
3)Purge:觸發(fā)清理,移除窗口和窗口中的數(shù)據(jù)。
4)Fire + Purge:觸發(fā)計(jì)算+清理,處理數(shù)據(jù)并移除窗口和窗口中的數(shù)據(jù)。WindowEvictor
1)CountEvictor: 計(jì)數(shù)過濾器。在Window中保留指定數(shù)量的元素,并從窗口頭部開始丟棄其余元素。
2)DeltaEvictor: 閾值過濾器。本質(zhì)上來說就是一個(gè)自定義規(guī)則,計(jì)算窗口中每個(gè)數(shù)據(jù)記錄,然后與一個(gè)事先定義好的閾值做比較,丟棄超過閾值的數(shù)據(jù)記錄。
3)TimeEvictor: 時(shí)間過濾器。保留Window中最近一段時(shí)間內(nèi)的元素,并丟棄其余元素。Window函數(shù)
1)增量計(jì)算函數(shù)
2)全量計(jì)算函數(shù)
四. 水印
- Watermark的生成機(jī)制
(1)周期性Watermark策略周期性Watermark策略在Flink中叫作PeriodicWatermarkAssigner,周期性(一定時(shí)間間隔或者達(dá)到一定的記錄條數(shù))地產(chǎn)生一個(gè)Watermark。
1) AscendingTimestamps:遞增Watermark,作用在Flink SQL中的Rowtime屬性上,Watermark=當(dāng)前收到的數(shù)據(jù)元素的最大時(shí)間戳-1,此處減1的目的是確保有最大時(shí)間戳的事件不會被當(dāng)做遲到數(shù)據(jù)丟棄。
2)BoundedOutOfOrderTimestamps:固定延遲Watermark,作用在Flink SQL的Rowtime屬性上,Watermark=當(dāng)前收到的數(shù)據(jù)元素的最大時(shí)間戳-固定延遲。
(2)每事件Watermark策略每事件Watermark策略在Flink中叫作PuntuatedWatamarkAssigner,數(shù)據(jù)流中每一個(gè)遞增的EventTime都會產(chǎn)生一個(gè)Watermark。在實(shí)際的生產(chǎn)中Punctuated方式在TPS很高的場景下會產(chǎn)生大量的Watermark,在一定程度上會對下游算子造成壓力
(3)無為策略無為策略在Flink中叫作PreserveWatermark。在Flink中可以使用DataStream API和Table & SQL混合編程,所以Flink SQL中不設(shè)定Watermark策略,使用底層DataStream中的Watermark策略
- 多流的Watermark
Flink內(nèi)部實(shí)現(xiàn)每一個(gè)邊上只能有一個(gè)遞增的Watermark,當(dāng)出現(xiàn)多流攜帶EventTime匯聚到一起(GroupBy或Union)時(shí),Apache Flink會選擇所有流入的EventTime中最小的一個(gè)向下游流出,從而保證Watermark的單調(diào)遞增和數(shù)據(jù)的完整性
五. 時(shí)間服務(wù)
- 定時(shí)器服務(wù)
定時(shí)器服務(wù)在Flink中叫作TimerService,窗口算子(WindowOperator)中使用了InternalTimerService來管理定時(shí)器(Timer),其初始化是在WindowOperator#open()中實(shí)現(xiàn)的 - 定時(shí)器
- 優(yōu)先級隊(duì)列
六. 窗口實(shí)現(xiàn)

- 時(shí)間窗口
- 會話窗口??
在Flink中提供了4種Session Window的默認(rèn)實(shí)現(xiàn)
1)ProcessingTimeSessionWindows:處理時(shí)間會話窗口,使用固定會話間隔時(shí)長。
2)DynamicProcessingTimeSessionWindows:處理時(shí)間會話窗口,使用自定義會話間隔時(shí)長。
3)EventTimeSessionWindows:事件時(shí)間會話窗口,使用固定會話間隔時(shí)長。
4)DynamicEventTimeSessionWindows:事件時(shí)間會話窗口,使用自定義會話間隔時(shí)長。 - 計(jì)數(shù)窗口
類型與序列化
Flink內(nèi)部自主進(jìn)行內(nèi)存管理,將數(shù)據(jù)以二進(jìn)制結(jié)構(gòu)保存在內(nèi)存中,目前的實(shí)現(xiàn)中大量使用了堆外內(nèi)存。如果讓開發(fā)人員直接操作二進(jìn)制結(jié)構(gòu),代碼會變得復(fù)雜臃腫,所以大數(shù)據(jù)平臺在設(shè)計(jì)API的時(shí)候,允許用戶直接像編寫普通Java應(yīng)用程序一樣使用其API開發(fā)Function,直接使用JDK提供的類型和自定義類型。

一. 物理類型

二. 邏輯類型

三. 類型推斷
四. 顯式類型
五. Flink Row
六. Blink Row
七. ColumnarRow
內(nèi)存管理
一. 自主內(nèi)存管理
- JVM內(nèi)存管理的不足
垃圾回收
有效數(shù)據(jù)密度低
OOM問題影響穩(wěn)定性
緩存未命中問題 - 自主內(nèi)存管理
因?yàn)镴VM存在諸多問題,所以越來越多的大數(shù)據(jù)計(jì)算引擎選擇自行管理JVM內(nèi)存,如Spark、Flink、HBase,盡量達(dá)到C/C++ 一樣的性能,同時(shí)避免OOM的發(fā)生。 - 堆外內(nèi)存的不足之處
二. 內(nèi)存模型
-
內(nèi)存布局
TaskManager是Flink中執(zhí)行計(jì)算的核心組件,是用來運(yùn)行用戶代碼的Java進(jìn)程。其中大量使用了堆外內(nèi)存。
Flink TaskManager簡化和詳細(xì)內(nèi)存模型 - 內(nèi)存計(jì)算
三. 內(nèi)存數(shù)據(jù)結(jié)構(gòu)
四. 內(nèi)存管理器
五. 網(wǎng)絡(luò)緩沖器
狀態(tài)管理
一. 狀態(tài)類型
(1)ValueState<T>即類型為T的單值狀態(tài)。這個(gè)狀態(tài)與對應(yīng)的Key綁定,是最簡單的狀態(tài)。可以通過update方法更新狀態(tài)值,通過value()方法獲取狀態(tài)值。
(2)ListState<T>即Key上的狀態(tài)值為一個(gè)列表。可以通過add方法往列表中附加值;也可以通過get()方法返回一個(gè)Iterable<T>來遍歷狀態(tài)值。
(3)ReducingState<T>這種狀態(tài)通過用戶傳入的reduceFunction,每次調(diào)用add方法添加值時(shí),會調(diào)用reduceFunction,最后合并到一個(gè)單一的狀態(tài)值。
(4)AggregatingState<IN,OUT>聚合State,和(3)不同的是,這里聚合的類型可以是不同的元素類型,使用add(IN)來加入元素,并使用AggregateFunction函數(shù)計(jì)算聚合結(jié)果。
(5)MapState<UK,UV>使用Map存儲Key-Value對,通過put(UK,UV)或者putAll(Map<UK,UV>)來添加,使用get(UK)來獲取。
二. 原始和托管狀態(tài)
按照由Flink管理還是用戶自行管理,狀態(tài)可以分為原始狀態(tài)(Raw State)和托管狀態(tài)(Managed State)。原始狀態(tài),即用戶自定義的State,F(xiàn)link在做快照的時(shí)候,把整個(gè)State當(dāng)作一個(gè)整體,需要開發(fā)者自己管理,使用byte數(shù)組來讀寫狀態(tài)內(nèi)容。托管狀態(tài)是由Flink框架管理的State,如ValueState、ListState、MapState等,其序列化與反序列化由Flink框架提供支持,無須用戶感知、干預(yù)。KeyedState和OperatorState可以是原始狀態(tài),也可以是托管狀態(tài)。通常在DataStream上的狀態(tài)推薦使用托管狀態(tài),一般情況下,在實(shí)現(xiàn)自定義算子時(shí),才會使用到原始狀態(tài)。
三. 狀態(tài)描述

四. 廣播狀態(tài)

在圖可以看到,業(yè)務(wù)數(shù)據(jù)流是一個(gè)普通數(shù)據(jù)流,規(guī)則數(shù)據(jù)流是廣播數(shù)據(jù)流,這樣就可以滿足實(shí)時(shí)性、規(guī)則更新的要求。規(guī)則算子將規(guī)則緩存在本地內(nèi)存中,在業(yè)務(wù)數(shù)據(jù)流記錄到來時(shí),能夠使用規(guī)則處理數(shù)據(jù)。
五. 狀態(tài)接口
六. 狀態(tài)存儲

七. 狀態(tài)持久化
八. 狀態(tài)重分布
- OperatorState重分布
- KeyedState重分布
九. 狀態(tài)過期
- DataStream中狀態(tài)過期
- Flink SQL中狀態(tài)過期
Flink SQL是數(shù)據(jù)分析的高層抽象,在SQL的世界里并無State的概念,而在流Join、聚合類的場景中,使用了State,如果State不定時(shí)清理,則可能會導(dǎo)致State過多,內(nèi)存溢出,為了穩(wěn)妥起見,最好為每個(gè)Flink SQL作業(yè)提供State清理的策略。如果定時(shí)清理State,則存在可能因?yàn)镾tate被清理而導(dǎo)致計(jì)算結(jié)果不完全準(zhǔn)確的風(fēng)險(xiǎn),F(xiàn)link的Table API和SQL接口中提供了參數(shù)設(shè)置選項(xiàng),能夠讓使用者在精確和資源消耗做折中 - 狀態(tài)過期清理
默認(rèn)情況下,只有在明確讀出過期值時(shí)才會刪除過期值,如通過調(diào)用ValueState#value()
作業(yè)提交
一. 提交流程

二. Graph總覽
三. 流圖
四. 作業(yè)圖
五. 執(zhí)行圖
資源管理
一. 資源抽象

二. 資源管理器
資源管理器在Flink中叫作ResourceManager。Flink同時(shí)支持不同的資源集群類型,ResourceManager位于Flink和資源管理集群(Yarn、K8s等)之間,是Flink集群級資源管理的抽象,其主要作用如下
1)申請容器啟動新的TM,或者為作業(yè)申請Slot。
2)處理JobManager和TaskManager的異常退出。
3)緩存TaskManager(即容器),等待一段時(shí)間之后再釋放掉不用的容器,避免資源反復(fù)地申請釋放。
4)JobManager和TaskManager的心跳感知,對JobManager和TaskManger的退出進(jìn)行對應(yīng)的處理
三. Slot管理器
Slot管理器在Flink中叫作SlotManager,是ResourceManager的組件,從全局角度維護(hù)當(dāng)前有多少TaskManager、每個(gè)TaskManager有多少空閑的Slot和Slot等資源的使用情況。當(dāng)Flink作業(yè)調(diào)度執(zhí)行時(shí),根據(jù)Slot分配策略為Task分配執(zhí)行的位置
1)對TaskManager提供注冊、取消注冊、空閑退出等管理動作,注冊則集群可用的Slot變多,取消注冊、空閑推出則釋放資源,還給資源管理集群。
2)對Flink作業(yè),接收Slot的請求和釋放、資源匯報(bào)等。當(dāng)資源不足的時(shí)候,SlotManger將資源請求暫存在等待隊(duì)列中,SlotManager通知ResourceManager去申請更多的資源,啟動新的TaskManager,TaskManager注冊到SlotManager之后,SlotManager就有可用的新資源了,從等待隊(duì)列中依次分配資源。
四. SlotProvider
SlotProvider接口定義了Slot的請求行為,支持兩種請求模式。
1)立即響應(yīng)模式:Slot請求會立即執(zhí)行。
2)排隊(duì)模式:排隊(duì)等待可用Slot,當(dāng)資源可用時(shí)分配資源
五. Slot選擇策略
六. Slot資源池
Slot資源池在Flink中叫作SlotPool,是JobMaster中記錄當(dāng)前作業(yè)從TaskManager獲取的Slot的集合。
七. Slot共享
作業(yè)調(diào)度
一. 調(diào)度
二. 執(zhí)行模式
- 流水線模式即Pipelined,此模式以流水線方式(包括Shuffle和廣播數(shù)據(jù))執(zhí)行作業(yè),但流水線可能會出現(xiàn)死鎖的數(shù)據(jù)交換除外。如果可能會出現(xiàn)數(shù)據(jù)交換死鎖,則數(shù)據(jù)交換以Batch方式執(zhí)行。當(dāng)數(shù)據(jù)流被多個(gè)下游分支消費(fèi)處理,處理后的結(jié)果再進(jìn)行Join時(shí),如果以Pipelined模式運(yùn)行,則可能出現(xiàn)數(shù)據(jù)交換死鎖
- 強(qiáng)制流水線模式即Pipelined_Forced,此模式以流水線方式(包括shuffle和broadcast數(shù)據(jù))執(zhí)行作業(yè),即便流水線可能會出現(xiàn)死鎖的數(shù)據(jù)交換時(shí)仍然執(zhí)行。一般情況下,Pipelined模式是優(yōu)先選擇,確保不會出現(xiàn)數(shù)據(jù)死鎖的情況下才會使用Pipelined_Forced模式
- 流水線優(yōu)先模式即Pipelined_With_Batch_Fallback,此模式首先使用Pipelined啟動作業(yè),如果可能死鎖則使用Pipelined_Forced啟動作業(yè)。當(dāng)作業(yè)異常退出時(shí),則使用Batch模式重新執(zhí)行作業(yè)
- 批處理模式即Batch,此模式對于所有的shuffle和broadcast都使用Batch模式執(zhí)行,僅本地的數(shù)據(jù)交換使用Pipelined模式。
- 強(qiáng)制批處理模式即Batch_Forced,此模式對于所有的數(shù)據(jù)交換都使用Batch模式,對于本地交換也不例外
三. 數(shù)據(jù)交換
- BLOCKINGBLOCKING類型的數(shù)據(jù)分區(qū)會等待數(shù)據(jù)完全處理完畢,然后才會交給下游進(jìn)行處理,在上游處理完畢之前,不會與下游進(jìn)行數(shù)據(jù)交換。該類型的數(shù)據(jù)分區(qū)可以被多次消費(fèi),也可以并發(fā)消費(fèi)。被消費(fèi)完畢之后不會自動釋放,而是等待調(diào)度器來判斷該數(shù)據(jù)分區(qū)無人再消費(fèi)之后,由調(diào)度器發(fā)出銷毀指令。該模式適用于批處理,不提供反壓流控能力。
- BLOCKING_PERSISTENTBLOCKING_PERSISTENT類型的數(shù)據(jù)分區(qū)類似于BLOCKING,但是其生命周期由用戶指定。調(diào)用JobManager或者ResourceManager API進(jìn)行銷毀,而不是由調(diào)度器控制。
- PIPELINEDPIPELINED(流水線)式數(shù)據(jù)交換適用于流計(jì)算和批處理。數(shù)據(jù)處理結(jié)果只能被1個(gè)消費(fèi)者(下游的算子)消費(fèi)1次,當(dāng)數(shù)據(jù)被消費(fèi)之后即自動銷毀。PIPELINED分區(qū)可能會保存一定數(shù)據(jù)的數(shù)據(jù),與PIPELINED_BOUNDED相反。此結(jié)果分區(qū)類型可以在運(yùn)行中保留任意數(shù)量的數(shù)據(jù)。當(dāng)數(shù)據(jù)量太大內(nèi)存無法容納時(shí),可以寫入磁盤中。
- PIPELINED_BOUNDEDPIPELINED_BOUNDED是PIPELINED帶有一個(gè)有限大小的本地緩沖池。對于流計(jì)算作業(yè)來說,固定大小的緩沖池可以避免緩沖太多的數(shù)據(jù)和檢查點(diǎn)延遲太久。不同于限制整體網(wǎng)絡(luò)緩沖池的大小,該模式下允許根據(jù)分區(qū)的總數(shù)彈性地選擇網(wǎng)絡(luò)緩沖池的大小。對于批處理作業(yè)來說,最好使用無限制的PIPELINED數(shù)據(jù)交換模式,因?yàn)樵谂幚砟J较聸]有CheckpointBarrier,其實(shí)現(xiàn)Exactly-Once與流計(jì)算不同。
四. 作業(yè)生命周期
五. 關(guān)鍵組件
六. 作業(yè)啟動??
七. 作業(yè)停止
八. 作業(yè)失敗調(diào)度
九. 組件容錯
作業(yè)執(zhí)行
一. 作業(yè)執(zhí)行圖
二. 核心對象
三. task執(zhí)行
數(shù)據(jù)交換
一. 數(shù)據(jù)傳遞模式
二. 關(guān)鍵組件
三. 數(shù)據(jù)傳遞
四. 數(shù)據(jù)傳遞過程
五. 網(wǎng)絡(luò)通信
應(yīng)用容錯
一. 容錯保證語義
二. 檢查點(diǎn)和保存點(diǎn)
- 檢查點(diǎn)在Flink中叫作Checkpoint,是Flink實(shí)現(xiàn)應(yīng)用容錯的核心機(jī)制,根據(jù)配置周期性通知Stream中各個(gè)算子的狀態(tài)來生成檢查點(diǎn)快照,從而將這些狀態(tài)數(shù)據(jù)定期持久化存儲下來,F(xiàn)link程序一旦意外崩潰,重新運(yùn)行程序時(shí)可以有選擇地從這些快照進(jìn)行恢復(fù),將應(yīng)用恢復(fù)到最后一次快照的狀態(tài),從此刻開始重新執(zhí)行,避免數(shù)據(jù)的丟失、重復(fù)。
- 保存點(diǎn)在Flink中叫作Savepoint,是基于Flink檢查點(diǎn)機(jī)制的應(yīng)用完整快照備份機(jī)制,用來保存狀態(tài),可以在另一個(gè)集群或者另一個(gè)時(shí)間點(diǎn),從保存的狀態(tài)中將作業(yè)恢復(fù)回來,適用于應(yīng)用升級、集群遷移、Flink集群版本更新、A/B測試以及假定場景、暫停和重啟、歸檔等場景。
三. 作業(yè)恢復(fù)
四. 關(guān)鍵組件
五. 輕量級異步分布式快照
六. 檢查點(diǎn)執(zhí)行過程
七. 檢查點(diǎn)恢復(fù)過程
八. 端對端嚴(yán)格一次
-
預(yù)提交階段
檢查點(diǎn)過程示例
這種方式只能在數(shù)據(jù)源Kafka到Flink內(nèi)部保證嚴(yán)格一次,一旦涉及從Sink寫入到外部Kafka就會出現(xiàn)問題了。假設(shè)Checkpoint 3完成之后,Source從Topic偏移量位置65536讀取了1000條數(shù)據(jù),Topic偏移量為66536,Sink寫入了1000條數(shù)據(jù)到外部Kafka,此時(shí)Flink應(yīng)用的1個(gè)Sink并行實(shí)例因?yàn)槲刺幚淼漠惓1罎?,進(jìn)入Failover階段,應(yīng)用自動從Checkpoint 3恢復(fù),重新從Topic的偏移量65536開始讀取數(shù)據(jù),這就會導(dǎo)致65536~66536之間的1000條數(shù)據(jù)被重復(fù)處理,寫入到了Kafka中。這種情況下需要避免重復(fù)寫入這1000條數(shù)據(jù)到Kafka中。冪等性是一種解決方案,如對HBase按照主鍵插入可能有效,第2次插入是對第1次的更新。
兩階段協(xié)議-預(yù)提交階段 -
提交階段
兩階段協(xié)議——提交階段
在預(yù)提交階段,數(shù)據(jù)實(shí)際上已經(jīng)寫入外部存儲,但是因?yàn)槭聞?wù)的原因是不可讀的,所以Sink在事務(wù)提交階段的工作稍微簡單一點(diǎn),當(dāng)所有的Sink實(shí)例提交成功之后,一旦預(yù)提交完成,必須確保提交外部事務(wù)也要成功,此時(shí)算子和外部系統(tǒng)協(xié)同來保證。倘若提交外部事務(wù)失?。ㄈ缇W(wǎng)絡(luò)故障等),F(xiàn)link應(yīng)用就會崩潰,然后根據(jù)用戶重啟策略進(jìn)行回滾,回滾到預(yù)提交時(shí)的狀態(tài),之后再次重試提交。
SQL
一. Calcite
二. 動態(tài)表
三. TableEnvironment
四. Table API

五. SQL API
六. 元數(shù)據(jù)
七. 數(shù)據(jù)訪問
八. SQL函數(shù)
九. Planner關(guān)鍵抽象
運(yùn)維監(jiān)控
一. 監(jiān)控指標(biāo)
二. 指標(biāo)組
三. 監(jiān)控集成
四. 指標(biāo)注冊中心
五. 指標(biāo)查詢服務(wù)
六. 延遲跟蹤實(shí)現(xiàn)原理
疑惑和難點(diǎn)
會話窗口不同于事件窗口,它的切分依賴于事件的行為,而不是時(shí)間序列,所以在很多情況下會因?yàn)槭录y序使得原本相互獨(dú)立的窗口因?yàn)樾率录牡絹韺?dǎo)致窗口重疊,而必須要進(jìn)行窗口的合并???(過程)












