Flink使用 DataSet 和 DataStream 代表数据集。DateSet 用于批处理,代表数据是有限的;而 DataStream 用于流数据,代表数据是无界的。数据集中的数据是不可以变的,也就是说不能对其中的元素增加或删除。我们通过数据源创建 DataSet 或者 DataStream ,通过 map,filter 等转换(transform)操作对数据集进行操作产生新的数据集。

编写 Flink 程序一般经过一下几个步骤:

  • 获得 execution 环境
  • 创建输入数据
  • 在数据集上进行转换操作(下文统一称为:transform)
  • 输出结果数据
  • 触发程序执行

下面我们将介绍编写 Flink 程序所涉及的基本 API。

输入和输出

首先,需要获得 execution 环境,Flink 提供了一下以下三种方式:

getExecutionEnvironment()
createLocalEnvironment()
createRemoteEnvironment(String host, int port, String... jarFiles)

以第一个为例创建 execution 环境的代码如下

批处理:

ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
DataSet<String> text = env.readTextFile("file:///D:\\words.txt");
text.print();

流处理

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> text = env.readTextFile("file:///D:\\words.txt");
text.print();
env.execute();

words.txt 文件内容:

a
b
c
d
e
a
b

上面代码创建了 execution 环境,同时利用 env 创建了输入源。在数据集上调用 print 方法可以将数据输出到控制台,当然也可以调用 writeAsText 等方法将数据输出到其他介质。上面流处理最后一行代码调用了 execute 方法,在流处理中需要显式调用该方法触发程序的执行。

上述代码有两种方式运行,一种是直接在 IDE 中执行,就像运行一个普通的 Java 程序,Flink 将启动一个本地的环境执行程序。另一种方式是将程序打包,提交到 Flink 集群运行。上面例子基本包含了一个 Flink 程序的基本骨架,但是并没有对数据集进行更多的 transform 操作,下面我们简单介绍基本 transform 操作。

map操作

这里的 map 操作类似 MapReduce 中的 map,对数据进行解析,处理。示例如下

批处理

DataSet<Tuple2<String, Integer>> words = text.map(new MapFunction<String, Tuple2<String, Integer>>() {
@Override
public Tuple2<String, Integer> map(String s) throws Exception {
return new Tuple2<>(s, 1);
}
});
words.print();

流处理

DataStream<Tuple2<String, Integer>> words = text.map(new MapFunction<String, Tuple2<String, Integer>>() {
@Override
public Tuple2<String, Integer> map(String s) throws Exception {
return new Tuple2<>(s, 1);
}
});
words.print()

这里批处理和流处理除了数据集的类型不同,其余写法都一样。就是将每个单词映射成了一个 (单词, 1) 二元组。与 map 类似的 transform 还有 filter,过滤不需要的记录,读者可以自行尝试。

指定 key

大数据处理经常需要按照某个维度进行处理,也就是需要指定 key。在 DataSet 中使用 groupBy 指定 key,而在 DataStream 中使用 keyBy 指定 key。这里我们以 keyBy 为例进行介绍。

Flink 的数据模型并不是基于 key-value 的,key 是虚拟的,可以看做是定义在数据上的函数。

在 Tuple 中定义 key

KeyedStream<Tuple2<String, Integer>, Tuple> keyed = words.keyBy(0); //0 代表 Tuple2 (二元组)中第一个元素
KeyedStream<Tuple2<String, Integer>, Tuple> keyed = words.keyBy(0,1); //0,1 代表二元组中第一个和第二个元素作为 key\

对于嵌套的 tuple

DataStream<Tuple3<Tuple2<Integer, Float>,String,Long>> ds;

ds.keyBy(0) 将会把 Tuple2<Integer, Float> 整体作为 key。

用字段表达式指定 key

public class WC {
public String word;
public int count;
}
DataStream<WC> words = // [...]
DataStream<WC> wordCounts = words.keyBy("word");

这里指定 WC 对象的 word 字段作为 key。字段表达式语法如下:

  • Java对象使用字段名作为key,例子如上
  • 对于 Tuple 类型使用字段名(f0, f1,...)或者偏移(从0开始)指定 key,例如 f0 和 5 分别代表 Tuple 第一个字段和第六个字段
  • Java 对象和 Tuple 嵌套的字段作为 key,例如:f1.user.zip 表示 Tuple 第二个字段中的 user 对象中的 zip 字段作为 key
  • 通配符 * 代表选择所有类型作为 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<Long, Long, String> word;
public IntWritable hadoopCitizen;
}
  • "count": WC类的 count 字段
  • "complex": complex 的所有字段(递归地)
  • "complex.word.f2": ComplexNestedClass 类中 word 三元组的第三个字段
  • "complex.hadoopCitizen": complex类中的 hadoopCitizen 字段

使用 Key Selector 指定 key

通过 key 选择器函数来制定 key,key 选择器的输入为每个元素,输出为指定的 key,例子如下

words.keyBy(new KeySelector<Tuple2<String, Integer>, Object>() {

            @Override
public Object getKey(Tuple2<String, Integer> stringIntegerTuple2) throws Exception {
return stringIntegerTuple2.f0;
}
});

可以看到实现的效果与 keyBy(0) 是一样的。

以上便是 Flink 指定 key 的方法。

总结

这篇文章主要介绍了 Flink 程序的基本骨架。获得环境、创建输入源、对数据集做 transform 以及输出。由于数据处理经常会按照不同维度(不同的 key)进行统计,因此,本篇内容重点介绍了 Flink 中如何指定 key。后续将会继续介绍 Flink API 的使用。

欢迎关注公众号「渡码」

Flink基本的API的更多相关文章

  1. 使用flink Table &Sql api来构建批量和流式应用(1)Table的基本概念

    从flink的官方文档,我们知道flink的编程模型分为四层,sql层是最高层的api,Table api是中间层,DataStream/DataSet Api 是核心,stateful Stream ...

  2. 使用flink Table &Sql api来构建批量和流式应用(2)Table API概述

    从flink的官方文档,我们知道flink的编程模型分为四层,sql层是最高层的api,Table api是中间层,DataStream/DataSet Api 是核心,stateful Stream ...

  3. 使用flink Table &Sql api来构建批量和流式应用(3)Flink Sql 使用

    从flink的官方文档,我们知道flink的编程模型分为四层,sql层是最高层的api,Table api是中间层,DataStream/DataSet Api 是核心,stateful Stream ...

  4. [源码分析] 带你梳理 Flink SQL / Table API内部执行流程

    [源码分析] 带你梳理 Flink SQL / Table API内部执行流程 目录 [源码分析] 带你梳理 Flink SQL / Table API内部执行流程 0x00 摘要 0x01 Apac ...

  5. Flink基本的API(续)

    上一篇介绍了编写 Flink 程序的基本步骤,以及一些常见 API,如:map.filter.keyBy 等,重点介绍了 keyBy 方法.本篇将继续介绍 Flink 中常用的 API,主要内容为 指 ...

  6. Apache Flink - Batch(DataSet API)

    Flink DataSet API编程指南: Flink中的DataSet程序是实现数据集转换的常规程序(例如,过滤,映射,连接,分组).数据集最初是从某些来源创建的(例如,通过读取文件或从本地集合创 ...

  7. Apache Flink -Streaming(DataStream API)

    综述: 在Flink中DataStream程序是在数据流上实现了转换的常规程序. 1.示范程序 import org.apache.flink.api.common.functions.FlatMap ...

  8. Flink Program Guide (3) -- Event Time (DataStream API编程指导 -- For Java)

    Event Time 本文翻译自DataStream API Docs v1.2的Event Time ------------------------------------------------ ...

  9. Flink学习笔记:Flink API 通用基本概念

    本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...

随机推荐

  1. SSIS-WMI监视文件夹

    在文档交互数据时,通常会排个job每隔几分钟执行来解析文档,但是jOb不能排的太频繁了,所以文档不能及时的被解析. 在SSIS中可以使用WMI这个组件来监视文件夹,一旦有新文档丢入就马上执行解析程序, ...

  2. Java数据类型(2)------自动封装拆箱

    目的: 自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象,以使用对象的API和引用类型操作.自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下 ...

  3. 解决debugJDK源码看不到局部变量的值

    背景:使用的jdk1.8.0_201 问题描述:在eclispe中调试代码进入到JDK源码中,想看到某个变量的值得变化,发现此变量的值没法看到 解决方案: 1.进入到你安装本机的jdk目录下,找到sr ...

  4. Linux shell变量详解

    Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个 ...

  5. 【转】Pandas学习笔记(二)选择数据

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

  6. CodeForces 150E: Freezing with Style

    题目传送门:CF150E. 据说这个傻逼题还有一个 \(\log\) 的做法,但是我还不会. 题意简述: 给定一棵 \(n\)(\(2\le n\le 10^5\))个点的树,边有边权. 定义一条路径 ...

  7. HBaseAPI

    环境准备 新建项目后在pom.xml中添加依赖: <dependency> <groupId>org.apache.hbase</groupId> <arti ...

  8. zy的日志报表执行有问题。crontab显示执行了任务,代码中应该有问题

    crontab定时任务在日志记录中是执行了 但是在执行脚本的过程中报错了, 找不到问题原因,以后也要在脚本中加入日志记录, 但是奇怪的是在中午和晚上是正常的, 应该是那个时间段的判断逻辑有问题,导致程 ...

  9. ESA2GJK1DH1K基础篇: Android实现SmartConfig简单Demo

    下载源码去 百度安信可 导入源码 等待加载完 我的提示更新下软件 ,我就更新下 安装完成以后重新导入工程 安装到手机 注意,由于Android 9.0 以后的获取WIFI名称需要打开GPS,所以如果提 ...

  10. priority_queue(优先队列)使用方法

    priority_queue默认是一个大根堆: 并且出队方式与普通队列queue的front不一样,是top . 如果想用小根堆,可以修改定义时的参数: priority_queue<int,v ...