Flink使用 DataSet 和 DataStream 代表数据集。DateSet 用于批处理,代表数据是有限的,而 DataStream 用于流数据,代表数据是无界的。数据集中的数据是不可以变的,也就是说不能对其中的元素增加或删除。我们通过数据源创建 DataSet 或者 DataStream ,通过 map,filter 等转换(transform)操作对数据集进行操作产生新的数据集。
编写 Flink 程序一般经过一下几个步骤:
下面我们将介绍编写 Flink 程序所涉及的基本 API。
首先,需要获得 execution 环境,Flink 提供了一下以下三种方式:
getExecutionEnvironment()
createLocalEnvironment()
createRemoteEnvironment(String host, int port, String... jarFiles)
以第一个为例创建 execution 环境的代码如下
批处理:
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
DataSet text = env.readTextFile("file:///D:\\words.txt");
text.print();
流处理:
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream text = env.readTextFile("file:///D:\\words.txt");
text.print();
env.execute();
上面代码创建了 execution 环境,同时利用 env 创建了输入源。在数据集上调用 print 方法可以将数据输出到控制台,当然也可以调用 writeAsText 等方法将数据输出到其他介质。上面流处理最后一行代码调用了 execute 方法,在流处理中需要显式调用该方法触发程序的执行。
上述代码有两种方式运行,一种是直接在 IDE 中执行,就像运行一个普通的 Java 程序,Flink 将启动一个本地的环境执行程序。另一种方式是将程序打包,提交到 Flink 集群运行。
上面例子基本包含了一个 Flink 程序的基本骨架,但是并没有对数据集进行更多的 transform 操作,下面我们简单介绍基本 transform 操作。
这里的 map 操作类似 MapReduce 中的 map,对数据进行解析,处理。示例如下
批处理:
DataSet> words = text.map(new MapFunction>() {
@Override
public Tuple2 map(String s) throws Exception {
return new Tuple2<>(s, 1);
}
});
words.print();
流处理:
DataStream> words = text.map(new MapFunction>() {
@Override
public Tuple2 map(String s) throws Exception {
return new Tuple2<>(s, 1);
}
});
words.print()
代码这里批处理和流处理除了数据集的类型不同,其余写法都一样。就是将每个单词映射成了一个 (单词, 1) 二元组。与 map 类似的 transform 还有 filter,过滤不需要的记录。
大数据处理经常需要按照某个维度进行处理,也就是需要指定 key。在 DataSet 中使用 groupBy 指定 key,而在 DataStream 中使用 keyBy 指定 key。这里我们以 keyBy 为例进行介绍。
Flink 的数据模型并不是基于 key-value 的,key 是虚拟的,可以看做是定义在数据上的函数。
在 Tuple 中定义 key
//0 代表 Tuple2 (二元组)中第一个元素
KeyedStream, Tuple> keyed = words.keyBy(0);
//0,1 代表二元组中第一个和第二个元素作为 key
KeyedStream, Tuple> keyed = words.keyBy(0,1);
嵌套的 tuple
DataStream,String,Long>> ds;
ds.keyBy(0) 将会把 Tuple2
用字段表达式指定key
public class WC {
public String word;
public int count;
}
DataStream words = // [...]
DataStream wordCounts = words.keyBy("word");
这里指定 WC 对象的 word 字段作为 key。
字段表达式语法如下:
字段表达式的举例
public static class WC {
public ComplexNestedClass complex; //nested POJO
private int count;
// getter / setter for private field (count)
public int getCount() {
return count;
}
public void setCount(int c) {
this.count = c;
}
}
public static class ComplexNestedClass {
public Integer someNumber;
public float someFloat;
public Tuple3 word;
public IntWritable hadoopCitizen;
}
使用 Key Selector 指定 key
通过 key 选择器函数来制定 key,key 选择器的输入为每个元素,输出为指定的 key,例子如下
words.keyBy(new KeySelector, Object>() {
@Override
public Object getKey(Tuple2 stringIntegerTuple2) throws Exception {
return stringIntegerTuple2.f0;
}
});
可以看到实现的效果与 keyBy(0) 是一样的。
转载自:Flink基本API的使用