Flink-數(shù)據(jù)流編程模型

姓名:閔聿寬

學(xué)號(hào):16020188028

轉(zhuǎn)自:https://blog.csdn.net/silentwolfyh/article/details/82865579

【嵌牛導(dǎo)讀】數(shù)據(jù)流是我們?nèi)缃裨陔娮釉O(shè)計(jì)中常用的一種方法。下面介紹了一種新的FLINK-數(shù)據(jù)流編程模型

【嵌牛鼻子】FLINK數(shù)據(jù)流 編程模型

【嵌牛提問】FLINK-數(shù)據(jù)流編程模型具有怎樣的特點(diǎn)和優(yōu)勢?

目錄:

1、抽象等級(jí)

2、程序和數(shù)據(jù)流

3、并行數(shù)據(jù)流

4、窗口

5、時(shí)間

6、狀態(tài)操作

7、容錯(cuò)檢查點(diǎn)

8、批處理流

1、抽象等級(jí)

Flink提供了不同級(jí)別的抽象來開發(fā)流/批處理應(yīng)用程序。

1) 低層級(jí)的抽象

最低層次的抽象僅僅提供有狀態(tài)流。它通過Process函數(shù)嵌入到DataStream API中。它允許用戶自由地處理來自一個(gè)或多個(gè)流的事件,并使用一致的容錯(cuò)狀態(tài)。此外,用戶可以注冊事件時(shí)間和處理時(shí)間回調(diào),允許程序?qū)崿F(xiàn)復(fù)雜的計(jì)算。

2) 核心API

在實(shí)踐中,大多數(shù)應(yīng)用程序不需要上面描述的低級(jí)抽象,而是對核心API進(jìn)行編程,比如DataStream API(有界或無界數(shù)據(jù)流)和DataSet API(有界數(shù)據(jù)集)。這些API提供了用于數(shù)據(jù)處理的通用構(gòu)建塊,比如由用戶定義的多種形式的轉(zhuǎn)換、連接、聚合、窗口、狀態(tài)等。在這些api中處理的數(shù)據(jù)類型以類(class)的形式由各自的編程語言所表示。

低級(jí)流程函數(shù)與DataStream API集成,使得只對某些操作進(jìn)行低級(jí)抽象成為可能。DataSet API為有界數(shù)據(jù)集提供了額外的原語,比如循環(huán)或迭代。

3) Table API

Table API是一個(gè)以表為中心的聲明性DSL,其中表可以動(dòng)態(tài)地改變(當(dāng)表示流數(shù)據(jù)時(shí))。表API遵循(擴(kuò)展)關(guān)系模型:表有一個(gè)附加模式(類似于關(guān)系數(shù)據(jù)庫表)和API提供了類似的操作,如select, project, join, group-by, aggregate 等。Table API 程序以聲明的方式定義邏輯操作應(yīng)該做什么而不是指定操作的代碼看起來如何。雖然Table API可以通過各種用戶定義函數(shù)進(jìn)行擴(kuò)展,但它的表達(dá)性不如核心API,但使用起來更簡潔(編寫的代碼更少)。此外,Table API程序還可以在執(zhí)行之前通過應(yīng)用優(yōu)化規(guī)則的優(yōu)化器??梢詿o縫地在Table API和DataStream/DataSet API之間進(jìn)行切換,允許程序?qū)able API和DataStream和DataSet API進(jìn)行混合使用。

4) Sql層

Flink提供的最高級(jí)別抽象是SQL。這種抽象在語義和表示方面都類似于Table API,但將程序表示為SQL查詢表達(dá)式。SQL抽象與表API密切交互,SQL查詢可以在表API中定義的表上執(zhí)行。

2、程序和數(shù)據(jù)流

Flink程序的基本構(gòu)建模塊是streams 和 transformations 。(請注意,F(xiàn)link的DataSet API中使用的數(shù)據(jù)集也是內(nèi)部流——稍后將對此進(jìn)行詳細(xì)介紹。)從概念上講,streams 是數(shù)據(jù)記錄的(可能是無限的)流,而transformations是將一個(gè)或多個(gè)流作為輸入并產(chǎn)生一個(gè)或多個(gè)輸出流的操作。

執(zhí)行時(shí),F(xiàn)link程序被映射到流數(shù)據(jù)流,由streams 和 transformations 操作符組成。每個(gè)數(shù)據(jù)流以一個(gè)或多個(gè)sources開始,以一個(gè)或多個(gè)sinks結(jié)束。數(shù)據(jù)流類似于任意有向無環(huán)圖(DAGs)。雖然通過迭代構(gòu)造允許特殊形式的循環(huán),但為了簡單起見,我們將在大多數(shù)情況下忽略這一點(diǎn)。

通常在程序中的transformations和數(shù)據(jù)流中的操作之間是一對一的對應(yīng)關(guān)系。然而,有時(shí)一個(gè)transformations可能包含多個(gè)transformations操作。

在streming連接器和批處理連接器文檔中記錄了Sources 和 sinks。在DataStream運(yùn)算和數(shù)據(jù)集transformations中記錄了transformations。

3、并行數(shù)據(jù)流

Flink中的程序本質(zhì)上是并行的和分布式的。在執(zhí)行期間,流有一個(gè)或多個(gè)流分區(qū),每個(gè)operator?有一個(gè)或多個(gè)operator subtasks(操作子任務(wù))。operator subtasks相互獨(dú)立,在不同的線程中執(zhí)行,可能在不同的機(jī)器或容器上執(zhí)行。

operator subtasks的數(shù)量是特定運(yùn)算符的并行度。一個(gè)流的并行性總是它的生產(chǎn)操作符的并行性。同一程序的不同運(yùn)算符可能具有不同級(jí)別的并行性。

流可以在兩個(gè)操作符之間以一對一(或轉(zhuǎn)發(fā))模式傳輸數(shù)據(jù),也可以在重新分配模式中傳輸數(shù)據(jù):

One-to-one?流(例如上圖中Source和map()運(yùn)算符之間的流)保持元素的分區(qū)和順序。這意味著map()操作符的subtask[1]將看到與源操作符的subtask[1]生成的元素相同的順序。

Redistributing?流(如上面的map()和keyBy/window之間,以及keyBy/window和Sink之間)改變流的分區(qū)。每個(gè)操作符子任務(wù)根據(jù)所選的轉(zhuǎn)換將數(shù)據(jù)發(fā)送到不同的目標(biāo)子任務(wù)。例如keyBy()(通過散列鍵來重新分區(qū))、broadcast()或balanced()(隨機(jī)重新分區(qū))。在重分發(fā)交換中,元素之間的順序只保留在每一對發(fā)送和接收子任務(wù)中(例如map()的子任務(wù)[1]和keyBy/window的子任務(wù)[2])。因此,在本例中,每個(gè)鍵中的順序都是保留的,但是并行性確實(shí)引入了關(guān)于不同鍵的聚合結(jié)果到達(dá)sink的順序的不確定性。

4、窗口

聚合事件(例如計(jì)數(shù)、求和)在流上的工作方式與批處理不同。例如,不可能計(jì)算流中的所有元素,因?yàn)榱魍ǔJ菬o限的(無界的)。相反,流上的聚合(計(jì)數(shù)、求和等)是由窗口限定作用域的,例如“過去5分鐘的計(jì)數(shù)”或“最后100個(gè)元素的總和”。

Windows可以是時(shí)間驅(qū)動(dòng)(示例:每30秒)或數(shù)據(jù)驅(qū)動(dòng)(示例:每100個(gè)元素)。一個(gè)典型的方法是區(qū)分不同類型的窗口,比如翻滾窗戶(沒有重疊)、滑動(dòng)窗口(有重疊)和會(huì)話窗口(中間有一個(gè)不活躍的間隙)。

5、時(shí)間

? ? ? ?當(dāng)提到流程序中的時(shí)間(例如定義窗口)時(shí),可以指不同的時(shí)間概念:

事件時(shí)間 : 是創(chuàng)建事件的時(shí)間。它通常由事件中的時(shí)間戳描述,例如由生產(chǎn)傳感器或生產(chǎn)服務(wù)附加。Flink通過時(shí)間戳轉(zhuǎn)讓者訪問事件時(shí)間戳。

攝入時(shí)間 : 在source操作符中一個(gè)事件進(jìn)入Flink數(shù)據(jù)流的時(shí)間。

處理時(shí)間 : 是執(zhí)行基于時(shí)間的操作的每個(gè)操作符的本地時(shí)間。

6、狀態(tài)操作

雖然一個(gè)數(shù)據(jù)流中有許多操作但只看作一個(gè)單獨(dú)的事件(例如事件解析器),但是一些操作記住了跨多個(gè)事件的信息(例如窗口操作符)。這些操作稱為有狀態(tài)操作。

有狀態(tài)操作的狀態(tài)被維護(hù)在可以認(rèn)為是嵌入式鍵/值存儲(chǔ)中。狀態(tài)與有狀態(tài)操作符讀取的流一起被嚴(yán)格地分區(qū)和分布。因此,在keyBy()函數(shù)之后,只能在鍵控流上訪問鍵/值狀態(tài),并且只能訪問與當(dāng)前事件的鍵相關(guān)聯(lián)的值。對齊流和狀態(tài)的鍵確保所有的狀態(tài)更新都是本地操作,保證一致性而不增加事務(wù)開銷。這種對齊還允許Flink透明地重新分配狀態(tài)和調(diào)整流分區(qū)。

(EventTime是信息自帶的時(shí)間,再進(jìn)入消息隊(duì)列,IngestionTime是進(jìn)入Flink的時(shí)間,Processing是進(jìn)入Operator的時(shí)間)

7、容錯(cuò)檢查點(diǎn)

Flink通過流回放和檢查點(diǎn)的組合實(shí)現(xiàn)了容錯(cuò)。檢查點(diǎn)與每個(gè)輸入流中的特定點(diǎn)以及每個(gè)操作符的對應(yīng)狀態(tài)相關(guān)。通過恢復(fù)操作符的狀態(tài)并從檢查點(diǎn)重新播放事件,流數(shù)據(jù)流可以在檢查點(diǎn)恢復(fù),同時(shí)保持一致性(準(zhǔn)確地說是一次處理語義)。

檢查點(diǎn)間隔是在執(zhí)行期間用恢復(fù)時(shí)間(需要重放的事件數(shù)量)來權(quán)衡容錯(cuò)開銷的一種方法。

8、批處理流

? ? ? ?Flink執(zhí)行批處理程序作為流程序的特殊情況,其中流是有界的(有限的元素?cái)?shù)量)。數(shù)據(jù)集在內(nèi)部被視為數(shù)據(jù)流。因此,上述概念同樣適用于批處理程序,也適用于流程序,但有少數(shù)例外:

批處理程序的容錯(cuò)不使用檢查點(diǎn)?;謴?fù)通過完全重放流來實(shí)現(xiàn)。這是可能的,因?yàn)檩斎胧怯薪绲?。這將使成本更多地用于恢復(fù),但使常規(guī)處理更便宜,因?yàn)樗苊饬藱z查點(diǎn)。

數(shù)據(jù)集API中的有狀態(tài)操作使用簡化的內(nèi)存/核心外數(shù)據(jù)結(jié)構(gòu),而不是鍵/值索引。

DataSet API引入了特殊的synchronized(基于超步的)迭代,這只能在有界的流上實(shí)現(xiàn)。有關(guān)詳細(xì)信息,請查看迭代文檔。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容