2018-12-20-flink(4)——Source介紹與實踐 概念 容錯 實戰 總結

本文轉自個人微信公衆號,原文鏈接。本博客評論系統需要梯子,大家關注下公衆號方便交流。

本文基於Apache Flink 1.7。

Source 就是Flink 程序的數據輸入,Flink 提供了多種數據輸入方式,下面逐一介紹。

概念

Flink預定義Sources

Flink 預定義了多種Sources。

  • 基於文件的,如readTextFile(path)readFile(fileInputFormat, path)等;
  • 基於socket的,如socketTextStream
  • 基於collections and iterators的,如fromCollection(Seq)fromElements(elements: _*)等,常用於開發測試。

Connectors

connectors 用於給接入第三方數據提供接口,現在支持的connectors 包括:

  • Apache Kafka
  • RabbitMQ
  • Apache NiFi
  • Twtter Streaming API
  • Amazon Kinesis Streams

另外,通過 Apache Bahir,可以支持ActiveMQ/Netty之類的Source。

Async I/O API

Flink 提供了外部數據存儲的異步I/O API。流計算中經常需要與外部存儲系統交互,比如取某個表的數據以便跟流中數據進行關聯,一般來說,如果用同步I/O的方式,會造成系統中出現大的等待時間,影響吞吐和延遲。爲了解決這個問題,異步I/O可以併發處理多個請求,提高吞吐,減少延遲,如下圖所示。

Queryable State

如果Flink 應用需要將大量數據寫到外部存儲,這時候很容易產生I/O 瓶頸,如果需要寫的數據是讀少寫多的數據,那麼是否可以讓外部應用自己來拉取數據呢?Queryable State 就是這個用途,提供了接口給外部應用,允許外部應用根據需要查詢Flink state,現階段Queryable State 還是Beta版,期待ing。

容錯

Flink 提供了容錯機制,以便Jobs從Failure恢復並繼續執行,Flink 提供source的 exactly-once需要source的支持,如下圖所示(注:圖片來源於Flink 官網):

實戰

預定義Sources

預定義的Source比較簡單,在程序開發、調試階段,可以採用基於Collection的Source,舉例來說:

val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime)
val stream = env.fromCollection(List(1,2,3,4,5))
stream.print
env.execute

Kafka Connector

Connectors 就以最常用的Kafka Connectors來說。Flink 提供了Flink Kafka Consumer 讀取Kafka topics的數據,Flink Kafka Consumer 集成了Flink的checkpoint 機制以提供exactly-once 語義,不僅以來Kafka Consumer 的offset 追蹤,同時將這些信息存到checkpoint。

Kafka Connector 在Flink 1.7.0後有大的改動,但還處於beta階段,所以,下面還是以flink-connector-kafka-0.11_2.11 爲例,而且,我們在生產環境也是用的這個版本。大家也可以用最新的flink-connector-kafka_2.11,這是一個通用版本,兼容0.10.0後邊的版本。

首先,在項目中import Flink Kafka Connector。

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-connector-kafka-0.11_${scala.binary.version}</artifactId>
    <version>${flink.version}</version>
</dependency>

代碼如下:

/** 註釋1
 * 啓動checkpoint(可選)
 * env.enableCheckpointing(5000); //checkpoint every 5000 msecs
 */
val properties = new Properties();
properties.setProperty("bootstrap.servers", "127.0.0.1:9092");
properties.setProperty("group.id", "groupXXX");
/** 註釋2
 * 下面配置讀取kafka topic partition 的起始偏移量(可選)
 * consumer.setStartFromEarliest();
 * consumer.setStartFromLatest();
 * consumer.setStartFromTimestamp(...);
 * consumer.setStartFromGroupOffsets();  // 默認
*/
val consumer = new FlinkKafkaConsumer011[]("topic_name", SimpleStringSchema, properties)
/** 註釋3
 * Watermark (可選)
 * consumer.assignTimestampsAndWatermarks(new CustomWatermarkEmitter());
 */
val stream = env.addSource(consumer)

1. 構造函數 ,需要三個參數:

  • topic 名
  • 反序列化方法
  • Kafka consumer的Properties

2. checkpoint,從註釋1 可以看出,Flink Kafka Consumer 可以啓動checkpoint機制,會週期性的給Kafka offsets 和 Flink的其它states 做 checkpoints,當Job 失敗時,Flink 讀取checkpoint裏最新的state並從對應offset 開始消費數據恢復運算。

3. 起始偏移量,從註釋2可以看出,Flink Kafka Consumer 允許設置讀取 Kafka Partition的起始偏移量,而且,允許不同Partitions 分別進行設置。但要注意,設置起始偏移量不適用於兩種情況:

  • Job 從failure 自動恢復。
  • 手動從某savepoint 啓動任務。

4. Kafka Topic 和Partition 自發現,比如構建Kafka Consumer時,topic名可以是正則表達式,這時候,如果有符合該正則的新的topic 加入到Kafka 集羣,可以被自動發現;另外,如果對Kafka Topic 進行RePartition,也可以自動發現,使用不多,可以自行查閱文檔。

5. Kafka Consumer與Watermark ,從註釋3可以看出,結合上篇文章,可以給數據設置方法以便給數據帶上watermark。

總結

本文主要以 Flink Kafka Connector 爲例講了Flink 裏的Sources,主要是考慮Kafka廣泛使用在實時系統中,甚至可以說是標配,後邊將開始講解Sink以及Flink SQL。

看到這裏,請掃描下方二維碼關注我,Happy Friday !

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章