Flink-支持的數據類型和實現UDF函數(更細粒度的控制流)

支持的數據類型

Flink流應用程序處理的是以數據對象表示的事件流。所以在Flink內部,我們需要能夠處理這些對象。它們需要被序列化和反序列化,以便通過網絡傳送它們;或者從狀態後端、檢查點和保存點讀取它們。爲了有效地做到這一點,Flink需要明確知道應用程序所處理的數據類型。Flink使用類型信息的概念來表示數據類型,併爲每個數據類型生成特定的序列化器、反序列化器和比較器。
Flink還具有一個類型提取系統,該系統分析函數的輸入和返回類型,以自動獲取類型信息,從而獲得序列化器和反序列化器。但是,在某些情況下,例如lambda函數或泛型類型,需要顯式地提供類型信息,才能使應用程序正常工作或提高其性能。
Flink支持Java和Scala中所有常見數據類型。使用最廣泛的類型有以下幾種。

基礎數據類型

Flink支持所有的Java和Scala基礎數據類型,Int, Double, Long, String。。。

val numbers: DataStream[Long] = env.fromElements(1L, 2L, 3L, 4L)
numbers.map( n => n + 1 )

Java和Scala元組(Tuples)

val persons: DataStream[(String, Integer)] = env.fromElements( 
("Adam", 17), 
("Sarah", 23) ) 
persons.filter(p => p._2 > 18)

Scala樣例類(case classes)

case class Person(name: String, age: Int) 
val persons: DataStream[Person] = env.fromElements(
Person("Adam", 17), 
Person("Sarah", 23) )
persons.filter(p => p.age > 18)

Java簡單對象(POJOs)

public class Person {
public String name;
public int age;
  public Person() {}
  public Person(String name, int age) { 
this.name = name;      
this.age = age;  
}
}
DataStream<Person> persons = env.fromElements(   
new Person("Alex", 42),   
new Person("Wendy", 23));

其它(Arrays, Lists, Maps, Enums, 等等)

Flink對Java和Scala中的一些特殊目的的類型也都是支持的,比如Java的ArrayList,HashMap,Enum等等。

函數類(Function Classes)

Flink暴露了所有udf函數的接口(實現方式爲接口或者抽象類)。例如MapFunction, FilterFunction, ProcessFunction等等。

class FilterFilter extends FilterFunction[String] {
      override def filter(value: String): Boolean = {
        value.contains("flink")
      }
}
val flinkTweets = tweets.filter(new FlinkFilter)

還可以將函數實現成匿名類

val flinkTweets = tweets.filter(
new RichFilterFunction[String] {
override def filter(value: String): Boolean = {
value.contains("flink")
}
}
)

我們filter的字符串"flink"還可以當作參數傳進去。

val tweets: DataStream[String] = ...
val flinkTweets = tweets.filter(new KeywordFilter("flink"))

class KeywordFilter(keyWord: String) extends FilterFunction[String] {
override def filter(value: String): Boolean = {
value.contains(keyWord)
}
}

匿名函數(Lambda Functions)

val tweets: DataStream[String] = ...
val flinkTweets = tweets.filter(_.contains("flink"))

富函數(Rich Functions)

“富函數”是DataStream API提供的一個函數類的接口,所有Flink函數類都有其Rich版本。它與常規函數的不同在於,可以獲取運行環境的上下文,並擁有一些生命週期方法,所以可以實現更復雜的功能。

 RichMapFunction
 RichFlatMapFunction
 RichFilterFunction

Rich Function有一個生命週期的概念。典型的生命週期方法有:

  1. open()方法是rich function的初始化方法,當一個算子例如map或者filter被調用之前open()會被調用。
  2. close()方法是生命週期中的最後一個調用的方法,做一些清理工作。
  3. getRuntimeContext()方法提供了函數的RuntimeContext的一些信息,例如函數執行的並行度,任務的名字,以及state狀態
class MyFlatMap extends RichFlatMapFunction[Int, (Int, Int)] {
var subTaskIndex = 0

override def open(configuration: Configuration): Unit = {
subTaskIndex = getRuntimeContext.getIndexOfThisSubtask
// 以下可以做一些初始化工作,例如建立一個和HDFS的連接
}

override def flatMap(in: Int, out: Collector[(Int, Int)]): Unit = {
if (in % 2 == subTaskIndex) {
out.collect((subTaskIndex, in))
}
}

override def close(): Unit = {
// 以下做一些清理工作,例如斷開和HDFS的連接。
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章