Apache Flink API

一、Apache Flink API

Flink 提供了不同級別的抽象來開發流 / 批處理應用程序。在這裏插入圖片描述

二、SQL:

Flink 提供的最高級別的抽象是 SQL。這種抽象在語義和表達方式上均類似於 Table API,但是將程序表示爲 SQL 查詢表達式。在 SQL 抽象與 Table API SQL 查詢緊密地相互作用,並且可以在中定義的表執行 Table API

查詢

SQL

三、Table API:

Table API 是 Flink 的語言嵌入式關係 API,用於在 Java 或 Scala 中編寫類 SQL 的查詢,這些查詢會自動進行優化。Table API 查詢可以使用一致的語法和語義同時在批處理或流數據上運行。

Table API 支持非常多的 Operations(操作)

From:與 SQL 查詢中的 FROM 子句相似。掃描已註冊的表。適用於批處理和流。

Table orders = tableEnv.from("Orders");

Select:類似於 SQL SELECT 語句。執行選擇操作。適用於批處理和流。

Table orders = tableEnv.from("Orders");
Table result = orders.select("a, c as d");

As:重命名字段。適用於批處理和流。

Table orders = tableEnv.from("Orders");
Table result = orders.as("x, y, z, t");

Where / Filter: 類似於 SQL WHERE 子句。篩選出未通過篩選謂詞的行。適用於批處理和流。

Table orders = tableEnv.from("Orders");
Table result = orders.where("b === 'red'");

AddColumns: 執行字段添加操作。如果添加的字段已經存在,它將引發異常。適用於批處理和流。

Table orders = tableEnv.from("Orders");
Table result = orders.addColumns("concat(c, 'sunny')");

DropColumns: 執行字段刪除操作。字段表達式應該是字段引用表達式,並且只能刪除現有字段。適用於批處理和流。

Table orders = tableEnv.from("Orders");
Table result = orders.dropColumns("b, c");

RenameColumns: 執行字段重命名操作。字段表達式應該是別名表達式,並且只有現有字段可以重命名。適用於批處理和流。

Table orders = tableEnv.from("Orders");
Table result = orders.renameColumns("b as b2, c as c2");

GroupBy Aggregation: 類似於 SQL GROUP BY 子句。使用以下正在運行的聚合運算符將分組鍵上的行分組,以逐行聚合行。適用於批處理和流。

Table orders = tableEnv.from("Orders");
Table result = orders.groupBy("a").select("a, b.sum as d");

Inner Join: 類似於 SQL JOIN 子句。連接兩個表。兩個表必須具有不同的字段名稱,並且至少一個相等的聯接謂詞必須通過聯接運算符或使用 where 或 filter 運算符進行定義。適用於批處理和流。

Table left = tableEnv.fromDataSet(ds1, "a, b, c");
Table right = tableEnv.fromDataSet(ds2, "d, e, f");
Table result = left.join(right).where("a = d").select("a, b, e");

Outer Join: 類似於 SQL LEFT / RIGHT / FULL OUTER JOIN 子句。連接兩個表。兩個表必須具有不同的字段名稱,並且必須至少定義一個相等聯接謂詞。適用於批處理和流。

Table left = tableEnv.fromDataSet(ds1, "a, b, c");
Table right = tableEnv.fromDataSet(ds2, "d, e, f");

Table leftOuterResult = left.leftOuterJoin(right, "a = d").select("a, b, e");
Table rightOuterResult = left.rightOuterJoin(right, "a = d").select("a, b, e");
Table fullOuterResult = left.fullOuterJoin(right, "a = d").select("a, b, e");

四、DataStream/DataSet API:

處理有界數據集,對數據集進行轉換(例如,過濾,映射,聯接,分組)。最初從某些來源(例如,通過讀取文件或從本地集合)創建數據集。結果通過接收器返回,接收器可以例如將數據寫入(分佈式)文件或標準輸出(例如命令行終端)。
DataStream API 是 Flink 的主要抽象,用於通過 Java 或 Scala 實現具有複雜時間語義的有狀態數據流處理的應用程序。

1、DataSet API(Transformations(轉換)、Data Sources(數據源)、Data Sinks(數據接收器))

Transformations(轉換):
Map:取一個元素併產生一個元素。

data.map(new MapFunction<String, Integer>() {
  public Integer map(String value) { return Integer.parseInt(value); }
});

FlatMap:取一個元素併產生零個,一個或多個元素。

data.flatMap(new FlatMapFunction<String, String>() {
  public void flatMap(String value, Collector<String> out) {
    for (String s : value.split(" ")) {
      out.collect(s);
    }
  }
});

Filter: 爲每個元素評估一個布爾函數,並保留該函數返回 true 的布爾函數。

data.filter(new FilterFunction<Integer>() {
  public boolean filter(Integer value) { return value > 1000; }
});

Reduce: 通過將兩個元素重複組合爲一個元素,將一組元素組合爲一個元素。Reduce 可以應用於完整的數據集或分組的數據集。

data.reduce(new ReduceFunction<Integer> {
  public Integer reduce(Integer a, Integer b) { return a + b; }
});

Aggregate: 將一組值彙總爲一個值。可以將聚合功能視爲內置的歸約功能。彙總可以應用於完整的數據集,也可以應用於分組的數據集。

Dataset<Tuple3<Integer, String, Double>> input = // [...]
DataSet<Tuple3<Integer, String, Double>> output = input.aggregate(SUM, 0).and(MIN, 2);

2、DataStream API (Transformations(轉換)、Data Sources(數據源)、Data Sinks(數據接收器))

Transformations(轉換)
Map:取一個元素併產生一個元素。下面的例子是通過一個映射函數,將輸入流的值加倍。

DataStream<Integer> dataStream = //...
dataStream.map(new MapFunction<Integer, Integer>() {
    @Override
    public Integer map(Integer value) throws Exception {
        return 2 * value;
    }
});

FlatMap:取一個元素併產生零個,一個或多個元素。FlatMap 功能可將句子拆分爲單詞:

dataStream.flatMap(new FlatMapFunction<String, String>() {
    @Override
    public void flatMap(String value, Collector<String> out)
        throws Exception {
        for(String word: value.split(" ")){
            out.collect(word);
        }
    }
});

Filter: 爲每個元素評估一個布爾函數,並保留該函數返回 true 的布爾函數。篩選出零值的篩選器:

dataStream.filter(new FilterFunction<Integer>() {
    @Override
    public boolean filter(Integer value) throws Exception {
        return value != 0;
    }
});

Reduce: 對鍵控數據流進行 “滾動” 壓縮。將當前元素與最後一個減小的值合併,併發出新值。reduce 函數創建部分和流:

keyedStream.reduce(new ReduceFunction<Integer>() {
    @Override
    public Integer reduce(Integer value1, Integer value2)
    throws Exception {
        return value1 + value2;
    }
});

Aggregate: 在鍵控數據流上滾動聚合。min 和 minBy 之間的區別是 min 返回最小值,而 minBy 返回在此字段中具有最小值的元素(與 max 和 maxBy 相同)。

keyedStream.sum(0);
keyedStream.sum("key");
keyedStream.min(0);
keyedStream.min("key");
keyedStream.max(0);
keyedStream.max("key");
keyedStream.minBy(0);
keyedStream.minBy("key");
keyedStream.maxBy(0);
keyedStream.maxBy("key");

Window:可以在已分區的 KeyedStreams 上定義 Windows。Windows 根據某些特徵將每個鍵中的數據分組(例如,最近 5 秒鐘內到達的數據)。

dataStream.keyBy(0).window(TumblingEventTimeWindows.of(Time.seconds(5))); // Last 5 seconds of data

Window Join:在給定鍵和一個公共窗口上連接兩個數據流。

dataStream.join(otherStream)
    .where(<key selector>).equalTo(<key selector>)
    .window(TumblingEventTimeWindows.of(Time.seconds(3)))
    .apply (new JoinFunction () {...});

Aggregations on windows:聚合窗口的內容。min 和 minBy 之間的區別是 min 返回最小值,而 minBy 返回在此字段中具有最小值的元素(與 max 和 maxBy 相同)。

windowedStream.sum(0);
windowedStream.sum("key");
windowedStream.min(0);
windowedStream.min("key");
windowedStream.max(0);
windowedStream.max("key");
windowedStream.minBy(0);
windowedStream.minBy("key");
windowedStream.maxBy(0);
windowedStream.maxBy("key");

3、Data Sources(數據源)

基於文件:

readTextFile(path)/ TextInputFormat- 逐行讀取文件,並將其作爲字符串返回。
readTextFileWithValue(path)/ TextValueInputFormat- 逐行讀取文件,並將它們作爲 StringValues 返回。StringValue 是可變的字符串。
readCsvFile(path)/ CsvInputFormat- 解析以逗號(或其他字符)分隔的字段的文件。返回元組或 POJO 的數據集。支持基本的 Java 類型及其與 Value 相對應的字段類型。
readFileOfPrimitives(path, Class)/ PrimitiveInputFormat- 解析以換行符(或其他 char 序列)分隔的原始數據類型的文件,例如 String 或 Integer。
readFileOfPrimitives(path, delimiter, Class)/ PrimitiveInputFormat- 解析以換行符(或其他 char 序列)分隔的原始數據類型的文件,例如 String 或 Integer 使用給定的分隔符。
readFile(fileInputFormat, path) - 根據指定的文件輸入格式讀取(一次)文件。
readFile(fileInputFormat, path, watchType, interval, pathFilter, typeInfo)- 這是前兩個內部調用的方法。它 path 根據給定的讀取文件 fileInputFormat。根據提供的內容 watchType,此源可以定期(每 intervalms)監視路徑中的新數據(FileProcessingMode.PROCESS_CONTINUOUSLY),或者處理一次當前路徑中的數據並退出(FileProcessingMode.PROCESS_ONCE)。使用 pathFilter,用戶可以進一步從文件中排除文件。

基於套接字:

socketTextStream- 從套接字讀取。元素可以由定界符分隔。

基於集合:

fromCollection(Collection)- 從 Java.util.Collection 創建數據集。集合中的所有元素必須具有相同的類型。
fromCollection(Iterator, Class)- 從迭代器創建數據集。該類指定迭代器返回的元素的數據類型。
fromElements(T ...)- 從給定的對象序列創建數據集。所有對象必須具有相同的類型。
fromParallelCollection(SplittableIterator, Class)- 從迭代器並行創建數據集。該類指定迭代器返回的元素的數據類型。
generateSequence(from, to) - 並行生成給定間隔中的數字序列。

通用:

readFile(inputFormat, path)/ FileInputFormat- 接受文件輸入格式。
createInput(inputFormat)/ InputFormat- 接受通用輸入格式。

4、Data Sinks(數據接收器)

writeAsText()/ TextOutputFormat- 將元素按行寫爲字符串。通過調用每個元素的 * toString()* 方法獲得字符串。
writeAsFormattedText()/ TextOutputFormat- 將元素按行寫爲字符串。通過爲每個元素調用用戶定義的 * format()* 方法來獲取字符串。
writeAsCsv(...)/ CsvOutputFormat- 將元組寫爲逗號分隔的值文件。行和字段定界符是可配置的。每個字段的值來自對象的 * toString()* 方法。
print()/ printToErr() - 在標準輸出 / 標準錯誤流上打印每個元素的 toString()值。可選地,可以提供前綴(msg),該前綴在輸出之前。這可以幫助區分不同的打印調用。如果並行度大於 1,則輸出之前還將帶有產生輸出的任務的標識符。
writeUsingOutputFormat()/ FileOutputFormat- 的方法和自定義文件輸出基類。支持自定義對象到字節的轉換。
writeToSocket - 根據一個元素將元素寫入套接字 SerializationSchema
addSink- 調用自定義接收器功能。Flink 捆綁有與其他系統(例如 Apache Kafka)的連接器,這些連接器已實現爲接收器功能。
write()/ FileOutputFormat- 的方法和自定義文件輸出基類。支持自定義對象到字節的轉換。
output()/ OutputFormat- 最通用的輸出方法,用於不基於文件的數據接收器(例如將結果存儲在數據庫中)。

五、Stateful Stream Processing:

通過 Process Function 嵌入到 DataStream API 中。它允許用戶自由地處理一個或多個流中的事件,並使用一致的容錯狀態。此外,用戶可以註冊事件時間和處理時間回調,從而允許程序實現複雜的計算。

參考:RangeYan
參考:API

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