Flink 極簡(jiǎn)教程: 架構(gòu)及原理 Apache Flink? — Stateful Computations over Data Streams
關(guān)鍵詞
分布式流處理
分布式計(jì)算引擎
All streaming use cases
- Event-driven Applications
- Stream & Batch Analytics
- Data Pipelines & ETL
Guaranteed correctness
- Exactly-once state consistency
- Event-time processing
- Sophisticated late data handling
Layered APIs
- SQL on Stream & Batch Data
- DataStream API & DataSet API
- ProcessFunction (Time & State)
Operational Focus
- Flexible deployment
- High-availability setup
- Savepoints
Scales to any use case
- Scale-out architecture
- Support for very large state
- Incremental checkpointing
Excellent Performance
- Low latency
- High throughput
- In-Memory computing
Flink 是什么?
Apache Flink 是一個(gè)分布式流計(jì)算引擎责静,用于在無(wú)邊界和有邊界數(shù)據(jù)流上進(jìn)行有狀態(tài)的計(jì)算劫笙。
Flink 的核心是用Java和Scala編寫的分布式流數(shù)據(jù)流引擎莲组。Flink以數(shù)據(jù)并行和流水線方式執(zhí)行任意流數(shù)據(jù)程序规惰,F(xiàn)link的流水線運(yùn)行時(shí)系統(tǒng)可以執(zhí)行批處理和流處理程序姜挺。此外怨咪,F(xiàn)link的運(yùn)行時(shí)本身也支持迭代算法的執(zhí)行牍颈。
Flink 能在所有常見集群環(huán)境中運(yùn)行烘挫,并能以內(nèi)存速度和任意規(guī)模進(jìn)行計(jì)算阿蝶。
參考: https://flink.apache.org/zh/flink-architecture.html
Apache Flink是一個(gè)面向分布式數(shù)據(jù)流處理和批量數(shù)據(jù)處理的開源計(jì)算平臺(tái)雳锋,它能夠基于同一個(gè)Flink運(yùn)行時(shí)(Flink Runtime),提供支持流處理和批處理兩種類型應(yīng)用的功能羡洁。
現(xiàn)有的開源計(jì)算方案玷过,會(huì)把流處理和批處理作為兩種不同的應(yīng)用類型,因?yàn)樗麄兯鼈兯峁┑腟LA是完全不相同的:流處理一般需要支持低延遲筑煮、Exactly-once保證辛蚊,而批處理需要支持高吞吐、高效處理真仲,所以在實(shí)現(xiàn)的時(shí)候通常是通過(guò)一個(gè)獨(dú)立的開源框架來(lái)實(shí)現(xiàn)其中每一種處理方案袋马。
1.實(shí)現(xiàn)批處理的開源方案有 MapReduce、Tez秸应、Crunch虑凛、Spark.
2.實(shí)現(xiàn)流處理的開源方案有 Samza、Storm .
Flink在實(shí)現(xiàn)流處理和批處理時(shí)软啼,與傳統(tǒng)的一些方案完全不同桑谍,它從另一個(gè)視角看待流處理和批處理,將二者統(tǒng)一起來(lái):Flink是完全支持流處理祸挪,也就是說(shuō)作為流處理看待時(shí)輸入數(shù)據(jù)流是無(wú)界的锣披;批處理被作為一種特殊的流處理,只是它的輸入數(shù)據(jù)流被定義為有界的。
基于同一個(gè)Flink運(yùn)行時(shí)(Flink Runtime)雹仿,分別提供了流處理和批處理API增热,而這兩種API也是實(shí)現(xiàn)上層面向流處理、批處理類型應(yīng)用框架的基礎(chǔ)胧辽。
基本特性
關(guān)于Flink所支持的特性峻仇,我這里只是通過(guò)分類的方式簡(jiǎn)單做一下梳理,涉及到具體的一些概念及其原理會(huì)在后面的部分做詳細(xì)說(shuō)明票顾。
流處理特性
支持高吞吐础浮、低延遲、高性能的流處理
支持帶有事件時(shí)間的窗口(Window)操作
支持有狀態(tài)計(jì)算的Exactly-once語(yǔ)義
支持高度靈活的窗口(Window)操作奠骄,支持基于time、count番刊、session含鳞,以及data-driven的窗口操作
支持具有Backpressure功能的持續(xù)流模型
支持基于輕量級(jí)分布式快照(Snapshot)實(shí)現(xiàn)的容錯(cuò)
一個(gè)運(yùn)行時(shí)同時(shí)支持Batch on Streaming處理和Streaming處理
Flink在JVM內(nèi)部實(shí)現(xiàn)了自己的內(nèi)存管理
支持迭代計(jì)算
支持程序自動(dòng)優(yōu)化:避免特定情況下Shuffle、排序等昂貴操作芹务,中間結(jié)果有必要進(jìn)行緩存
API支持
對(duì)Streaming數(shù)據(jù)類應(yīng)用蝉绷,提供DataStream API
對(duì)批處理類應(yīng)用,提供DataSet API(支持Java/Scala)
Libraries支持
支持機(jī)器學(xué)習(xí)(FlinkML)
支持圖分析(Gelly)
支持關(guān)系數(shù)據(jù)處理(Table)
支持復(fù)雜事件處理(CEP)
整合支持
支持Flink on YARN
支持HDFS
支持來(lái)自Kafka的輸入數(shù)據(jù)
支持Apache HBase
支持Hadoop程序
支持Tachyon
支持ElasticSearch
支持RabbitMQ
支持Apache Storm
支持S3
支持XtreemFS
基本概念
Stream
Transformation
Operator
用戶實(shí)現(xiàn)的Flink程序是由Stream和Transformation這兩個(gè)基本構(gòu)建塊組成枣抱,其中Stream是一個(gè)中間結(jié)果數(shù)據(jù)熔吗,而Transformation是一個(gè)操作,它對(duì)一個(gè)或多個(gè)輸入Stream進(jìn)行計(jì)算處理佳晶,輸出一個(gè)或多個(gè)結(jié)果Stream桅狠。當(dāng)一個(gè)Flink程序被執(zhí)行的時(shí)候,它會(huì)被映射為Streaming Dataflow轿秧。一個(gè)Streaming Dataflow是由一組Stream和Transformation Operator組成中跌,它類似于一個(gè)DAG圖,在啟動(dòng)的時(shí)候從一個(gè)或多個(gè)Source Operator開始菇篡,結(jié)束于一個(gè)或多個(gè)Sink Operator漩符。
Dataflow Programming Model
Flink核心是一個(gè)流式的數(shù)據(jù)流執(zhí)行引擎,并且能夠基于同一個(gè)Flink運(yùn)行時(shí)驱还,提供支持流處理和批處理兩種類型應(yīng)用嗜暴。
Flink 針對(duì)數(shù)據(jù)流的分布式計(jì)算提供了數(shù)據(jù)分布,數(shù)據(jù)通信及容錯(cuò)機(jī)制等功能议蟆∶屏ぃ基于流執(zhí)行引擎,F(xiàn)link提供了跟多高抽象層的API , 便于用戶編寫分布式任務(wù)咪鲜。
Levels of Abstraction
Flink offers different levels of abstraction to develop streaming/batch applications.
最低級(jí)別的抽象只是提供有狀態(tài)的流(stateful streaming)狐赡。它 通過(guò)Process Function嵌入到DataStream API 中悼吱。它允許用戶自由處理來(lái)自一個(gè)或多個(gè)流的事件,并使用一致的容錯(cuò)狀態(tài)奠滑。此外载萌,用戶可以注冊(cè)事件時(shí)間和處理時(shí)間回調(diào),允許程序?qū)崿F(xiàn)復(fù)雜的計(jì)算览祖。
DataStream API (bounded/unbounded streams) and the DataSet API (bounded data sets)
: 實(shí)際上孝鹊,大多數(shù)應(yīng)用程序不需要上述低級(jí)抽象,而是針對(duì)核心 API 進(jìn)行編程展蒂, 例如DataStream API(有界/無(wú)界流)和DataSet API (有界數(shù)據(jù)集)又活。這些流暢的 API 為數(shù)據(jù)處理提供了通用的構(gòu)建塊,如各種形式的用戶指定的轉(zhuǎn)換锰悼、連接柳骄、聚合、窗口箕般、狀態(tài)等耐薯。這些 API 中處理的數(shù)據(jù)類型在各自的編程語(yǔ)言中表示為類。低級(jí)Process Function與DataStream API集成丝里,使得僅對(duì)某些操作進(jìn)行低級(jí)抽象成為可能曲初。該數(shù)據(jù)集API提供的有限數(shù)據(jù)集的其他原語(yǔ),如循環(huán)/迭代杯聚。表API: The Table API is a declarative DSL centered around tables, which may be dynamically changing tables (when representing streams)臼婆。Tables have a schema attached (similar to tables in relational databases) and the API offers comparable operations, such as select, project, join, group-by, aggregate, etc. Table API programs declaratively define what logical operation should be done rather than specifying exactly how the code for the operation looks. Though the Table API is extensible by various types of user-defined functions, it is less expressive than the Core APIs, but more concise to use (less code to write). In addition, Table API programs also go through an optimizer that applies optimization rules before execution 。盡管 Table API 可以通過(guò)各種類型的用戶定義函數(shù)進(jìn)行擴(kuò)展幌绍,但它的表現(xiàn)力不如核心 API颁褂,但使用起來(lái)更簡(jiǎn)潔(編寫的代碼更少)。此外纷捞,Table API 程序在執(zhí)行前還會(huì)經(jīng)過(guò)一個(gè)優(yōu)化器痢虹,該優(yōu)化器會(huì)應(yīng)用優(yōu)化規(guī)則。
可以在表和DataStream / DataSet之間無(wú)縫轉(zhuǎn)換主儡,允許程序混合Table API以及DataStream 和DataSet API奖唯。 One can seamlessly convert between tables and DataStream/DataSet, allowing programs to mix Table API and with the DataStream and DataSet APIs.
- Flink 提供的最高級(jí)別抽象是SQL。這種抽象在語(yǔ)義和表達(dá)上都類似于Table API糜值,但將程序表示為 SQL 查詢表達(dá)式丰捷。在SQL抽象與表API SQL查詢緊密地相互作用,并且可以在中定義的表執(zhí)行表API寂汇。
- The highest level abstraction offered by Flink is SQL. This abstraction is similar to the Table API both in semantics and expressiveness, but represents programs as SQL query expressions. The SQL abstraction closely interacts with the Table API, and SQL queries can be executed over tables defined in the Table API.
下面具體介紹常見的幾種API:
DataSet API
對(duì)靜態(tài)數(shù)據(jù)進(jìn)行批處理作業(yè)病往,將靜態(tài)數(shù)據(jù)抽象成分布式的數(shù)據(jù)集,用戶可以方便的使用Flink提供的各種操作符對(duì)分布式數(shù)據(jù)集進(jìn)行處理骄瓣,支持Java,Scala和python停巷;
DataStream API
對(duì)數(shù)據(jù)流進(jìn)行流處理作業(yè),將流式的數(shù)據(jù)抽象成分布式的數(shù)據(jù)流,用戶可以方面的對(duì)分布式數(shù)據(jù)流進(jìn)行各種操作畔勤,支持Java蕾各,scala和python;
Table API
對(duì)結(jié)構(gòu)化數(shù)據(jù)進(jìn)行查詢操作庆揪,將結(jié)構(gòu)化數(shù)據(jù)抽象成關(guān)系表式曲,并通過(guò)SQL的DSL對(duì)關(guān)系表進(jìn)行各種查詢操作,支持Java和Scala;
SQL
SQL查詢是使用TableEnvironment的sqlquery()方法執(zhí)行的缸榛,該方法以SQL的形式返回SQL查詢的結(jié)果吝羞。Table可以在后續(xù)的SQL和Table API查詢中使用,可以轉(zhuǎn)換誒DataSet和DataStream内颗,也可以寫入TableSink钧排。SQL和Table API可以無(wú)縫的整合,進(jìn)行整體優(yōu)化并轉(zhuǎn)換為單個(gè)程序均澳。要訪問(wèn)SQL中查詢的表卖氨,必須在TableEnvironment中注冊(cè)他,可以從TableSource,Table,DataStream和DataSet注冊(cè)表负懦,用戶也可以在TableEnvironment中注冊(cè)外部目錄以制定數(shù)據(jù)源的位置。Blink開源后柏腻,將使Flink SQL更加完善穩(wěn)定纸厉。
StateFul Stream Processing
最低級(jí)抽象只提供有狀態(tài)流,通過(guò)Process Function嵌入到DataStream API中五嫂,它允許用戶自由處理來(lái)自一個(gè)或者多個(gè)流的時(shí)間颗品,并使用一致的容錯(cuò)狀態(tài),此外用戶可以注冊(cè)event time和processing time回調(diào)沃缘,允許程序?qū)崿F(xiàn)復(fù)雜的計(jì)算躯枢。
程序和數(shù)據(jù)流 Programs and Dataflows
Flink 程序的基本構(gòu)建塊是流和轉(zhuǎn)換。(請(qǐng)注意槐臀,F(xiàn)link 的 DataSet API 中使用的 DataSet 在內(nèi)部也是流——稍后會(huì)詳細(xì)介紹锄蹂。)從概念上講,流是(可能永無(wú)止境的)數(shù)據(jù)記錄流水慨,而轉(zhuǎn)換是將一個(gè)或多個(gè)流作為輸入得糜,并因此產(chǎn)生一個(gè)或多個(gè)輸出流。
當(dāng)執(zhí)行時(shí)晰洒,F(xiàn)link 程序被映射到流數(shù)據(jù)流朝抖,由流和轉(zhuǎn)換操作符組成。每個(gè)數(shù)據(jù)流以一個(gè)或多個(gè)源開始谍珊,以一個(gè)或多個(gè)接收器結(jié)束治宣。數(shù)據(jù)流類似于任意有向無(wú)環(huán)圖 (DAG)。
并行數(shù)據(jù)流 Parallel Dataflows
Flink 中的程序本質(zhì)上是并行和分布式的。在執(zhí)行過(guò)程中侮邀,一個(gè)流有一個(gè)或多個(gè)流分區(qū)坏怪,每個(gè)算子有一個(gè)或多個(gè)算子子任務(wù)。運(yùn)算符子任務(wù)彼此獨(dú)立豌拙,并在不同的線程中執(zhí)行陕悬,并且可能在不同的機(jī)器或容器上執(zhí)行。
運(yùn)算符子任務(wù)的數(shù)量是該特定運(yùn)算符的并行度按傅。流的并行性始終是其生產(chǎn)運(yùn)算符的并行性捉超。同一程序的不同操作符可能具有不同級(jí)別的并行性。
Streams can transport data between two operators in a one-to-one (or forwarding) pattern, or in a redistributing pattern:
One-to-one streams (for example between the Source and the map() operators in the figure above) preserve the partitioning and ordering of the elements. That means that subtask[1] of the map() operator will see the same elements in the same order as they were produced by subtask[1] of the Source operator.
Redistributing streams (as between map() and keyBy/window above, as well as between keyBy/window and Sink) change the partitioning of streams. Each operator subtask sends data to different target subtasks, depending on the selected transformation. Examples are keyBy() (which re-partitions by hashing the key), broadcast(), or rebalance() (which re-partitions randomly). In a redistributing exchange the ordering among the elements is only preserved within each pair of sending and receiving subtasks (for example, subtask[1] of map() and subtask[2] of keyBy/window). So in this example, the ordering within each key is preserved, but the parallelism does introduce non-determinism regarding the order in which the aggregated results for different keys arrive at the sink.
Details about configuring and controlling parallelism can be found in the docs on parallel execution.
Windows
聚合事件(例如唯绍,計(jì)數(shù)拼岳、總和)在流上的工作方式與在批處理中的工作方式不同。例如况芒,不可能對(duì)流中的所有元素進(jìn)行計(jì)數(shù)惜纸,因?yàn)榱魍ǔJ菬o(wú)限的(無(wú)界)。相反绝骚,流上的聚合(計(jì)數(shù)耐版、總和等)由windows限定范圍,例如“過(guò)去 5 分鐘內(nèi)的計(jì)數(shù)”或“最后 100 個(gè)元素的總和”压汪。
Windows 可以是時(shí)間驅(qū)動(dòng)的(例如:每 30 秒)或數(shù)據(jù)驅(qū)動(dòng)的(例如:每 100 個(gè)元素)粪牲。通常區(qū)分不同類型的窗口,例如翻滾窗口(無(wú)重疊)止剖、 滑動(dòng)窗口(有重疊)和會(huì)話窗口(由不活動(dòng)的間隙打斷)腺阳。
Aggregating events (e.g., counts, sums) works differently on streams than in batch processing. For example, it is impossible to count all elements in a stream, because streams are in general infinite (unbounded). Instead, aggregates on streams (counts, sums, etc), are scoped by windows, such as “count over the last 5 minutes”, or “sum of the last 100 elements”.
Windows can be time driven (example: every 30 seconds) or data driven (example: every 100 elements). One typically distinguishes different types of windows, such as tumbling windows (no overlap), sliding windows (with overlap), and session windows (punctuated by a gap of inactivity).
Time
在流式程序中提及時(shí)間時(shí)(例如定義窗口),可以指代不同的時(shí)間概念:
事件時(shí)間是創(chuàng)建事件的時(shí)間穿香。它通常由事件中的時(shí)間戳描述亭引,例如由生產(chǎn)傳感器或生產(chǎn)服務(wù)附加。Flink 通過(guò)時(shí)間戳分配器訪問(wèn)事件時(shí)間戳皮获。
攝取時(shí)間是事件在源運(yùn)營(yíng)商處進(jìn)入 Flink 數(shù)據(jù)流的時(shí)間焙蚓。
處理時(shí)間是執(zhí)行基于時(shí)間的操作的每個(gè)操作員的本地時(shí)間。
When referring to time in a streaming program (for example to define windows), one can refer to different notions of time:
Event Time is the time when an event was created. It is usually described by a timestamp in the events, for example attached by the producing sensor, or the producing service. Flink accesses event timestamps via timestamp assigners.
Ingestion time is the time when an event enters the Flink dataflow at the source operator.
Processing Time is the local time at each operator that performs a time-based operation.
Stateful Operations
雖然數(shù)據(jù)流中的許多操作一次只查看一個(gè)單獨(dú)的事件(例如事件解析器)魔市,但有些操作會(huì)記住多個(gè)事件的信息(例如窗口操作符)主届。這些操作稱為有狀態(tài)的。
有狀態(tài)操作的狀態(tài)可以被視為嵌入式鍵/值存儲(chǔ)待德。狀態(tài)與有狀態(tài)操作符讀取的流一起被嚴(yán)格地劃分和分布君丁。因此,在keyBy()函數(shù)之后将宪,只能在鍵控流上訪問(wèn)鍵/值狀態(tài)绘闷,并且僅限于與當(dāng)前事件鍵關(guān)聯(lián)的值橡庞。對(duì)齊流和狀態(tài)的鍵可確保所有狀態(tài)更新都是本地操作,保證一致性而沒(méi)有事務(wù)開銷印蔗。這種對(duì)齊還允許 Flink 重新分配狀態(tài)并透明地調(diào)整流分區(qū)扒最。
While many operations in a dataflow simply look at one individual event at a time (for example an event parser), some operations remember information across multiple events (for example window operators). These operations are called stateful.
The state of stateful operations is maintained in what can be thought of as an embedded key/value store. The state is partitioned and distributed strictly together with the streams that are read by the stateful operators. Hence, access to the key/value state is only possible on keyed streams, after a keyBy() function, and is restricted to the values associated with the current event’s key. Aligning the keys of streams and state makes sure that all state updates are local operations, guaranteeing consistency without transaction overhead. This alignment also allows Flink to redistribute the state and adjust the stream partitioning transparently.
容錯(cuò)檢查點(diǎn)
Flink 使用流重放和檢查點(diǎn)的組合來(lái)實(shí)現(xiàn)容錯(cuò)。檢查點(diǎn)與每個(gè)輸入流中的特定點(diǎn)以及每個(gè)操作符的相應(yīng)狀態(tài)相關(guān)华嘹。流數(shù)據(jù)流可以從檢查點(diǎn)恢復(fù)吧趣,同時(shí)通過(guò)恢復(fù)操作符的狀態(tài)和從檢查點(diǎn)重放事件來(lái)保持一致性(恰好一次處理語(yǔ)義)。
檢查點(diǎn)間隔是一種權(quán)衡執(zhí)行期間容錯(cuò)開銷與恢復(fù)時(shí)間(需要重放的事件數(shù))的方法耙厚。
Flink 核心組件
分布式系統(tǒng)需要解決:分配和管理在集群的計(jì)算資源强挫、處理配合、持久和可訪問(wèn)的數(shù)據(jù)存儲(chǔ)薛躬、失敗恢復(fù)俯渤。Fink專注分布式流處理。
Components of a Flink Setup
1.JobManager
接收 Application型宝,包含StreamGraph(DAG)八匠、JobGraph(logical dataflow graph,已經(jīng)進(jìn)過(guò)優(yōu)化趴酣,如task chain)和JAR梨树,將JobGraph轉(zhuǎn)化為ExecutionGraph(physical dataflow graph,并行化)岖寞,包含可以并發(fā)執(zhí)行的tasks劝萤。其他工作類似Spark driver,如向RM申請(qǐng)資源慎璧、schedule tasks、保存作業(yè)的元數(shù)據(jù)跨释,如checkpoints胸私。JM可分為JobMaster和ResourceManager(和下面的不同),分別負(fù)責(zé)任務(wù)和資源鳖谈,在Session模式下啟動(dòng)多個(gè)job就會(huì)有多個(gè)JobMaster岁疼。
Job Managers, Task Managers, Clients
The Flink runtime consists of two types of processes:
-
The JobManagers (also called masters) coordinate the distributed execution. They schedule tasks, coordinate checkpoints, coordinate recovery on failures, etc.
There is always at least one Job Manager. A high-availability setup will have multiple JobManagers, one of which one is always the leader, and the others are standby.
-
The TaskManagers (also called workers) execute the tasks (or more specifically, the subtasks) of a dataflow, and buffer and exchange the data streams.
There must always be at least one TaskManager.
The JobManagers and TaskManagers can be started in various ways: directly on the machines as a standalone cluster, in containers, or managed by resource frameworks like YARN or Mesos. TaskManagers connect to JobManagers, announcing themselves as available, and are assigned work.
The client is not part of the runtime and program execution, but is used to prepare and send a dataflow to the JobManager. After that, the client can disconnect, or stay connected to receive progress reports. The client runs either as part of the Java/Scala program that triggers the execution, or in the command line process
./bin/flink run ...
.
2.ResourceManager
一般是Yarn,當(dāng)TM有空閑的slot就會(huì)告訴JM缆娃,沒(méi)有足夠的slot也會(huì)啟動(dòng)新的TM捷绒。kill掉長(zhǎng)時(shí)間空閑的TM。
3.TaskManager
類似Spark的executor贯要,會(huì)跑多個(gè)線程的task暖侨、數(shù)據(jù)緩存與交換。
source(),map()形成一個(gè)操作鏈, keyBy(), window(), apply() 形成一個(gè)操作鏈崇渗。
Flink這樣設(shè)計(jì)的目的在于字逗,操作鏈中的所有操作可以使用一個(gè)線程來(lái)執(zhí)行京郑,這樣可以避免多個(gè)操作在不同線程執(zhí)行帶來(lái)的上下文切換損失,并且可以直接在一個(gè)jvm中共享數(shù)據(jù)
4.Dispatcher(Application Master)
提供REST接口來(lái)接收client的application提交葫掉,它負(fù)責(zé)啟動(dòng)JM和提交 Application些举,同時(shí)運(yùn)行Web UI。
5.Task
Task 是最基本的調(diào)度單位俭厚,由一個(gè)線程執(zhí)行户魏,里面包含一個(gè)或多個(gè)operator。多個(gè)operators就成為operation chain挪挤,需要上下游并發(fā)度一致叼丑,且傳遞模式(之前的Data exchange strategies)是forward。
flink的taskmanager運(yùn)行task的時(shí)候是每個(gè)task采用一個(gè)單獨(dú)的線程电禀,這就會(huì)帶來(lái)很多線程切換開銷幢码,進(jìn)而影響吞吐量。為了減輕這種情況尖飞,flink進(jìn)行了優(yōu)化症副,也即對(duì)subtask進(jìn)行鏈?zhǔn)讲僮鳎準(zhǔn)讲僮鹘Y(jié)束之后得到的task政基,再作為一個(gè)調(diào)度執(zhí)行單元贞铣,放到一個(gè)線程里執(zhí)行。如下圖的沮明,source/map 兩個(gè)算子進(jìn)行了鏈?zhǔn)皆樱籯eyby/window/apply有進(jìn)行了鏈?zhǔn)剑瑂ink單獨(dú)的一個(gè)荐健。
Task 執(zhí)行: Spark中每個(gè)Stage中的Task會(huì)被分配到一個(gè)Worker中的 -> Executor容器里面的 -> 一個(gè)線程池中被執(zhí)行酱畅,F(xiàn)link稱每個(gè)Executor為一個(gè)TaskManager,每個(gè)TaskManager中會(huì)有多個(gè)slot作為內(nèi)存隔離:
Spark: Worker ——> Executor ——> 線程池 ——> 線程
Flink: Worker ——> TaskManager ——> Slot ——> 線程
6.Task Slots and Resources
每個(gè)task slot是TaskManager的一部分江场,若一個(gè)taskManager有三個(gè)taskSlot纺酸,則這三個(gè)taskSlot會(huì)均分這個(gè)TaskManager的資源(僅內(nèi)存,不包括CPU)址否。有多個(gè)slot意味著同一個(gè)JVM中會(huì)有多個(gè)子任務(wù)餐蔬,這些任務(wù)會(huì)共享JVM的TCP連接和心跳信息。這里要說(shuō)明的是佑附,slot的個(gè)數(shù)不是subtask的個(gè)數(shù)是一一對(duì)應(yīng)樊诺,一個(gè)slot中可以有多個(gè)subtask。在默認(rèn)情況下音同,同一個(gè)job中的子任務(wù)(subtask)是可以共享一個(gè)slot的词爬。
slot 是TM的資源子集。一個(gè)slot并不代表一個(gè)線程权均,它里面并不一定只放一個(gè)task缸夹。
多個(gè)task在一個(gè)slot就涉及 slot sharing group痪寻。
一個(gè)jobGraph的任務(wù)需要多少slot,取決于最大的并發(fā)度虽惭,這樣的話橡类,并發(fā)1和并發(fā)2就不會(huì)放到一個(gè)slot中。
Co-Location Group是在此基礎(chǔ)上芽唇,數(shù)據(jù)的forward形式顾画,即一個(gè)slot中,如果它處理的是key1的數(shù)據(jù)匆笤,那么接下來(lái)的task也是處理key1的數(shù)據(jù)研侣,此時(shí)就達(dá)到Co-Location Group。
盡管有slot sharing group炮捧,但一個(gè)group里串聯(lián)起來(lái)的task各自所需資源的大小并不好確定庶诡。阿里日常用得最多的還是一個(gè)task一個(gè)slot的方式。
Task Slots and Resources
每個(gè) worker(TaskManager)都是一個(gè) JVM進(jìn)程 咆课,可以在不同的線程中執(zhí)行一個(gè)或多個(gè)子任務(wù)末誓。
為了控制一個(gè) worker 接受多少任務(wù),一個(gè) worker 有所謂的任務(wù)槽 Task Slot(至少一個(gè))书蚪。 每個(gè)任務(wù)槽 Task Slot 代表 TaskManager 資源的一個(gè)固定子集喇澡。
例如,具有三個(gè)插槽的 TaskManager 會(huì)將其托管內(nèi)存的 1/3 專用于每個(gè)插槽殊校。分配資源意味著子任務(wù)不會(huì)與來(lái)自其他作業(yè)的子任務(wù)競(jìng)爭(zhēng)托管內(nèi)存晴玖,而是擁有一定數(shù)量的保留托管內(nèi)存。
請(qǐng)注意为流,這里沒(méi)有發(fā)生 CPU 隔離呕屎;當(dāng)前插槽僅分隔任務(wù)的托管內(nèi)存。 通過(guò)調(diào)整任務(wù)槽的數(shù)量敬察,用戶可以定義子任務(wù)如何相互隔離榨惰。每個(gè) TaskManager 有一個(gè)插槽意味著每個(gè)任務(wù)組都在單獨(dú)的 JVM 中運(yùn)行(例如,可以在單獨(dú)的容器中啟動(dòng))静汤。
擁有多個(gè)插槽 Task Slot , 意味著更多的子任務(wù)共享同一個(gè) JVM。
同一 JVM 中的任務(wù)共享 TCP 連接(通過(guò)多路復(fù)用)和心跳消息居凶。它們還可以共享數(shù)據(jù)集和數(shù)據(jù)結(jié)構(gòu)虫给,從而減少每個(gè)任務(wù)的開銷。
Each worker (TaskManager) is a JVM process, and may execute one or more subtasks in separate threads. To control how many tasks a worker accepts, a worker has so called task slots (at least one).
Each task slot represents a fixed subset of resources of the TaskManager. A TaskManager with three slots, for example, will dedicate 1/3 of its managed memory to each slot. Slotting the resources means that a subtask will not compete with subtasks from other jobs for managed memory, but instead has a certain amount of reserved managed memory. Note that no CPU isolation happens here; currently slots only separate the managed memory of tasks.
By adjusting the number of task slots, users can define how subtasks are isolated from each other. Having one slot per TaskManager means each task group runs in a separate JVM (which can be started in a separate container, for example). Having multiple slots means more subtasks share the same JVM. Tasks in the same JVM share TCP connections (via multiplexing) and heartbeat messages. They may also share data sets and data structures, thus reducing the per-task overhead.
By default, Flink allows subtasks to share slots even if they are subtasks of different tasks, so long as they are from the same job. The result is that one slot may hold an entire pipeline of the job. Allowing this slot sharing has two main benefits:
A Flink cluster needs exactly as many task slots as the highest parallelism used in the job. No need to calculate how many tasks (with varying parallelism) a program contains in total.
It is easier to get better resource utilization. Without slot sharing, the non-intensive source/map() subtasks would block as many resources as the resource intensive window subtasks. With slot sharing, increasing the base parallelism in our example from two to six yields full utilization of the slotted resources, while making sure that the heavy subtasks are fairly distributed among the TaskManagers.
The APIs also include a resource group mechanism which can be used to prevent undesirable slot sharing.
As a rule-of-thumb, a good default number of task slots would be the number of CPU cores. With hyper-threading, each slot then takes 2 or more hardware thread contexts.
slot和parallelism
1.slot是指taskmanager的并發(fā)執(zhí)行能力
在hadoop 1.x 版本中也有slot的概念掀虎,有興趣的讀者可以了解一下
taskmanager.numberOfTaskSlots:3
每一個(gè)taskmanager中的分配3個(gè)TaskSlot,3個(gè)taskmanager一共有9個(gè)TaskSlot
2.parallelism是指taskmanager實(shí)際使用的并發(fā)能力
parallelism.default:1
運(yùn)行程序默認(rèn)的并行度為1荷腊,9個(gè)TaskSlot只用了1個(gè)较幌,有8個(gè)空閑。設(shè)置合適的并行度才能提高效率药蜻。
3.parallelism是可配置瓷式、可指定的
1.可以通過(guò)修改$FLINK_HOME/conf/flink-conf.yaml文件的方式更改并行度
2.可以通過(guò)設(shè)置$FLINK_HOME/bin/flink 的-p參數(shù)修改并行度
3.可以通過(guò)設(shè)置executionEnvironmentk的方法修改并行度
4.可以通過(guò)設(shè)置flink的編程API修改過(guò)并行度
5.這些并行度設(shè)置優(yōu)先級(jí)從低到高排序,排序?yàn)閍pi>env>p>file.
6.設(shè)置合適的并行度语泽,能提高運(yùn)算效率
7.parallelism不能多與slot個(gè)數(shù)贸典。
slot和parallelism總結(jié)
1.slot是靜態(tài)的概念,是指taskmanager具有的并發(fā)執(zhí)行能力
2.parallelism是動(dòng)態(tài)的概念踱卵,是指程序運(yùn)行時(shí)實(shí)際使用的并發(fā)能力
3.設(shè)置合適的parallelism能提高運(yùn)算效率廊驼,太多了和太少了都不行
4.設(shè)置parallelism有多中方式,優(yōu)先級(jí)為api>env>p>file
7. Tasks and Operator Chains (算子鏈)
Flink會(huì)在生成JobGraph階段惋砂,將代碼中可以優(yōu)化的算子優(yōu)化成一個(gè)算子鏈(Operator Chains)以放到一個(gè)task(一個(gè)線程)中執(zhí)行妒挎,以減少線程之間的切換和緩沖的開銷,提高整體的吞吐量和延遲西饵。
算子之間是否可以組成一個(gè)Operator Chains酝掩,看是否滿足以下條件:
- 上下游算子的并行度一致
- 下游節(jié)點(diǎn)的入度為1
- 上下游節(jié)點(diǎn)都在同一個(gè) slot group 中
- 下游節(jié)點(diǎn)的 chain 策略為 ALWAYS(可以與上下游鏈接,map眷柔、flatmap期虾、filter 等默認(rèn)是ALWAYS)
- 上游節(jié)點(diǎn)的 chain 策略為 ALWAYS 或 HEAD(只能與下游鏈接,不能與上游鏈接闯割,Source默認(rèn)是HEAD)
- 兩個(gè)節(jié)點(diǎn)間數(shù)據(jù)分區(qū)方式是 forward
- 用戶沒(méi)有禁用 chain(代碼中是否配置disableChain())
算子被定義后彻消,先根據(jù)條件優(yōu)化算子鏈 ,然后組成一個(gè)個(gè)subtask宙拉,最后根據(jù)是否可以共享slot分布在taskManager的slot中執(zhí)行宾尚。
Flink 體系結(jié)構(gòu)
Flink的基礎(chǔ)架構(gòu)圖:
兩種運(yùn)行模式:
1.Session模式:預(yù)先啟動(dòng)好AM和TM,每提交一個(gè)job就啟動(dòng)一個(gè)Job Manager并向Flink的RM申請(qǐng)資源谢澈,不夠的話煌贴,F(xiàn)link的RM向YARN的RM申請(qǐng)資源。適合規(guī)模小锥忿,運(yùn)行時(shí)間短的作業(yè)牛郑。./bin/flink run ./path/to/job.jar
2.Job模式:每一個(gè)job都重新啟動(dòng)一個(gè)Flink集群,完成后結(jié)束Flink敬鬓,且只有一個(gè)Job Manager淹朋。資源按需申請(qǐng),適合大作業(yè)钉答。./bin/flink run -m yarn-cluster ./path/to/job.jar
下面是簡(jiǎn)單例子础芍,詳細(xì)看官網(wǎng)。
# 啟動(dòng)yarn-session数尿,4個(gè)TM仑性,每個(gè)有4GB堆內(nèi)存,4個(gè)slot
cd flink-1.7.0/
./bin/yarn-session.sh -n 4 -jm 1024m -tm 4096m -s 4
# 啟動(dòng)作業(yè)
./bin/flink run -m yarn-cluster -yn 4 -yjm 1024m -ytm 4096m ./examples/batch/WordCount.jar
細(xì)節(jié)取決于具體環(huán)境右蹦,如不同的RM
Application Deployment
Framework模式:Flink作業(yè)為JAR诊杆,并被提交到Dispatcher or JM or YARN歼捐。
Library模式:Flink作業(yè)為application-specific container image,如Docker image晨汹,適合微服務(wù)豹储。
Task Execution
作業(yè)調(diào)度:在流計(jì)算中預(yù)先啟動(dòng)好節(jié)點(diǎn),而在批計(jì)算中宰缤,每當(dāng)某個(gè)階段完成計(jì)算才啟動(dòng)下一個(gè)節(jié)點(diǎn)颂翼。
資源管理:slot作為基本單位,有大小和位置屬性慨灭。JM有SlotPool朦乏,向Flink RM申請(qǐng)Slot,F(xiàn)linkRM發(fā)現(xiàn)自己的SlotManager中沒(méi)有足夠的Slot氧骤,就會(huì)向集群RM申請(qǐng)呻疹。后者返回可用TM的ip,讓FlinkRM去啟動(dòng)筹陵,TM啟動(dòng)后向FlinkRM注冊(cè)刽锤。后者向TM請(qǐng)求Slot,TM向JM提供相應(yīng)Slot朦佩。JM用完后釋放Slot并思,TM會(huì)把釋放的Slot報(bào)告給FlinkRM。在Blink版本中语稠,job模式會(huì)根據(jù)申請(qǐng)slot的大小分配相應(yīng)的TM宋彼,而session模式則預(yù)先設(shè)置好TM大小,每有slot申請(qǐng)就從TM中劃分相應(yīng)的資源仙畦。
任務(wù)可以是相同operator (data parallelism)输涕,不同 operator (task parallelism),甚至不同application (job parallelism)慨畸。TM提供一定數(shù)量的slots來(lái)控制并行的任務(wù)數(shù)莱坎。
上圖A和C是source function,E是sink function寸士,小數(shù)字表示并行度檐什。
一個(gè)TM是一個(gè)JVM進(jìn)程,它通過(guò)多線程完成任務(wù)弱卡。線程的隔離不太好乃正,一個(gè)線程失敗有可能導(dǎo)致整個(gè)TM失敗。
Highly-Available Setup
從失敗中恢復(fù)需要重啟失敗進(jìn)程谐宙、作業(yè)和恢復(fù)它的state。
當(dāng)一個(gè)TM掛掉而RM又無(wú)法找到空閑的資源時(shí)界弧,就只能暫時(shí)降低并行度凡蜻,直到有空閑的資源重啟TM搭综。
當(dāng)JM掛掉就靠ZK來(lái)重新選舉,和找到JM存儲(chǔ)到遠(yuǎn)程storage的元數(shù)據(jù)划栓、JobGraph兑巾。重啟JM并從最后一個(gè)完成的checkpoint開始。
JM在執(zhí)行期間會(huì)得到每個(gè)task checkpoints的state存儲(chǔ)路徑(task將state寫到遠(yuǎn)程storage)并寫到遠(yuǎn)程storage忠荞,同時(shí)在ZK的存儲(chǔ)路徑留下pointer指明到哪里找上面的存儲(chǔ)路徑蒋歌。
背壓
數(shù)據(jù)涌入的速度大于處理速度。在source operator中委煤,可通過(guò)Kafka解決堂油。在任務(wù)間的operator有如下機(jī)制應(yīng)對(duì):
Local exchange:task1和2在同一個(gè)工作節(jié)點(diǎn),那么buffer pool可以直接交給下一個(gè)任務(wù)碧绞,但下一個(gè)任務(wù)task2消費(fèi)buffer pool中的信息速度減慢時(shí)府框,當(dāng)前任務(wù)task1填充buffer pool的速度也會(huì)減慢。
Remote exchange:TM保證每個(gè)task至少有一個(gè)incoming和一個(gè)outgoing緩沖區(qū)讥邻。當(dāng)下游receiver的處理速度低于上有的sender的發(fā)送速度迫靖,receiver的incoming緩沖區(qū)就會(huì)開始積累數(shù)據(jù)(需要空閑的buffer來(lái)放從TCP連接中接收的數(shù)據(jù)),當(dāng)擠滿后就不再接收數(shù)據(jù)兴使。上游sender利用netty水位機(jī)制系宜,當(dāng)網(wǎng)絡(luò)中的緩沖數(shù)據(jù)過(guò)多時(shí)暫停發(fā)送。
Data Transfer in Flink
TM負(fù)責(zé)數(shù)據(jù)在tasks間的轉(zhuǎn)移发魄,轉(zhuǎn)移之前會(huì)存儲(chǔ)到buffer(這又變回micro-batches)盹牧。每個(gè)TM有32KB的網(wǎng)絡(luò)buffer用于接收和發(fā)送數(shù)據(jù)。如果sender和receiver在不同進(jìn)程欠母,那么會(huì)通過(guò)操作系統(tǒng)的網(wǎng)絡(luò)棧來(lái)通信欢策。每對(duì)TM保持permanent TCP連接來(lái)交換數(shù)據(jù)。每個(gè)sender任務(wù)能夠給所有receiving任務(wù)發(fā)送數(shù)據(jù)赏淌,反之踩寇,所有receiver任務(wù)能夠接收所有sender任務(wù)的數(shù)據(jù)。TM保證每個(gè)任務(wù)都至少有一個(gè)incoming和outgoing的buffer六水,并增加額外的緩沖區(qū)分配約束來(lái)避免死鎖俺孙。
如果sender和receiver任務(wù)在同一個(gè)TM進(jìn)程,sender會(huì)序列化結(jié)果數(shù)據(jù)到buffer掷贾,如果滿了就放到隊(duì)列睛榄。receiver任務(wù)通過(guò)隊(duì)列得到數(shù)據(jù)并進(jìn)行反序列化。這樣的好處是解耦任務(wù)并允許在任務(wù)中使用可變對(duì)象想帅,從而減少了對(duì)象實(shí)例化和垃圾收集场靴。一旦數(shù)據(jù)被序列化,就能安全地修改。而缺點(diǎn)是計(jì)算消耗大旨剥,在一些條件下能夠把task穿起來(lái)咧欣,避免序列化。(C10)
Flow Control with Back Pressure
receiver放到緩沖區(qū)的數(shù)據(jù)變?yōu)殛?duì)列轨帜,sender將要發(fā)送的數(shù)據(jù)變?yōu)殛?duì)列魄咕,最后sender減慢發(fā)送速度。
Event Time Processing
event time處理的數(shù)據(jù)必須有時(shí)間戳(Long unix timestamp)并定義了watermarks蚌父。watermark是一種特殊的records holding a timestamp long value哮兰。它必須是遞增的(防止倒退),有一個(gè)timestamp t(下圖的5)苟弛,暗示所有接下來(lái)的數(shù)據(jù)都會(huì)大于這個(gè)值喝滞。后來(lái)的,小于這個(gè)值嗡午,就被視為遲來(lái)數(shù)據(jù)囤躁,F(xiàn)link有其他機(jī)制處理。
Watermarks and Event Time
WM在Flink是一種特殊的record荔睹,它會(huì)被operator tasks接收和釋放狸演。
tasks有時(shí)間服務(wù)來(lái)維持timers(timers注冊(cè)到時(shí)間服務(wù)上),在time-window task中僻他,timers分別記錄了各個(gè)window的結(jié)束時(shí)間宵距。當(dāng)任務(wù)獲得一個(gè)watermark時(shí),task會(huì)根據(jù)這個(gè)watermark的timestamp更新內(nèi)部的event-time clock吨拗。任務(wù)內(nèi)部的時(shí)間服務(wù)確定所有timers時(shí)間是否小于watermark的timestamp满哪,如果大于則觸發(fā)call-back算子來(lái)釋放記錄并返回結(jié)果。最后task還會(huì)將更新的event-time clock的WM進(jìn)行廣播劝篷。(結(jié)合下圖理解)
只有ProcessFunction可以讀取和修改timestamp或者watermark(The ProcessFunction
can read the timestamp of a currently processed record, request the current event-time of the operator, and register timers)哨鸭。下面是PF的行為。
當(dāng)收到WM大于所有目前擁有的WM娇妓,就會(huì)把event-time clock更新為所有WM中最小的那個(gè)像鸡,并廣播這個(gè)最小的WM。即便是多個(gè)streams輸入哈恰,機(jī)制也一樣只估,只是增加Paritition WM數(shù)量。這種機(jī)制要求獲得的WM必須是累加的着绷,而且task必須有新的WM接收蛔钙,否則clock就不會(huì)更新,task的timers就不會(huì)被觸發(fā)荠医。另外吁脱,當(dāng)多個(gè)streams輸入時(shí)桑涎,timers會(huì)被WM比較離散的stream主導(dǎo),從而使更密集的stream的state不斷積累兼贡。
Timestamp Assignment and Watermark Generation
當(dāng)streaming application消化流時(shí)產(chǎn)生石洗。Flink有三種方式產(chǎn)生:
- SourceFunction:產(chǎn)生的record帶有timestamp,一些特殊時(shí)點(diǎn)產(chǎn)生WM紧显。如果SF暫時(shí)不再發(fā)送WM,則會(huì)被認(rèn)為是idle缕棵。Flink會(huì)從接下來(lái)的watermark operators中排除由這個(gè)SF生產(chǎn)的分區(qū)(上圖有4個(gè)分區(qū))孵班,從而解決timer不觸發(fā)的問(wèn)題。
-
AssignerWithPeriodicWatermarks
提取每條記錄的timestamp招驴,并周期性的查詢當(dāng)前WM篙程,即上圖的Partition WM。 -
AssignerWithPunctuatedWatermarks
可以從每條數(shù)據(jù)提取WM别厘。
上面兩個(gè)User-defined timestamp assignment functions通常用在source operator附近虱饿,因?yàn)閟tream一經(jīng)處理就很難把握record的時(shí)間順序了。所以UDF可以修改timestamp和WM触趴,但在數(shù)據(jù)處理時(shí)使用不是一個(gè)好主意氮发。
State Management
由任務(wù)維護(hù)并用于計(jì)算函數(shù)結(jié)果的所有數(shù)據(jù)都屬于任務(wù)的state。其實(shí)state可以理解為task業(yè)務(wù)邏輯的本地或?qū)嵗兞俊?/p>
在Flink冗懦,state總是和特定的operator關(guān)聯(lián)爽冕。operator需要注冊(cè)它的state,而state有兩種類型:
- Operator State:由同一并行任務(wù)處理的所有記錄都可以訪問(wèn)相同的state披蕉,而其他的task或operator不能訪問(wèn)颈畸,即一個(gè)task專屬一個(gè)state。這種state有三種primitives
- List State represents state as a list of entries.
- Union List State同上没讲,但在任務(wù)失敗和作業(yè)從savepoint重啟的行為不一樣
- Broadcast State(v1.5) 同樣一個(gè)task專屬一個(gè)state眯娱,但state都是一樣的(需要自己注意保持一致,對(duì)state更新時(shí)爬凑,實(shí)際上只對(duì)當(dāng)前task的state進(jìn)行更新徙缴。只有所有task的更新一樣時(shí),即輸入數(shù)據(jù)一樣(一開始廣播所以一樣贰谣,但數(shù)據(jù)的順序可能不一樣)娜搂,對(duì)數(shù)據(jù)的處理一樣,才能保證state一樣)吱抚。這種state只能存儲(chǔ)在內(nèi)存百宇,所以沒(méi)有RockDB backend。
- Keyed State:相同key的record共享一個(gè)state秘豹。
- Value State:每個(gè)key一個(gè)值携御,這個(gè)值可以是復(fù)雜的數(shù)據(jù)結(jié)構(gòu).
- List State:每個(gè)key一個(gè)list
- Map State:每個(gè)key一個(gè)map
上面兩種state的存在方式有兩種:raw和managed,一般都是用后者,也推薦用后者(更好的內(nèi)存管理啄刹、不需造輪子)涮坐。
State Backends
state backend決定了state如何被存儲(chǔ)、訪問(wèn)和維持誓军。它的主要職責(zé)是本地state管理和checkpoint state到遠(yuǎn)程袱讹。在管理方面,可選擇將state存儲(chǔ)到內(nèi)存還是磁盤昵时。checkpoint方面在C8詳細(xì)介紹捷雕。
MemoryStateBackend, FsStateBackend, RocksDBStateBackend適合越來(lái)越大的state。都支持異步checkpoint壹甥,其中RocksDB還支持incremental的checkpoint救巷。
- 注意:As RocksDB’s JNI bridge API is based on byte[], the maximum supported size per key and per value is 2^31 bytes each. IMPORTANT: states that use merge operations in RocksDB (e.g. ListState) can silently accumulate value sizes > 2^31 bytes and will then fail on their next retrieval. This is currently a limitation of RocksDB JNI.
Scaling Stateful Operators
Flink會(huì)根據(jù)input rate調(diào)整并發(fā)度。對(duì)于stateful operators有以下4種方式:
keyed state:根據(jù)key group來(lái)調(diào)整句柠,即分為同一組的key-value會(huì)被分到相同的task
list state:所有l(wèi)ist entries會(huì)被收集并重新均勻分布浦译,當(dāng)增加并發(fā)度時(shí),要新建list
union list state:增加并發(fā)時(shí)溯职,廣播整個(gè)list精盅,所以rescaling后,所有task都有所有的list state谜酒。
- broadcast state
Checkpoints, Savepoints, and State Recovery
Flink’s Lightweight Checkpointing Algorithm
在分布式開照算法Chandy-Lamport的基礎(chǔ)上實(shí)現(xiàn)渤弛。有一種特殊的record叫checkpoint barrier(由JM產(chǎn)生),它帶有checkpoint ID來(lái)把流進(jìn)行劃分甚带。在CB前面的records會(huì)被包含到checkpoint她肯,之后的會(huì)被包含在之后的checkpoint。
當(dāng)source task收到這種信息鹰贵,就會(huì)停止發(fā)送recordes晴氨,觸發(fā)state backend對(duì)本地state的checkpoint,并廣播checkpoint ID到所有下游task碉输。當(dāng)checkpoint完成時(shí)籽前,state backend喚醒source task,后者向JM確定相應(yīng)的checkpoint ID已經(jīng)完成任務(wù)敷钾。
當(dāng)下游獲得其中一個(gè)CB時(shí)枝哄,就會(huì)暫停處理這個(gè)CB對(duì)應(yīng)的source的數(shù)據(jù)(完成checkpoint后發(fā)送的數(shù)據(jù)),并將這些數(shù)據(jù)存到緩沖區(qū)阻荒,直到其他相同ID的CB都到齊挠锥,就會(huì)把state(下圖的12、8)進(jìn)行checkpoint侨赡,并廣播CB到下游蓖租。直到所有CB被廣播到下游粱侣,才開始處理排隊(duì)在緩沖區(qū)的數(shù)據(jù)。當(dāng)然蓖宦,其他沒(méi)有發(fā)送CB的source的數(shù)據(jù)會(huì)繼續(xù)處理齐婴。
最后,當(dāng)所有sink會(huì)向JM發(fā)送BC確定checkpoint已完成稠茂。
這種機(jī)制還有兩個(gè)優(yōu)化:
- 當(dāng)operator的state很大時(shí)柠偶,復(fù)制整個(gè)state并發(fā)送到遠(yuǎn)程storage會(huì)很費(fèi)時(shí)。而RocksDB state backend支持asynchronous and incremental的checkpoints睬关。當(dāng)觸發(fā)checkpoint時(shí)嚣州,backend會(huì)快照所有本地state的修改(直至上一次checkpoint),然后馬上讓task繼續(xù)執(zhí)行共螺。后臺(tái)線程異步發(fā)送快照到遠(yuǎn)程storage。
- 在等待其余CB時(shí)情竹,已經(jīng)完成checkpoint的source數(shù)據(jù)需要排隊(duì)藐不。但如果使用at-least-once就不需要等了。但當(dāng)所有CB到齊再checkpoint秦效,存儲(chǔ)的state就已經(jīng)包含了下一次checkpoint才記錄的數(shù)據(jù)雏蛮。(如果是取最值這種state就無(wú)所謂)
Recovery from Consistent Checkpoints
上圖隊(duì)列中的7和6之所以能恢復(fù),取決于數(shù)據(jù)源是否resettable阱州,如Kafka挑秉,不會(huì)因?yàn)榘l(fā)送信息就把信息刪除。這才能實(shí)現(xiàn)處理過(guò)程的exactly-once state consistency(嚴(yán)格來(lái)講苔货,數(shù)據(jù)還是被重復(fù)處理犀概,但是在讀檔后重復(fù)的)垄懂。但是下游系統(tǒng)有可能接收到多個(gè)結(jié)果恼除。這方面朵你,F(xiàn)link提供sink算子實(shí)現(xiàn)output的exactly-once迎捺,例如給checkpoint提交records釋放記錄碟婆。另一個(gè)方法是idempotent updates刨仑,詳細(xì)看C7析珊。
Savepoints
checkpoints加上一些額外的元數(shù)據(jù)贝椿,功能也是在checkpoint的基礎(chǔ)上豐富敢会。不同于checkpoints曾沈,savepoint不會(huì)被Flink自動(dòng)創(chuàng)造(由用戶或者外部scheduler觸發(fā)創(chuàng)造)和銷毀。savepoint可以重啟不同但兼容的作業(yè)鸥昏,從而:
- 修復(fù)bugs進(jìn)而修復(fù)錯(cuò)誤的結(jié)果塞俱,也可用于A/B test或者what-if場(chǎng)景。
- 調(diào)整并發(fā)度
- 遷移作業(yè)到其他集群吏垮、新版Flink
也可以用于暫停作業(yè)敛腌,通過(guò)savepoint查看作業(yè)情況卧土。
參考
Stream Processing with Apache Flink by Vasiliki Kalavri; Fabian Hueske
Flink 應(yīng)用場(chǎng)景
應(yīng)用場(chǎng)景
Apache Flink 功能強(qiáng)大,支持開發(fā)和運(yùn)行多種不同種類的應(yīng)用程序像樊。它的主要特性包括:批流一體化尤莺、精密的狀態(tài)管理、事件時(shí)間支持以及精確一次的狀態(tài)一致性保障等生棍。Flink 不僅可以運(yùn)行在包括 YARN颤霎、 Mesos、Kubernetes 在內(nèi)的多種資源管理框架上涂滴,還支持在裸機(jī)集群上獨(dú)立部署友酱。在啟用高可用選項(xiàng)的情況下,它不存在單點(diǎn)失效問(wèn)題柔纵。事實(shí)證明缔杉,F(xiàn)link 已經(jīng)可以擴(kuò)展到數(shù)千核心,其狀態(tài)可以達(dá)到 TB 級(jí)別搁料,且仍能保持高吞吐或详、低延遲的特性。世界各地有很多要求嚴(yán)苛的流處理應(yīng)用都運(yùn)行在 Flink 之上郭计。
接下來(lái)我們將介紹 Flink 常見的幾類應(yīng)用并給出相關(guān)實(shí)例鏈接霸琴。
事件驅(qū)動(dòng)型應(yīng)用
什么是事件驅(qū)動(dòng)型應(yīng)用?
事件驅(qū)動(dòng)型應(yīng)用是一類具有狀態(tài)的應(yīng)用昭伸,它從一個(gè)或多個(gè)事件流提取數(shù)據(jù)梧乘,并根據(jù)到來(lái)的事件觸發(fā)計(jì)算、狀態(tài)更新或其他外部動(dòng)作庐杨。
事件驅(qū)動(dòng)型應(yīng)用是在計(jì)算存儲(chǔ)分離的傳統(tǒng)應(yīng)用基礎(chǔ)上進(jìn)化而來(lái)选调。在傳統(tǒng)架構(gòu)中,應(yīng)用需要讀寫遠(yuǎn)程事務(wù)型數(shù)據(jù)庫(kù)灵份。
相反学歧,事件驅(qū)動(dòng)型應(yīng)用是基于狀態(tài)化流處理來(lái)完成。在該設(shè)計(jì)中各吨,數(shù)據(jù)和計(jì)算不會(huì)分離枝笨,應(yīng)用只需訪問(wèn)本地(內(nèi)存或磁盤)即可獲取數(shù)據(jù)。系統(tǒng)容錯(cuò)性的實(shí)現(xiàn)依賴于定期向遠(yuǎn)程持久化存儲(chǔ)寫入 checkpoint揭蜒。下圖描述了傳統(tǒng)應(yīng)用和事件驅(qū)動(dòng)型應(yīng)用架構(gòu)的區(qū)別横浑。
事件驅(qū)動(dòng)型應(yīng)用的優(yōu)勢(shì)?
事件驅(qū)動(dòng)型應(yīng)用無(wú)須查詢遠(yuǎn)程數(shù)據(jù)庫(kù)屉更,本地?cái)?shù)據(jù)訪問(wèn)使得它具有更高的吞吐和更低的延遲徙融。而由于定期向遠(yuǎn)程持久化存儲(chǔ)的 checkpoint 工作可以異步、增量式完成瑰谜,因此對(duì)于正常事件處理的影響甚微欺冀。事件驅(qū)動(dòng)型應(yīng)用的優(yōu)勢(shì)不僅限于本地?cái)?shù)據(jù)訪問(wèn)树绩。傳統(tǒng)分層架構(gòu)下,通常多個(gè)應(yīng)用會(huì)共享同一個(gè)數(shù)據(jù)庫(kù)隐轩,因而任何對(duì)數(shù)據(jù)庫(kù)自身的更改(例如:由應(yīng)用更新或服務(wù)擴(kuò)容導(dǎo)致數(shù)據(jù)布局發(fā)生改變)都需要謹(jǐn)慎協(xié)調(diào)饺饭。反觀事件驅(qū)動(dòng)型應(yīng)用,由于只需考慮自身數(shù)據(jù)职车,因此在更改數(shù)據(jù)表示或服務(wù)擴(kuò)容時(shí)所需的協(xié)調(diào)工作將大大減少瘫俊。
Flink 如何支持事件驅(qū)動(dòng)型應(yīng)用?
事件驅(qū)動(dòng)型應(yīng)用會(huì)受制于底層流處理系統(tǒng)對(duì)時(shí)間和狀態(tài)的把控能力悴灵,F(xiàn)link 諸多優(yōu)秀特質(zhì)都是圍繞這些方面來(lái)設(shè)計(jì)的扛芽。它提供了一系列豐富的狀態(tài)操作原語(yǔ),允許以精確一次的一致性語(yǔ)義合并海量規(guī)模(TB 級(jí)別)的狀態(tài)數(shù)據(jù)积瞒。此外川尖,F(xiàn)link 還支持事件時(shí)間和自由度極高的定制化窗口邏輯,而且它內(nèi)置的 ProcessFunction
支持細(xì)粒度時(shí)間控制茫孔,方便實(shí)現(xiàn)一些高級(jí)業(yè)務(wù)邏輯叮喳。同時(shí),F(xiàn)link 還擁有一個(gè)復(fù)雜事件處理(CEP)類庫(kù)银酬,可以用來(lái)檢測(cè)數(shù)據(jù)流中的模式。
Flink 中針對(duì)事件驅(qū)動(dòng)應(yīng)用的明星特性當(dāng)屬 savepoint筐钟。Savepoint 是一個(gè)一致性的狀態(tài)映像揩瞪,它可以用來(lái)初始化任意狀態(tài)兼容的應(yīng)用。在完成一次 savepoint 后篓冲,即可放心對(duì)應(yīng)用升級(jí)或擴(kuò)容李破,還可以啟動(dòng)多個(gè)版本的應(yīng)用來(lái)完成 A/B 測(cè)試。
Programs written in the Data Stream API can resume execution from a savepoint. Savepoints allow both updating your programs and your Flink cluster without losing any state.
Savepoints are manually triggered checkpoints, which take a snapshot of the program and write it out to a state backend. They rely on the regular checkpointing mechanism for this. During execution programs are periodically snapshotted on the worker nodes and produce checkpoints. For recovery only the last completed checkpoint is needed and older checkpoints can be safely discarded as soon as a new one is completed.
Savepoints are similar to these periodic checkpoints except that they are triggered by the user and don’t automatically expire when newer checkpoints are completed. Savepoints can be created from the command line or when cancelling a job via the REST API.
典型的事件驅(qū)動(dòng)型應(yīng)用實(shí)例
數(shù)據(jù)分析應(yīng)用
什么是數(shù)據(jù)分析應(yīng)用壹将?
數(shù)據(jù)分析任務(wù)需要從原始數(shù)據(jù)中提取有價(jià)值的信息和指標(biāo)嗤攻。傳統(tǒng)的分析方式通常是利用批查詢,或?qū)⑹录涗浵聛?lái)并基于此有限數(shù)據(jù)集構(gòu)建應(yīng)用來(lái)完成诽俯。為了得到最新數(shù)據(jù)的分析結(jié)果妇菱,必須先將它們加入分析數(shù)據(jù)集并重新執(zhí)行查詢或運(yùn)行應(yīng)用,隨后將結(jié)果寫入存儲(chǔ)系統(tǒng)或生成報(bào)告暴区。
借助一些先進(jìn)的流處理引擎闯团,還可以實(shí)時(shí)地進(jìn)行數(shù)據(jù)分析。和傳統(tǒng)模式下讀取有限數(shù)據(jù)集不同仙粱,流式查詢或應(yīng)用會(huì)接入實(shí)時(shí)事件流房交,并隨著事件消費(fèi)持續(xù)產(chǎn)生和更新結(jié)果。這些結(jié)果數(shù)據(jù)可能會(huì)寫入外部數(shù)據(jù)庫(kù)系統(tǒng)或以內(nèi)部狀態(tài)的形式維護(hù)伐割。儀表展示應(yīng)用可以相應(yīng)地從外部數(shù)據(jù)庫(kù)讀取數(shù)據(jù)或直接查詢應(yīng)用的內(nèi)部狀態(tài)候味。
如下圖所示刃唤,Apache Flink 同時(shí)支持流式及批量分析應(yīng)用。
流式分析應(yīng)用的優(yōu)勢(shì)白群?
和批量分析相比尚胞,由于流式分析省掉了周期性的數(shù)據(jù)導(dǎo)入和查詢過(guò)程,因此從事件中獲取指標(biāo)的延遲更低川抡。不僅如此辐真,批量查詢必須處理那些由定期導(dǎo)入和輸入有界性導(dǎo)致的人工數(shù)據(jù)邊界,而流式查詢則無(wú)須考慮該問(wèn)題崖堤。
另一方面侍咱,流式分析會(huì)簡(jiǎn)化應(yīng)用抽象。批量查詢的流水線通常由多個(gè)獨(dú)立部件組成密幔,需要周期性地調(diào)度提取數(shù)據(jù)和執(zhí)行查詢楔脯。如此復(fù)雜的流水線操作起來(lái)并不容易,一旦某個(gè)組件出錯(cuò)將會(huì)影響流水線的后續(xù)步驟胯甩。而流式分析應(yīng)用整體運(yùn)行在 Flink 之類的高端流處理系統(tǒng)之上昧廷,涵蓋了從數(shù)據(jù)接入到連續(xù)結(jié)果計(jì)算的所有步驟,因此可以依賴底層引擎提供的故障恢復(fù)機(jī)制偎箫。
Flink 如何支持?jǐn)?shù)據(jù)分析類應(yīng)用木柬?
Flink 為持續(xù)流式分析和批量分析都提供了良好的支持。具體而言淹办,它內(nèi)置了一個(gè)符合 ANSI 標(biāo)準(zhǔn)的 SQL 接口眉枕,將批、流查詢的語(yǔ)義統(tǒng)一起來(lái)怜森。無(wú)論是在記錄事件的靜態(tài)數(shù)據(jù)集上還是實(shí)時(shí)事件流上速挑,相同 SQL 查詢都會(huì)得到一致的結(jié)果。同時(shí) Flink 還支持豐富的用戶自定義函數(shù)副硅,允許在 SQL 中執(zhí)行定制化代碼姥宝。如果還需進(jìn)一步定制邏輯,可以利用 Flink DataStream API 和 DataSet API 進(jìn)行更低層次的控制恐疲。此外腊满,F(xiàn)link 的 Gelly 庫(kù)為基于批量數(shù)據(jù)集的大規(guī)模高性能圖分析提供了算法和構(gòu)建模塊支持。
典型的數(shù)據(jù)分析應(yīng)用實(shí)例
- 電信網(wǎng)絡(luò)質(zhì)量監(jiān)控
- 移動(dòng)應(yīng)用中的產(chǎn)品更新及實(shí)驗(yàn)評(píng)估分析
- 消費(fèi)者技術(shù)中的實(shí)時(shí)數(shù)據(jù)即席分析
- 大規(guī)模圖分析
數(shù)據(jù)管道應(yīng)用
什么是數(shù)據(jù)管道培己?
提取-轉(zhuǎn)換-加載(ETL)是一種在存儲(chǔ)系統(tǒng)之間進(jìn)行數(shù)據(jù)轉(zhuǎn)換和遷移的常用方法糜烹。ETL 作業(yè)通常會(huì)周期性地觸發(fā),將數(shù)據(jù)從事務(wù)型數(shù)據(jù)庫(kù)拷貝到分析型數(shù)據(jù)庫(kù)或數(shù)據(jù)倉(cāng)庫(kù)漱凝。
數(shù)據(jù)管道和 ETL 作業(yè)的用途相似疮蹦,都可以轉(zhuǎn)換、豐富數(shù)據(jù)茸炒,并將其從某個(gè)存儲(chǔ)系統(tǒng)移動(dòng)到另一個(gè)愕乎。但數(shù)據(jù)管道是以持續(xù)流模式運(yùn)行阵苇,而非周期性觸發(fā)。因此它支持從一個(gè)不斷生成數(shù)據(jù)的源頭讀取記錄感论,并將它們以低延遲移動(dòng)到終點(diǎn)绅项。例如:數(shù)據(jù)管道可以用來(lái)監(jiān)控文件系統(tǒng)目錄中的新文件,并將其數(shù)據(jù)寫入事件日志比肄;另一個(gè)應(yīng)用可能會(huì)將事件流物化到數(shù)據(jù)庫(kù)或增量構(gòu)建和優(yōu)化查詢索引快耿。
下圖描述了周期性 ETL 作業(yè)和持續(xù)數(shù)據(jù)管道的差異。
數(shù)據(jù)管道的優(yōu)勢(shì)芳绩?
和周期性 ETL 作業(yè)相比掀亥,持續(xù)數(shù)據(jù)管道可以明顯降低將數(shù)據(jù)移動(dòng)到目的端的延遲。此外妥色,由于它能夠持續(xù)消費(fèi)和發(fā)送數(shù)據(jù)搪花,因此用途更廣,支持用例更多嘹害。
Flink 如何支持?jǐn)?shù)據(jù)管道應(yīng)用撮竿?
很多常見的數(shù)據(jù)轉(zhuǎn)換和增強(qiáng)操作可以利用 Flink 的 SQL 接口(或 Table API)及用戶自定義函數(shù)解決。如果數(shù)據(jù)管道有更高級(jí)的需求笔呀,可以選擇更通用的 DataStream API 來(lái)實(shí)現(xiàn)幢踏。Flink 為多種數(shù)據(jù)存儲(chǔ)系統(tǒng)(如:Kafka、Kinesis许师、Elasticsearch房蝉、JDBC數(shù)據(jù)庫(kù)系統(tǒng)等)內(nèi)置了連接器。同時(shí)它還提供了文件系統(tǒng)的連續(xù)型數(shù)據(jù)源及數(shù)據(jù)匯枯跑,可用來(lái)監(jiān)控目錄變化和以時(shí)間分區(qū)的方式寫入文件惨驶。
典型的數(shù)據(jù)管道應(yīng)用實(shí)例
- 電子商務(wù)中的實(shí)時(shí)查詢索引構(gòu)建
- 電子商務(wù)中的持續(xù) ETL
處理無(wú)界和有界數(shù)據(jù)
任何類型的數(shù)據(jù)都可以形成一種事件流白热。信用卡交易敛助、傳感器測(cè)量、機(jī)器日志屋确、網(wǎng)站或移動(dòng)應(yīng)用程序上的用戶交互記錄纳击,所有這些數(shù)據(jù)都形成一種流。
數(shù)據(jù)可以被作為 無(wú)界 或者 有界 流來(lái)處理攻臀。
無(wú)界流 有定義流的開始焕数,但沒(méi)有定義流的結(jié)束。它們會(huì)無(wú)休止地產(chǎn)生數(shù)據(jù)刨啸。無(wú)界流的數(shù)據(jù)必須持續(xù)處理堡赔,即數(shù)據(jù)被攝取后需要立刻處理。我們不能等到所有數(shù)據(jù)都到達(dá)再處理设联,因?yàn)檩斎胧菬o(wú)限的善已,在任何時(shí)候輸入都不會(huì)完成灼捂。處理無(wú)界數(shù)據(jù)通常要求以特定順序攝取事件,例如事件發(fā)生的順序换团,以便能夠推斷結(jié)果的完整性悉稠。
有界流 有定義流的開始,也有定義流的結(jié)束艘包。有界流可以在攝取所有數(shù)據(jù)后再進(jìn)行計(jì)算的猛。有界流所有數(shù)據(jù)可以被排序,所以并不需要有序攝取想虎。有界流處理通常被稱為批處理
Apache Flink 擅長(zhǎng)處理無(wú)界和有界數(shù)據(jù)集 精確的時(shí)間控制和狀態(tài)化使得 Flink 的運(yùn)行時(shí)(runtime)能夠運(yùn)行任何處理無(wú)界流的應(yīng)用卦尊。有界流則由一些專為固定大小數(shù)據(jù)集特殊設(shè)計(jì)的算法和數(shù)據(jù)結(jié)構(gòu)進(jìn)行內(nèi)部處理,產(chǎn)生了出色的性能磷醋。
通過(guò)探索 Flink 之上構(gòu)建的 用例 來(lái)加深理解猫牡。
API 和庫(kù)
Apache Flink 是一個(gè)針對(duì)無(wú)界和有界數(shù)據(jù)流進(jìn)行有狀態(tài)計(jì)算的框架。Flink 自底向上在不同的抽象級(jí)別提供了多種 API邓线,并且針對(duì)常見的使用場(chǎng)景開發(fā)了專用的擴(kuò)展庫(kù)淌友。
在本章中,我們將介紹 Flink 所提供的這些簡(jiǎn)單易用骇陈、易于表達(dá)的 API 和庫(kù)震庭。
流處理應(yīng)用的基本組件
可以由流處理框架構(gòu)建和執(zhí)行的應(yīng)用程序類型是由框架對(duì) 流、狀態(tài)你雌、時(shí)間 的支持程度來(lái)決定的器联。在下文中,我們將對(duì)上述這些流處理應(yīng)用的基本組件逐一進(jìn)行描述婿崭,并對(duì) Flink 處理它們的方法進(jìn)行細(xì)致剖析拨拓。
流
顯而易見,(數(shù)據(jù))流是流處理的基本要素氓栈。然而渣磷,流也擁有著多種特征。這些特征決定了流如何以及何時(shí)被處理授瘦。Flink 是一個(gè)能夠處理任何類型數(shù)據(jù)流的強(qiáng)大處理框架醋界。
- 有界 和 無(wú)界 的數(shù)據(jù)流:流可以是無(wú)界的;也可以是有界的提完,例如固定大小的數(shù)據(jù)集形纺。Flink 在無(wú)界的數(shù)據(jù)流處理上擁有諸多功能強(qiáng)大的特性,同時(shí)也針對(duì)有界的數(shù)據(jù)流開發(fā)了專用的高效算子徒欣。
- 實(shí)時(shí) 和 歷史記錄 的數(shù)據(jù)流:所有的數(shù)據(jù)都是以流的方式產(chǎn)生逐样,但用戶通常會(huì)使用兩種截然不同的方法處理數(shù)據(jù)。或是在數(shù)據(jù)生成時(shí)進(jìn)行實(shí)時(shí)的處理脂新;亦或是先將數(shù)據(jù)流持久化到存儲(chǔ)系統(tǒng)中——例如文件系統(tǒng)或?qū)ο蟠鎯?chǔ)秽澳,然后再進(jìn)行批處理。Flink 的應(yīng)用能夠同時(shí)支持處理實(shí)時(shí)以及歷史記錄數(shù)據(jù)流戏羽。
狀態(tài)
只有在每一個(gè)單獨(dú)的事件上進(jìn)行轉(zhuǎn)換操作的應(yīng)用才不需要狀態(tài)担神,換言之,每一個(gè)具有一定復(fù)雜度的流處理應(yīng)用都是有狀態(tài)的始花。任何運(yùn)行基本業(yè)務(wù)邏輯的流處理應(yīng)用都需要在一定時(shí)間內(nèi)存儲(chǔ)所接收的事件或中間結(jié)果妄讯,以供后續(xù)的某個(gè)時(shí)間點(diǎn)(例如收到下一個(gè)事件或者經(jīng)過(guò)一段特定時(shí)間)進(jìn)行訪問(wèn)并進(jìn)行后續(xù)處理。
應(yīng)用狀態(tài)是 Flink 中的一等公民酷宵,F(xiàn)link 提供了許多狀態(tài)管理相關(guān)的特性支持亥贸,其中包括:
- 多種狀態(tài)基礎(chǔ)類型:Flink 為多種不同的數(shù)據(jù)結(jié)構(gòu)提供了相對(duì)應(yīng)的狀態(tài)基礎(chǔ)類型,例如原子值(value)浇垦,列表(list)以及映射(map)炕置。開發(fā)者可以基于處理函數(shù)對(duì)狀態(tài)的訪問(wèn)方式,選擇最高效男韧、最適合的狀態(tài)基礎(chǔ)類型朴摊。
- 插件化的State Backend:State Backend 負(fù)責(zé)管理應(yīng)用程序狀態(tài),并在需要的時(shí)候進(jìn)行 checkpoint此虑。Flink 支持多種 state backend甚纲,可以將狀態(tài)存在內(nèi)存或者 RocksDB。RocksDB 是一種高效的嵌入式朦前、持久化鍵值存儲(chǔ)引擎介杆。Flink 也支持插件式的自定義 state backend 進(jìn)行狀態(tài)存儲(chǔ)。
- 精確一次語(yǔ)義:Flink 的 checkpoint 和故障恢復(fù)算法保證了故障發(fā)生后應(yīng)用狀態(tài)的一致性韭寸。因此春哨,F(xiàn)link 能夠在應(yīng)用程序發(fā)生故障時(shí),對(duì)應(yīng)用程序透明恩伺,不造成正確性的影響赴背。
- 超大數(shù)據(jù)量狀態(tài):Flink 能夠利用其異步以及增量式的 checkpoint 算法,存儲(chǔ)數(shù) TB 級(jí)別的應(yīng)用狀態(tài)莫其。
- 可彈性伸縮的應(yīng)用:Flink 能夠通過(guò)在更多或更少的工作節(jié)點(diǎn)上對(duì)狀態(tài)進(jìn)行重新分布癞尚,支持有狀態(tài)應(yīng)用的分布式的橫向伸縮耸三。
時(shí)間
時(shí)間是流處理應(yīng)用另一個(gè)重要的組成部分乱陡。因?yàn)槭录偸窃谔囟〞r(shí)間點(diǎn)發(fā)生,所以大多數(shù)的事件流都擁有事件本身所固有的時(shí)間語(yǔ)義仪壮。進(jìn)一步而言憨颠,許多常見的流計(jì)算都基于時(shí)間語(yǔ)義,例如窗口聚合、會(huì)話計(jì)算爽彤、模式檢測(cè)和基于時(shí)間的 join养盗。流處理的一個(gè)重要方面是應(yīng)用程序如何衡量時(shí)間,即區(qū)分事件時(shí)間(event-time)和處理時(shí)間(processing-time)适篙。
Flink 提供了豐富的時(shí)間語(yǔ)義支持往核。
- 事件時(shí)間模式:使用事件時(shí)間語(yǔ)義的流處理應(yīng)用根據(jù)事件本身自帶的時(shí)間戳進(jìn)行結(jié)果的計(jì)算。因此嚷节,無(wú)論處理的是歷史記錄的事件還是實(shí)時(shí)的事件聂儒,事件時(shí)間模式的處理總能保證結(jié)果的準(zhǔn)確性和一致性。
- Watermark 支持:Flink 引入了 watermark 的概念硫痰,用以衡量事件時(shí)間進(jìn)展衩婚。Watermark 也是一種平衡處理延時(shí)和完整性的靈活機(jī)制。
- 遲到數(shù)據(jù)處理:當(dāng)以帶有 watermark 的事件時(shí)間模式處理數(shù)據(jù)流時(shí)效斑,在計(jì)算完成之后仍會(huì)有相關(guān)數(shù)據(jù)到達(dá)非春。這樣的事件被稱為遲到事件。Flink 提供了多種處理遲到數(shù)據(jù)的選項(xiàng)缓屠,例如將這些數(shù)據(jù)重定向到旁路輸出(side output)或者更新之前完成計(jì)算的結(jié)果奇昙。
- 處理時(shí)間模式:除了事件時(shí)間模式,F(xiàn)link 還支持處理時(shí)間語(yǔ)義敌完。處理時(shí)間模式根據(jù)處理引擎的機(jī)器時(shí)鐘觸發(fā)計(jì)算敬矩,一般適用于有著嚴(yán)格的低延遲需求,并且能夠容忍近似結(jié)果的流處理應(yīng)用蠢挡。
分層 API
Flink 根據(jù)抽象程度分層弧岳,提供了三種不同的 API。每一種 API 在簡(jiǎn)潔性和表達(dá)力上有著不同的側(cè)重业踏,并且針對(duì)不同的應(yīng)用場(chǎng)景禽炬。
下文中,我們將簡(jiǎn)要描述每一種 API 及其應(yīng)用勤家,并提供相關(guān)的代碼示例腹尖。
ProcessFunction
ProcessFunction 是 Flink 所提供的最具表達(dá)力的接口。ProcessFunction 可以處理一或兩條輸入數(shù)據(jù)流中的單個(gè)事件或者歸入一個(gè)特定窗口內(nèi)的多個(gè)事件伐脖。它提供了對(duì)于時(shí)間和狀態(tài)的細(xì)粒度控制热幔。開發(fā)者可以在其中任意地修改狀態(tài),也能夠注冊(cè)定時(shí)器用以在未來(lái)的某一時(shí)刻觸發(fā)回調(diào)函數(shù)讼庇。因此绎巨,你可以利用 ProcessFunction 實(shí)現(xiàn)許多有狀態(tài)的事件驅(qū)動(dòng)應(yīng)用所需要的基于單個(gè)事件的復(fù)雜業(yè)務(wù)邏輯。
下面的代碼示例展示了如何在 KeyedStream
上利用 KeyedProcessFunction
對(duì)標(biāo)記為 START
和 END
的事件進(jìn)行處理蠕啄。當(dāng)收到 START
事件時(shí)场勤,處理函數(shù)會(huì)記錄其時(shí)間戳戈锻,并且注冊(cè)一個(gè)時(shí)長(zhǎng)4小時(shí)的計(jì)時(shí)器。如果在計(jì)時(shí)器結(jié)束之前收到 END
事件和媳,處理函數(shù)會(huì)計(jì)算其與上一個(gè) START
事件的時(shí)間間隔漠其,清空狀態(tài)并將計(jì)算結(jié)果返回志于。否則幔摸,計(jì)時(shí)器結(jié)束件舵,并清空狀態(tài)。
/**
* 將相鄰的 keyed START 和 END 事件相匹配并計(jì)算兩者的時(shí)間間隔
* 輸入數(shù)據(jù)為 Tuple2<String, String> 類型她倘,第一個(gè)字段為 key 值坪它,
* 第二個(gè)字段標(biāo)記 START 和 END 事件。
*/
public static class StartEndDuration
extends KeyedProcessFunction<String, Tuple2<String, String>, Tuple2<String, Long>> {
private ValueState<Long> startTime;
@Override
public void open(Configuration conf) {
// obtain state handle
startTime = getRuntimeContext()
.getState(new ValueStateDescriptor<Long>("startTime", Long.class));
}
/** Called for each processed event. */
@Override
public void processElement(
Tuple2<String, String> in,
Context ctx,
Collector<Tuple2<String, Long>> out) throws Exception {
switch (in.f1) {
case "START":
// set the start time if we receive a start event.
startTime.update(ctx.timestamp());
// register a timer in four hours from the start event.
ctx.timerService()
.registerEventTimeTimer(ctx.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, ctx.timestamp() - sTime));
// clear the state
startTime.clear();
}
default:
// do nothing
}
}
/** Called when a timer fires. */
@Override
public void onTimer(
long timestamp,
OnTimerContext ctx,
Collector<Tuple2<String, Long>> out) {
// Timeout interval exceeded. Cleaning up the state.
startTime.clear();
}
}
這個(gè)例子充分展現(xiàn)了 KeyedProcessFunction
強(qiáng)大的表達(dá)力帝牡,也因此是一個(gè)實(shí)現(xiàn)相當(dāng)復(fù)雜的接口往毡。
DataStream API
DataStream API 為許多通用的流處理操作提供了處理原語(yǔ)。這些操作包括窗口靶溜、逐條記錄的轉(zhuǎn)換操作开瞭,在處理事件時(shí)進(jìn)行外部數(shù)據(jù)庫(kù)查詢等。DataStream API 支持 Java 和 Scala 語(yǔ)言罩息,預(yù)先定義了例如map()
嗤详、reduce()
、aggregate()
等函數(shù)瓷炮。你可以通過(guò)擴(kuò)展實(shí)現(xiàn)預(yù)定義接口或使用 Java葱色、Scala 的 lambda 表達(dá)式實(shí)現(xiàn)自定義的函數(shù)。
下面的代碼示例展示了如何捕獲會(huì)話時(shí)間范圍內(nèi)所有的點(diǎn)擊流事件娘香,并對(duì)每一次會(huì)話的點(diǎn)擊量進(jìn)行計(jì)數(shù)苍狰。
// 網(wǎng)站點(diǎn)擊 Click 的數(shù)據(jù)流
DataStream<Click> clicks = ...
DataStream<Tuple2<String, Long>> result = clicks
// 將網(wǎng)站點(diǎn)擊映射為 (userId, 1) 以便計(jì)數(shù)
.map(
// 實(shí)現(xiàn) MapFunction 接口定義函數(shù)
new MapFunction<Click, Tuple2<String, Long>>() {
@Override
public Tuple2<String, Long> map(Click click) {
return Tuple2.of(click.userId, 1L);
}
})
// 以 userId (field 0) 作為 key
.keyBy(0)
// 定義 30 分鐘超時(shí)的會(huì)話窗口
.window(EventTimeSessionWindows.withGap(Time.minutes(30L)))
// 對(duì)每個(gè)會(huì)話窗口的點(diǎn)擊進(jìn)行計(jì)數(shù),使用 lambda 表達(dá)式定義 reduce 函數(shù)
.reduce((a, b) -> Tuple2.of(a.f0, a.f1 + b.f1));
SQL & Table API
Flink 支持兩種關(guān)系型的 API烘绽,Table API 和 SQL淋昭。這兩個(gè) API 都是批處理和流處理統(tǒng)一的 API,這意味著在無(wú)邊界的實(shí)時(shí)數(shù)據(jù)流和有邊界的歷史記錄數(shù)據(jù)流上安接,關(guān)系型 API 會(huì)以相同的語(yǔ)義執(zhí)行查詢翔忽,并產(chǎn)生相同的結(jié)果。Table API 和 SQL 借助了 Apache Calcite 來(lái)進(jìn)行查詢的解析盏檐,校驗(yàn)以及優(yōu)化歇式。它們可以與 DataStream 和 DataSet API 無(wú)縫集成,并支持用戶自定義的標(biāo)量函數(shù)胡野,聚合函數(shù)以及表值函數(shù)材失。
Flink 的關(guān)系型 API 旨在簡(jiǎn)化數(shù)據(jù)分析、數(shù)據(jù)流水線和 ETL 應(yīng)用的定義给涕。
下面的代碼示例展示了如何使用 SQL 語(yǔ)句查詢捕獲會(huì)話時(shí)間范圍內(nèi)所有的點(diǎn)擊流事件豺憔,并對(duì)每一次會(huì)話的點(diǎn)擊量進(jìn)行計(jì)數(shù)。此示例與上述 DataStream API 中的示例有著相同的邏輯够庙。
SELECT userId, COUNT(*)
FROM clicks
GROUP BY SESSION(clicktime, INTERVAL '30' MINUTE), userId
庫(kù)
Flink 具有數(shù)個(gè)適用于常見數(shù)據(jù)處理應(yīng)用場(chǎng)景的擴(kuò)展庫(kù)恭应。這些庫(kù)通常嵌入在 API 中,且并不完全獨(dú)立于其它 API耘眨。它們也因此可以受益于 API 的所有特性昼榛,并與其他庫(kù)集成。
復(fù)雜事件處理(CEP):模式檢測(cè)是事件流處理中的一個(gè)非常常見的用例剔难。Flink 的 CEP 庫(kù)提供了 API胆屿,使用戶能夠以例如正則表達(dá)式或狀態(tài)機(jī)的方式指定事件模式。CEP 庫(kù)與 Flink 的 DataStream API 集成偶宫,以便在 DataStream 上評(píng)估模式非迹。CEP 庫(kù)的應(yīng)用包括網(wǎng)絡(luò)入侵檢測(cè),業(yè)務(wù)流程監(jiān)控和欺詐檢測(cè)纯趋。
DataSet API:DataSet API 是 Flink 用于批處理應(yīng)用程序的核心 API憎兽。DataSet API 所提供的基礎(chǔ)算子包括map、reduce吵冒、(outer) join纯命、co-group、iterate等痹栖。所有算子都有相應(yīng)的算法和數(shù)據(jù)結(jié)構(gòu)支持亿汞,對(duì)內(nèi)存中的序列化數(shù)據(jù)進(jìn)行操作。如果數(shù)據(jù)大小超過(guò)預(yù)留內(nèi)存揪阿,則過(guò)量數(shù)據(jù)將存儲(chǔ)到磁盤疗我。Flink 的 DataSet API 的數(shù)據(jù)處理算法借鑒了傳統(tǒng)數(shù)據(jù)庫(kù)算法的實(shí)現(xiàn),例如混合散列連接(hybrid hash-join)和外部歸并排序(external merge-sort)南捂。
Gelly: Gelly 是一個(gè)可擴(kuò)展的圖形處理和分析庫(kù)碍粥。Gelly 是在 DataSet API 之上實(shí)現(xiàn)的,并與 DataSet API 集成黑毅。因此嚼摩,它能夠受益于其可擴(kuò)展且健壯的操作符。Gelly 提供了內(nèi)置算法矿瘦,如 label propagation枕面、triangle enumeration 和 page rank 算法,也提供了一個(gè)簡(jiǎn)化自定義圖算法實(shí)現(xiàn)的 Graph API缚去。
Flink 技術(shù)特性
部署應(yīng)用到任意地方
Apache Flink 是一個(gè)分布式系統(tǒng)潮秘,它需要計(jì)算資源來(lái)執(zhí)行應(yīng)用程序。Flink 集成了所有常見的集群資源管理器易结,例如 Hadoop YARN枕荞、 Apache Mesos 和 Kubernetes柜候,但同時(shí)也可以作為獨(dú)立集群運(yùn)行。
Flink 被設(shè)計(jì)為能夠很好地工作在上述每個(gè)資源管理器中躏精,這是通過(guò)資源管理器特定(resource-manager-specific)的部署模式實(shí)現(xiàn)的渣刷。Flink 可以采用與當(dāng)前資源管理器相適應(yīng)的方式進(jìn)行交互。
部署 Flink 應(yīng)用程序時(shí)矗烛,F(xiàn)link 會(huì)根據(jù)應(yīng)用程序配置的并行性自動(dòng)標(biāo)識(shí)所需的資源辅柴,并從資源管理器請(qǐng)求這些資源。在發(fā)生故障的情況下瞭吃,F(xiàn)link 通過(guò)請(qǐng)求新資源來(lái)替換發(fā)生故障的容器碌嘀。提交或控制應(yīng)用程序的所有通信都是通過(guò) REST 調(diào)用進(jìn)行的,這可以簡(jiǎn)化 Flink 與各種環(huán)境中的集成歪架。
運(yùn)行任意規(guī)模應(yīng)用
Flink 旨在任意規(guī)模上運(yùn)行有狀態(tài)流式應(yīng)用股冗。因此,應(yīng)用程序被并行化為可能數(shù)千個(gè)任務(wù)和蚪,這些任務(wù)分布在集群中并發(fā)執(zhí)行魁瞪。所以應(yīng)用程序能夠充分利用無(wú)盡的 CPU、內(nèi)存惠呼、磁盤和網(wǎng)絡(luò) IO导俘。而且 Flink 很容易維護(hù)非常大的應(yīng)用程序狀態(tài)。其異步和增量的檢查點(diǎn)算法對(duì)處理延遲產(chǎn)生最小的影響剔蹋,同時(shí)保證精確一次狀態(tài)的一致性旅薄。
Flink 用戶報(bào)告了其生產(chǎn)環(huán)境中一些令人印象深刻的擴(kuò)展性數(shù)字
- 處理每天處理數(shù)萬(wàn)億的事件,
- 應(yīng)用維護(hù)幾TB大小的狀態(tài), 和
- 應(yīng)用在數(shù)千個(gè)內(nèi)核上運(yùn)行。
利用內(nèi)存性能
有狀態(tài)的 Flink 程序針對(duì)本地狀態(tài)訪問(wèn)進(jìn)行了優(yōu)化泣崩。任務(wù)的狀態(tài)始終保留在內(nèi)存中少梁,如果狀態(tài)大小超過(guò)可用內(nèi)存,則會(huì)保存在能高效訪問(wèn)的磁盤數(shù)據(jù)結(jié)構(gòu)中矫付。任務(wù)通過(guò)訪問(wèn)本地(通常在內(nèi)存中)狀態(tài)來(lái)進(jìn)行所有的計(jì)算凯沪,從而產(chǎn)生非常低的處理延遲。Flink 通過(guò)定期和異步地對(duì)本地狀態(tài)進(jìn)行持久化存儲(chǔ)來(lái)保證故障場(chǎng)景下精確一次的狀態(tài)一致性买优。
運(yùn)維
Apache Flink 是一個(gè)針對(duì)無(wú)界和有界數(shù)據(jù)流進(jìn)行有狀態(tài)計(jì)算的框架妨马。由于許多流應(yīng)用程序旨在以最短的停機(jī)時(shí)間連續(xù)運(yùn)行,因此流處理器必須提供出色的故障恢復(fù)能力杀赢,以及在應(yīng)用程序運(yùn)行期間進(jìn)行監(jiān)控和維護(hù)的工具烘跺。
Apache Flink 非常注重流數(shù)據(jù)處理的可運(yùn)維性。因此在這一小節(jié)中脂崔,我們將詳細(xì)介紹 Flink 的故障恢復(fù)機(jī)制滤淳,并介紹其管理和監(jiān)控應(yīng)用的功能。
7 * 24小時(shí)穩(wěn)定運(yùn)行
在分布式系統(tǒng)中砌左,服務(wù)故障是常有的事脖咐,為了保證服務(wù)能夠7*24小時(shí)穩(wěn)定運(yùn)行铺敌,像Flink這樣的流處理器故障恢復(fù)機(jī)制是必須要有的。顯然這就意味著屁擅,它(這類流處理器)不僅要能在服務(wù)出現(xiàn)故障時(shí)候能夠重啟服務(wù)偿凭,而且還要當(dāng)故障發(fā)生時(shí),保證能夠持久化服務(wù)內(nèi)部各個(gè)組件的當(dāng)前狀態(tài)煤蹭,只有這樣才能保證在故障恢復(fù)時(shí)候笔喉,服務(wù)能夠繼續(xù)正常運(yùn)行取视,好像故障就沒(méi)有發(fā)生過(guò)一樣硝皂。
Flink通過(guò)幾下多種機(jī)制維護(hù)應(yīng)用可持續(xù)運(yùn)行及其一致性:
- 檢查點(diǎn)的一致性: Flink的故障恢復(fù)機(jī)制是通過(guò)建立分布式應(yīng)用服務(wù)狀態(tài)一致性檢查點(diǎn)實(shí)現(xiàn)的,當(dāng)有故障產(chǎn)生時(shí)作谭,應(yīng)用服務(wù)會(huì)重啟后稽物,再重新加載上一次成功備份的狀態(tài)檢查點(diǎn)信息。結(jié)合可重放的數(shù)據(jù)源折欠,該特性可保證精確一次(exactly-once)的狀態(tài)一致性贝或。
- 高效的檢查點(diǎn): 如果一個(gè)應(yīng)用要維護(hù)一個(gè)TB級(jí)的狀態(tài)信息,對(duì)此應(yīng)用的狀態(tài)建立檢查點(diǎn)服務(wù)的資源開銷是很高的锐秦,為了減小因檢查點(diǎn)服務(wù)對(duì)應(yīng)用的延遲性(SLAs服務(wù)等級(jí)協(xié)議)的影響咪奖,F(xiàn)link采用異步及增量的方式構(gòu)建檢查點(diǎn)服務(wù)。
- 端到端的精確一次: Flink 為某些特定的存儲(chǔ)支持了事務(wù)型輸出的功能酱床,及時(shí)在發(fā)生故障的情況下羊赵,也能夠保證精確一次的輸出。
- 集成多種集群管理服務(wù): Flink已與多種集群管理服務(wù)緊密集成扇谣,如 Hadoop YARN, Mesos, 以及 Kubernetes昧捷。當(dāng)集群中某個(gè)流程任務(wù)失敗后,一個(gè)新的流程服務(wù)會(huì)自動(dòng)啟動(dòng)并替代它繼續(xù)執(zhí)行罐寨。
- 內(nèi)置高可用服務(wù): Flink內(nèi)置了為解決單點(diǎn)故障問(wèn)題的高可用性服務(wù)模塊靡挥,此模塊是基于Apache ZooKeeper 技術(shù)實(shí)現(xiàn)的,Apache ZooKeeper是一種可靠的鸯绿、交互式的跋破、分布式協(xié)調(diào)服務(wù)組件。
Flink能夠更方便地升級(jí)瓶蝴、遷移幔烛、暫停、恢復(fù)應(yīng)用服務(wù)
驅(qū)動(dòng)關(guān)鍵業(yè)務(wù)服務(wù)的流應(yīng)用是經(jīng)常需要維護(hù)的囊蓝。比如需要修復(fù)系統(tǒng)漏洞饿悬,改進(jìn)功能,或開發(fā)新功能聚霜。然而升級(jí)一個(gè)有狀態(tài)的流應(yīng)用并不是簡(jiǎn)單的事情狡恬,因?yàn)樵谖覀優(yōu)榱松?jí)一個(gè)改進(jìn)后版本而簡(jiǎn)單停止當(dāng)前流應(yīng)用并重啟時(shí)珠叔,我們還不能丟失掉當(dāng)前流應(yīng)用的所處于的狀態(tài)信息。
而Flink的 Savepoint 服務(wù)就是為解決升級(jí)服務(wù)過(guò)程中記錄流應(yīng)用狀態(tài)信息及其相關(guān)難題而產(chǎn)生的一種唯一的弟劲、強(qiáng)大的組件祷安。一個(gè) Savepoint,就是一個(gè)應(yīng)用服務(wù)狀態(tài)的一致性快照兔乞,因此其與checkpoint組件的很相似汇鞭,但是與checkpoint相比,Savepoint 需要手動(dòng)觸發(fā)啟動(dòng)庸追,而且當(dāng)流應(yīng)用服務(wù)停止時(shí)霍骄,它并不會(huì)自動(dòng)刪除。Savepoint 常被應(yīng)用于啟動(dòng)一個(gè)已含有狀態(tài)的流服務(wù)淡溯,并初始化其(備份時(shí))狀態(tài)读整。Savepoint 有以下特點(diǎn):
- 便于升級(jí)應(yīng)用服務(wù)版本: Savepoint 常在應(yīng)用版本升級(jí)時(shí)使用,當(dāng)前應(yīng)用的新版本更新升級(jí)時(shí)咱娶,可以根據(jù)上一個(gè)版本程序記錄的 Savepoint 內(nèi)的服務(wù)狀態(tài)信息來(lái)重啟服務(wù)米间。它也可能會(huì)使用更早的 Savepoint 還原點(diǎn)來(lái)重啟服務(wù),以便于修復(fù)由于有缺陷的程序版本導(dǎo)致的不正確的程序運(yùn)行結(jié)果膘侮。
- 方便集群服務(wù)移植: 通過(guò)使用 Savepoint屈糊,流服務(wù)應(yīng)用可以自由的在不同集群中遷移部署。
- 方便Flink版本升級(jí): 通過(guò)使用 Savepoint琼了,可以使應(yīng)用服務(wù)在升級(jí)Flink時(shí)逻锐,更加安全便捷。
- 增加應(yīng)用并行服務(wù)的擴(kuò)展性: Savepoint 也常在增加或減少應(yīng)用服務(wù)集群的并行度時(shí)使用表伦。
- 便于A/B測(cè)試及假設(shè)分析場(chǎng)景對(duì)比結(jié)果: 通過(guò)把同一應(yīng)用在使用不同版本的應(yīng)用程序谦去,基于同一個(gè) Savepoint 還原點(diǎn)啟動(dòng)服務(wù)時(shí),可以測(cè)試對(duì)比2個(gè)或多個(gè)版本程序的性能及服務(wù)質(zhì)量蹦哼。
- 暫停和恢復(fù)服務(wù): 一個(gè)應(yīng)用服務(wù)可以在新建一個(gè) Savepoint 后再停止服務(wù)鳄哭,以便于后面任何時(shí)間點(diǎn)再根據(jù)這個(gè)實(shí)時(shí)刷新的 Savepoint 還原點(diǎn)進(jìn)行恢復(fù)服務(wù)。
- 歸檔服務(wù): Savepoint 還提供還原點(diǎn)的歸檔服務(wù)纲熏,以便于用戶能夠指定時(shí)間點(diǎn)的 Savepoint 的服務(wù)數(shù)據(jù)進(jìn)行重置應(yīng)用服務(wù)的狀態(tài)妆丘,進(jìn)行恢復(fù)服務(wù)。
監(jiān)控和控制應(yīng)用服務(wù)
如其它應(yīng)用服務(wù)一樣局劲,持續(xù)運(yùn)行的流應(yīng)用服務(wù)也需要監(jiān)控及集成到一些基礎(chǔ)設(shè)施資源管理服務(wù)中勺拣,例如一個(gè)組件的監(jiān)控服務(wù)及日志服務(wù)等。監(jiān)控服務(wù)有助于預(yù)測(cè)問(wèn)題并提前做出反應(yīng)鱼填,日志服務(wù)提供日志記錄能夠幫助追蹤药有、調(diào)查、分析故障發(fā)生的根本原因。最后愤惰,便捷易用的訪問(wèn)控制應(yīng)用服務(wù)運(yùn)行的接口也是Flink的一個(gè)重要的亮點(diǎn)特征苇经。
Flink與許多常見的日志記錄和監(jiān)視服務(wù)集成得很好,并提供了一個(gè)REST API來(lái)控制應(yīng)用服務(wù)和查詢應(yīng)用信息宦言。具體表現(xiàn)如下:
- Web UI方式: Flink提供了一個(gè)web UI來(lái)觀察扇单、監(jiān)視和調(diào)試正在運(yùn)行的應(yīng)用服務(wù)。并且還可以執(zhí)行或取消組件或任務(wù)的執(zhí)行奠旺。
- 日志集成服務(wù):Flink實(shí)現(xiàn)了流行的slf4j日志接口蜘澜,并與日志框架log4j或logback集成。
- 指標(biāo)服務(wù): Flink提供了一個(gè)復(fù)雜的度量系統(tǒng)來(lái)收集和報(bào)告系統(tǒng)和用戶定義的度量指標(biāo)信息响疚。度量信息可以導(dǎo)出到多個(gè)報(bào)表組件服務(wù)鄙信,包括 JMX, Ganglia, Graphite, Prometheus, StatsD, Datadog, 和 Slf4j.
- 標(biāo)準(zhǔn)的WEB REST API接口服務(wù): Flink提供多種REST API接口,有提交新應(yīng)用程序稽寒、獲取正在運(yùn)行的應(yīng)用程序的Savepoint服務(wù)信息扮碧、取消應(yīng)用服務(wù)等接口趟章。REST API還提供元數(shù)據(jù)信息和已采集的運(yùn)行中或完成后的應(yīng)用服務(wù)的指標(biāo)信息杏糙。
Flink 生態(tài)圈
參考資料
https://flink.apache.org
https://nightlies.apache.org/flink/flink-docs-release-1.7/concepts/runtime.html
https://nightlies.apache.org/flink/flink-docs-release-1.7/concepts/programming-model.html