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实现。