Apache Flink實戰(一) - 簡介

瞭解Flink是什麼,Flink應用程序運行的多樣化,對比業界經常使用的流處理框架,Flink的發展趨勢,Flink生態圈,Flink應用場景及Flink如何進行高效的Flink學習。git

0 相關源碼

1 前言

1.1 功能

1.2 用戶

  • 國際
  • 國內

1.3 特色

◆ 結合Java、Scala兩種語言 ◆ 從基礎到實戰 ◆ 系統學習Flink的核心知識 ◆ 快速完成從入門到上手企業開發的能力提高github

1.4 安排

◆ 初識Flink ◆ 編程模型及核心概念 ◆ DataSet API編程 ◆ DataStream API編程 ◆ Flink Table&SQL ◆ Window和Time操做 ◆ Flink Connectors ◆ Flink部署及做業提交 ◆ Flink監控及調優web

  • 使用Flink自定義數據源讀取配置數據
  • 使用Flink完成實時數據清洗
  • 使用Flink完成實時結果統計
  • 統計結果可視化展現(Kibana)

1.5 收穫

◆ 系統入門Flink開發 ◆ 掌握應用Java SE/Scala的Flink實現 ◆理解Flink項目的開發流程 ◆ 快速上手企業開發正則表達式

1.6 環境

◆ Mac OS: 10.14.12 ◆ Kafka: 1.1.1 ◆ Hadoop : CDH ( 5.15.1) ◆ ES/Kibana : 6+ ◆ FXIQ: IDEA ◆ Flink : 1.7算法

1.7 確保你已掌握

◆ 瞭解Linux經常使用基本命令的使用 ◆ 熟悉Java SE或Scala的基本使用 ◆ 熟悉Hadoop基礎應用數據庫

1.8 學習方法推薦

◆認真閱讀本教程!多思考、多動手! ◆合理利用網絡資源 ◆善於提問:QQ羣討論apache

2 教程大綱

◆ Flink概述 ◆ Flink應用場景 ◆ Flink Layer ◆ Flink發 展趨勢 ◆ Flink應用程序運行方式多樣化 ◆ 如何學習Flink ◆ Flink VS Storm VS Spark Streaming編程

Flink概述

Apache Flink是一個框架和分佈式處理引擎,用於對無界和有界數據流進行狀態計算。 Flink設計爲在全部常見的集羣環境中運行,之內存速度和任何規模執行計算。後端

在這裏,咱們解釋Flink架構的重要方面。bash

架構

處理無界和有界數據

任何類型的數據都是做爲事件流產生的。信用卡交易,傳感器測量,機器日誌或網站或移動應用程序上的用戶交互,全部這些數據都做爲流生成。

數據能夠做爲無界或有界流處理。

  • 無界流有一個開始但沒有定義的結束。它們不會在生成時終止並提供數據。必須連續處理無界流,即必須在攝取以後當即處理事件。沒法等待全部輸入數據到達,由於輸入是無界的,而且在任什麼時候間點都不會完成。處理無界數據一般要求以特定順序攝取事件,例如事件發生的順序,以便可以推斷結果完整性。

  • 有界流具備定義的開始和結束。能夠在執行任何計算以前經過攝取全部數據來處理有界流。處理有界流不須要有序攝取,由於能夠始終對有界數據集進行排序。有界流的處理也稱爲批處理

  • Apache Flink擅長處理無界和有界數據集。精確控制時間和狀態使Flink的運行時可以在無界流上運行任何類型的應用程序。有界流由算法和數據結構內部處理,這些算法和數據結構專爲固定大小的數據集而設計,從而產生出色的性能。

經過探索在Flink之上構建的用例來講服本身。

利用內存中性能

有狀態Flink應用程序針對本地狀態訪問進行了優化。任務狀態始終保留在內存中,若是狀態大小超過可用內存,則保存在訪問高效的磁盤上數據結構中。所以,任務經過訪問本地(一般是內存中)狀態來執行全部計算,從而產生很是低的處理延遲。 Flink經過按期和異步地將本地狀態檢查點到持久存儲來保證在出現故障時的一次狀態一致性。

應用

Apache Flink是一個用於對無界和有界數據流進行有狀態計算的框架。 Flink在不一樣的抽象級別提供多個API,併爲常見用例提供專用庫。

在這裏,咱們介紹Flink易於使用和富有表現力的API和庫。

流媒體應用程序的構建塊

能夠由流處理框架構建和執行的應用程序類型由框架控制流,狀態和時間的程度來定義。在下文中,咱們描述了流處理應用程序的這些構建塊,並解釋了Flink處理它們的方法。

顯然,流是流處理的一個基本方面。可是,流能夠具備不一樣的特徵,這些特徵會影響流的處理方式。 Flink是一個多功能的處理框架,能夠處理任何類型的流。

  • 有界和無界流:流能夠是無界的或有界的,即固定大小的數據集。 Flink具備處理無界流的複雜功能,但也有專門的運營商來有效地處理有界流。
  • 實時和記錄的流:全部數據都做爲流生成。有兩種方法能夠處理數據。在生成時實時處理它或將流持久保存到存儲系統,例如文件系統或對象存儲,並在之後處理它。 Flink應用程序能夠處理記錄或實時流。

狀態

每一個非平凡的流應用程序都是有狀態的,即,只有對各個事件應用轉換的應用程序不須要狀態。運行基本業務邏輯的任何應用程序都須要記住事件或中間結果,以便在之後的時間點訪問它們,例如在收到下一個事件時或在特定持續時間以後。

應用狀態是Flink的一等公民。您能夠經過查看Flink在狀態處理環境中提供的全部功能來查看。

  • 多狀態基元:Flink爲不一樣的數據結構提供狀態基元,例如原子值,列表或映射。開發人員能夠根據函數的訪問模式選擇最有效的狀態原語。
  • 可插拔狀態後端:應用程序狀態由可插拔狀態後端管理和檢查點。 Flink具備不一樣的狀態後端,能夠在內存或RocksDB中存儲狀態,RocksDB是一種高效的嵌入式磁盤數據存儲。也能夠插入自定義狀態後端。
  • 徹底一次的狀態一致性:Flink的檢查點和恢復算法可確保在發生故障時應用程序狀態的一致性。所以,故障是透明處理的,不會影響應用程序的正確性。
  • 很是大的狀態:因爲其異步和增量檢查點算法,Flink可以維持幾兆兆字節的應用程序狀態。 可擴展的應用程序:Flink經過將狀態從新分配給更多或更少的工做人員來支持有狀態應用程序的擴展。

時間

時間是流應用程序的另外一個重要組成部分大多數事件流都具備固有的時間語義,由於每一個事件都是在特定時間點生成的。此外,許多常見的流計算基於時間,例如窗口聚合,會話化,模式檢測和基於時間的鏈接。流處理的一個重要方面是應用程序如何測量時間,即事件時間和處理時間的差別。

Flink提供了一組豐富的與時間相關的功能。

  • 事件時間模式:使用事件時間語義處理流的應用程序根據事件的時間戳計算結果。所以,不管是否處理記錄的或實時的事件,事件時間處理都容許準確和一致的結果。
  • 水印支持:Flink使用水印來推斷事件時間應用中的時間。水印也是一種靈活的機制,能夠權衡結果的延遲和完整性。
  • 延遲數據處理:當使用水印在事件 - 時間模式下處理流時,可能會在全部相關事件到達以前完成計算。這類事件被稱爲遲發事件。 Flink具備多個選項來處理延遲事件,例如經過側輸出從新路由它們以及更新之前完成的結果。
  • 處理時間模式:除了事件時間模式以外,Flink還支持處理時間語義,該處理時間語義執行由處理機器的掛鐘時間觸發的計算。處理時間模式適用於具備嚴格的低延遲要求的某些應用,這些要求能夠容忍近似結果。

4 Layered APIs

Flink提供三層API。 每一個API在簡潔性和表達性之間提供不一樣的權衡,並針對不一樣的用例。

咱們簡要介紹每一個API,討論其應用程序,並顯示代碼示例。

ProcessFunctions

ProcessFunctions是Flink提供的最具表現力的功能接口。 Flink提供ProcessFunction來處理來自窗口中分組的一個或兩個輸入流或事件的單個事件。 ProcessFunctions提供對時間和狀態的細粒度控制。 ProcessFunction能夠任意修改其狀態並註冊將在將來觸發回調函數的定時器。所以,ProcessFunctions能夠根據許多有狀態事件驅動的應用程序的須要實現複雜的每事件業務邏輯。

如下示例顯示了一個KeyedProcessFunction,它對KeyedStream進行操做並匹配START和END事件。收到START事件時,該函數會記住其狀態的時間戳,並在四小時內註冊一個計時器。若是在計時器觸發以前收到END事件,則該函數計算END和START事件之間的持續時間,清除狀態並返回該值。不然,計時器只會觸發並清除狀態。

/**
 * Matches keyed START and END events and computes the difference between 
 * both elements' timestamps. The first String field is the key attribute, * the second String attribute marks START and END events. */ 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(); } } 複製代碼

該示例說明了KeyedProcessFunction的表達能力,但也強調了它是一個至關冗長的接口。

DataStream API

DataStream API爲許多常見的流處理操做提供原語,例如窗口化,一次記錄轉換以及經過查詢外部數據存儲來豐富事件。 DataStream API可用於Java和Scala,它基於函數,例如map(),reduce()和aggregate()。 能夠經過擴展接口或Java或Scala lambda函數來定義函數。

如下示例顯示如何對點擊流進行會話並計算每一個會話的點擊次數。

// 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));
複製代碼

SQL & Table API

Flink具備兩個關係API,Table API和SQL。 這兩個API都是用於批處理和流處理的統一API,即,在無界的實時流或有界的記錄流上以相同的語義執行查詢,併產生相同的結果。 Table API和SQL利用Apache Calcite進行解析,驗證和查詢優化。 它們能夠與DataStream和DataSet API無縫集成,並支持用戶定義的標量,聚合和表值函數。

Flink的關係API旨在簡化數據分析,數據流水線和ETL應用程序的定義。

如下示例顯示用於會話點擊流的SQL查詢,並計算每一個會話的點擊次數。 這與DataStream API示例中的用例相同。

SELECT userId, COUNT(*)
FROM clicks
GROUP BY SESSION(clicktime, INTERVAL '30' MINUTE), userId
複製代碼

Flink具備幾個用於常見數據處理用例的庫。這些庫一般嵌入在API中,而不是徹底獨立的。所以,他們能夠從API的全部功能中受益,並與其餘庫集成。

  • 復瑣事件處理(CEP):模式檢測是事件流處理的一個很是常見的用例。 Flink的CEP庫提供了一個API來指定事件模式(想一想正則表達式或狀態機)。 CEP庫與Flink的DataStream API集成,以便在DataStream上評估模式。 CEP庫的應用包括網絡入侵檢測,業務流程監控和欺詐檢測。

  • DataSet API:DataSet API是Flink用於批處理應用程序的核心API。 DataSet API的原語包括map,reduce,(外部)join,co-group和iterate。全部操做都由算法和數據結構支持,這些算法和數據結構對內存中的序列化數據進行操做,並在數據大小超過內存預算時溢出到磁盤。 Flink的DataSet API的數據處理算法受到傳統數據庫運算符的啓發,例如混合散列鏈接或外部合併排序。

  • Gelly:Gelly是一個可擴展的圖形處理和分析庫。 Gelly在DataSet API之上實現並與之集成。所以,它受益於其可擴展且強大的運營商。 Gelly具備內置算法,例如標籤傳播,三角形枚舉和頁面排名,但也提供了一種Graph API,能夠簡化自定義圖算法的實現。

5 運行多樣化

5.1 隨處部署應用程序

Apache Flink是一個分佈式系統,須要計算資源才能執行應用程序。 Flink與全部常見的集羣資源管理器(如Hadoop YARN,Apache Mesos和Kubernetes)集成,但也能夠設置爲做爲獨立集羣運行。

Flink旨在很好地運做之前列出的每一個資源管理器。 這是經過特定於資源管理器的部署模式實現的,這些模式容許Flink以其慣用方式與每一個資源管理器進行交互。

部署Flink應用程序時,Flink會根據應用程序配置的並行性自動識別所需資源,並從資源管理器請求它們。 若是發生故障,Flink會經過請求新資源來替換髮生故障的容器。提交或控制應用程序的全部通訊都經過REST調用。 這簡化了Flink在許多環境中的集成。

5.2 以任何規模運行應用程序

Flink旨在以任何規模運行有狀態流應用程序。 應用程序並行化爲數千個在集羣中分佈和同時執行的任務。所以,應用程序能夠利用幾乎無限量的CPU,主內存,磁盤和網絡IO。並且,Flink很容易保持很是大的應用程序狀態。其異步和增量檢查點算法確保對處理延遲的影響最小,同時保證一次性狀態一致性。

用戶報告了在其生產環境中運行的Flink應用程序使人印象深入的可擴展性數字,例如

  • 應用程序天天處理數萬億個事件,
  • 應用程序維護多個TB的狀態
  • 運行在數千個核心上的應用程序

6 業界流處理框架對比

7 Flink 使用案例

Apache Flink 功能強大,支持開發和運行多種不一樣種類的應用程序。它的主要特性包括:批流一體化、精密的狀態管理、事件時間支持以及精確一次的狀態一致性保障等。 Flink 不只能夠運行在包括 YARN、 Mesos、Kubernetes 在內的多種資源管理框架上,還支持在裸機集羣上獨立部署。 在啓用高可用選項的狀況下,它不存在單點失效問題。事實證實,Flink 已經能夠擴展到數千核心,其狀態能夠達到 TB 級別,且仍能保持高吞吐、低延遲的特性。世界各地有不少要求嚴苛的流處理應用都運行在 Flink 之上。

接下來咱們將介紹 Flink 常見的幾類應用並給出相關實例連接。

  • [事件驅動型應用]
  • [數據分析應用]
  • [數據管道應用]

7.1 事件驅動型應用

7.1.1 什麼是事件驅動型應用?

事件驅動型應用是一類具備狀態的應用,它從一個或多個事件流提取數據,並根據到來的事件觸發計算、狀態更新或其餘外部動做。

事件驅動型應用是在計算存儲分離的傳統應用基礎上進化而來。在傳統架構中,應用須要讀寫遠程事務型數據庫。

相反,事件驅動型應用是基於狀態化流處理來完成。在該設計中,數據和計算不會分離,應用只需訪問本地(內存或磁盤)便可獲取數據。系統容錯性的實現依賴於按期向遠程持久化存儲寫入 checkpoint。

  • 傳統應用和事件驅動型應用架構的區別

7.1.2 事件驅動型應用的優點?

事件驅動型應用無須查詢遠程數據庫,本地數據訪問使得它具備更高的吞吐和更低的延遲。而因爲按期向遠程持久化存儲的 checkpoint 工做能夠異步、增量式完成,所以對於正常事件處理的影響甚微。事件驅動型應用的優點不只限於本地數據訪問。傳統分層架構下,一般多個應用會共享同一個數據庫,於是任何對數據庫自身的更改(例如:由應用更新或服務擴容致使數據佈局發生改變)都須要謹慎協調。反觀事件驅動型應用,因爲只需考慮自身數據,所以在更改數據表示或服務擴容時所需的協調工做將大大減小。

7.1.3 Flink 如何支持事件驅動型應用?

事件驅動型應用會受制於底層流處理系統對時間和狀態的把控能力,Flink 諸多優秀特質都是圍繞這些方面來設計的。 它提供了一系列豐富的狀態操做原語,容許以精確一次的一致性語義合併海量規模(TB 級別)的狀態數據。 此外,Flink 還支持事件時間和自由度極高的定製化窗口邏輯,並且它內置的 ProcessFunction 支持細粒度時間控制,方便實現一些高級業務邏輯。 同時,Flink 還擁有一個復瑣事件處理(CEP)類庫,能夠用來檢測數據流中的模式。

Flink 中針對事件驅動應用的明星特性當屬 savepoint。Savepoint 是一個一致性的狀態映像,它能夠用來初始化任意狀態兼容的應用。在完成一次 savepoint 後,便可放心對應用升級或擴容,還能夠啓動多個版本的應用來完成 A/B 測試。

典型的事件驅動型應用實例

數據分析應用

什麼是數據分析應用?

數據分析任務須要從原始數據中提取有價值的信息和指標。傳統的分析方式一般是利用批查詢,或將事件記錄下來並基於此有限數據集構建應用來完成。爲了獲得最新數據的分析結果,必須先將它們加入分析數據集並從新執行查詢或運行應用,隨後將結果寫入存儲系統或生成報告。

藉助一些先進的流處理引擎,還能夠實時地進行數據分析。和傳統模式下讀取有限數據集不一樣,流式查詢或應用會接入實時事件流,並隨着事件消費持續產生和更新結果。這些結果數據可能會寫入外部數據庫系統或之內部狀態的形式維護。儀表展現應用能夠相應地從外部數據庫讀取數據或直接查詢應用的內部狀態。

以下圖所示,Apache Flink 同時支持流式及批量分析應用。

[圖片上傳失敗...(image-a51e80-1556549767091)]

流式分析應用的優點?

和批量分析相比,因爲流式分析省掉了週期性的數據導入和查詢過程,所以從事件中獲取指標的延遲更低。不只如此,批量查詢必須處理那些由按期導入和輸入有界性致使的人工數據邊界,而流式查詢則無須考慮該問題。

另外一方面,流式分析會簡化應用抽象。批量查詢的流水線一般由多個獨立部件組成,須要週期性地調度提取數據和執行查詢。如此複雜的流水線操做起來並不容易,一旦某個組件出錯將會影響流水線的後續步驟。而流式分析應用總體運行在 Flink 之類的高端流處理系統之上,涵蓋了從數據接入到連續結果計算的全部步驟,所以能夠依賴底層引擎提供的故障恢復機制。

Flink 如何支持數據分析類應用?

Flink 爲持續流式分析和批量分析都提供了良好的支持。具體而言,它內置了一個符合 ANSI 標準的 SQL 接口,將批、流查詢的語義統一塊兒來。不管是在記錄事件的靜態數據集上仍是實時事件流上,相同 SQL 查詢都會獲得一致的結果。同時 Flink 還支持豐富的用戶自定義函數,容許在 SQL 中執行定製化代碼。若是還需進一步定製邏輯,能夠利用 Flink DataStream API 和 DataSet API 進行更低層次的控制。此外,Flink 的 Gelly 庫爲基於批量數據集的大規模高性能圖分析提供了算法和構建模塊支持。

典型的數據分析應用實例

數據管道應用

什麼是數據管道?

提取-轉換-加載(ETL)是一種在存儲系統之間進行數據轉換和遷移的經常使用方法。ETL 做業一般會週期性地觸發,將數據從事務型數據庫拷貝到分析型數據庫或數據倉庫。

數據管道和 ETL 做業的用途類似,均可以轉換、豐富數據,並將其從某個存儲系統移動到另外一個。但數據管道是以持續流模式運行,而非週期性觸發。所以它支持從一個不斷生成數據的源頭讀取記錄,並將它們以低延遲移動到終點。例如:數據管道能夠用來監控文件系統目錄中的新文件,並將其數據寫入事件日誌;另外一個應用可能會將事件流物化到數據庫或增量構建和優化查詢索引。

下圖描述了週期性 ETL 做業和持續數據管道的差別。

image

數據管道的優點?

和週期性 ETL 做業相比,持續數據管道能夠明顯下降將數據移動到目的端的延遲。此外,因爲它可以持續消費和發送數據,所以用途更廣,支持用例更多。

Flink 如何支持數據管道應用?

不少常見的數據轉換和加強操做能夠利用 Flink 的 SQL 接口(或 Table API)及用戶自定義函數解決。若是數據管道有更高級的需求,能夠選擇更通用的 DataStream API 來實現。Flink 爲多種數據存儲系統(如:Kafka、Kinesis、Elasticsearch、JDBC數據庫系統等)內置了鏈接器。同時它還提供了文件系統的連續型數據源及數據匯,可用來監控目錄變化和以時間分區的方式寫入文件。

典型的數據管道應用實例

X 聯繫我

  • 公衆號

    圖片標題

  • Q羣

博客

  • 知乎
相關文章
相關標籤/搜索