Flink 程序与数据流结构

Flink 应用程序结构就是如上图所示:

  • Source: 数据源,Flink 在流处理和批处理上的 source 大概有 4 类:基于本地集合的 source、基于文件的 source、基于网络套接字的 source、自定义的 source。自定义的 source 常见的有 Apache kafka、Amazon Kinesis Streams、RabbitMQ、Twitter Streaming API、Apache NiFi 等,当然你也可以定义自己的 source。
  • Transformation:数据转换的各种操作,有 Map / FlatMap / Filter / KeyBy / Reduce / Fold / Aggregations / Window / WindowAll / Union / Window join / Split / Select / Project 等,操作很多,可以将数据转换计算成你想要的数据。
  • Sink:接收器,Flink 将转换计算后的数据发送的地点 ,你可能需要存储下来,Flink 常见的 Sink 大概有如下几类:写入文件、打印出来、写入 socket 、自定义的 sink 。自定义的 sink 常见的有 Apache kafka、RabbitMQ、MySQL、ElasticSearch、Apache Cassandra、Hadoop FileSystem 等,同理你也可以定义自己的 sink。


Flink支持的数据类型



1. 原生数据类型

Flink通过实现BasicTypeInfo数据类型,能够支持Java和Scala所有的基本数据类型,比如 Integer,String,和Double等。

val intStream:DataStream[Int] = env.fromElements(3,1,3,4,6,8)

Flink实现另外一种TypeInfomation是BasicArrayTypeInfo,对应的是Java基本类型数组(装箱)或String对象的数组,如下代码通过使用Array数组和List集合创建DataStream数据集。

val dataStream:DataStream[Int] = env.fromCollection(List(3,1,2,1,5))



2. Java Tuples类型

Tuple是包含固定数量各种类型字段的复合类。Flink Java API提供了Tuple1-Tuple25。Tuple的字段可以是Flink的任意类型,甚至嵌套Tuple。

val tupleStream2:DataStream[Tuple2[String,Int]] = env.fromElements(new Tuple2("a",1) , new Tuple2("c",2))



3. Scala Case Class类型

Flink通过实现CaseClassTypeInfo支持任意的Scala Case Class,包括Scala tuples类型。

//定义 wordcount case class数据结构
case class WordCount(word:String, count:Int)
//通过fromElements方法创建数据集
val input = env.fromeElements(WordCount("hello",1),WordCount("tom",2))
//根据word字段为分区字段
val keyStream1 = input.keyBy("word")
//也可以通过指定postition分区
val keyStream2 = intput.keyBy(0)



4. POJOs类型

POJOs类型可以完成复杂数据结构的定义,Flink通过实现PojoTypeInfo来描述任意的POJOs,包括Java和Scala类。在Flink中使用POJOs类可用字段名称获取字段,例如dataStream.join(otherStream).where(“name”).equalTo(“personName”),对于用户做数据处理则非常透明和简单。使用Flink中的POJOs数据类型,需要遵循以下要求:

  • POJOs类必须是Public修饰且必须独立定义,不能是内部类;
  • POJOs类中必须含有默认空构造器;
  • POJOs类中所有的Fields必须是Public或者具有Public修饰的getter和setter方法;
  • POJOs类中的字段类型必须是Flink支持的。
public class WordWithCount {

public String word;

public int count;

public WordWithCount() {}

public WordWithCount(String word, int count) { this.word = word; this.count = count; }

}

DataStream<WordWithCount> wordCounts = env.fromElements(

new WordWithCount("hello", 1),

new WordWithCount("world", 2));

wordCounts.keyBy("word");



5. Flink Value类型

通过实现org.apache.flinktypes.Value接口的read和write方法提供自定义代码来进行序列化/反序列化,而不是使用通用的序列化框架。

Flink预定义的值类型与原生数据类型是一一对应的(例如:ByteValue, ShortValue, IntValue, LongValue, FloatValue, DoubleValue, StringValue, CharValue, BooleanValue)。这些值类型作为原生数据类型的可变变体,他们的值是可以改变的,允许程序重用对象从而缓解GC的压力。



6. 特殊类型

Flink比较特殊的类型有以下两种:

1.Scala的 Either、Option和Try。

2.Java ApI有自己的Either实现。