Apache Flink - 基本API概念
- Flink程序是实现分布式集合转换的常规程序。集合最初是从源创建的。通过接收器(slink)返回结果,接收器可以将数据写到某个文件或stdout。Flink可以在各种环境(context)中运行,本地JVM或集群。
1.数据集和数据流
- Flink用特殊的类
DataSet
andDataStream来表示程序中的数据。可以认为他们是可以包含重复数据的不可变数据集合。在DataSet中数据是有限的,而在DataStream中数据是无限的。
- 这些集合不同于java里的集合,他们是不可变的,一旦被创造就不能改动,也不能简单的抽查里面的元素。
- 最初的集合是通过在Flink程序里添加一个源被创造的,新的集合是使用API方法(如
map
,filter
)通过转换得到的。
2.剖析一个Flink程序
- 每个程序包含相同的基本部分:
- 获得一个执行环境(execution environment).
- 加载/创建初始数据。
- 指定转换这些数据。
- 指定放置计算结果的位置。
- 触发程序执行。
- StreamExecutionEnvironment是所有Flink程序的基础。可以通过以下静态方法获得:
getExecutionEnvironment() createLocalEnvironment() createRemoteEnvironment(String host, int port, String... jarFiles)
通常只需要使用getExecutionEnvironment()方法,因为这将根据环境做出正确的事:如果你执行你的程序在IDE上或着作为一个普通Java程序,它将创建一个本地环境,将在本地机器上执行程序。如果您从您的程序创建了一个JAR文件,并通过命令行调用它,Flink集群管理者将执行你的main方法并且getExecutionEnvironment()将返回一个在一个集群上执行程序的执行环境。
- 用于指定数据源,执行环境有几个方法来从文件读取:你可以逐行阅读,像CSV文件,或者使用完全自定义数据输入格式。要读取一个文本文件的顺序,您可以使用:
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); DataStream<String> text = env.readTextFile("file:///path/to/file");
这将给你一个数据流,然后,您可以通过转换创建新的派生数据流。
- 你可以通过调用DataStream数据转换方法转换。例如,一个map转换看起来像这样:
DataStream<String> input = ...; DataStream<Integer> parsed = input.map(new MapFunction<String, Integer>() {
@Override
public Integer map(String value) {
return Integer.parseInt(value);
}
});通过将原始集合中的每个字符串转换为整数,这将创建一个新的数据流。
- 一旦你有了一个包含你的最终结果的数据流,通过创建一个sink可以把它写一个外部系统。这些是一些创建一个sink的的方法示例:
writeAsText(String path) print()
- 一旦你指定完整程序,你需要通过调用StreamExecutionEnvironment上的execute()去触发程序执行。根据ExecutionEnvironment的类型,执行将会被触发在你的本地机器上或提交程序在集群上执行。这个execute()方法返回一个JobExecutionResult,它包含执行时间和累加结果。
3.延迟计算
- 所有Flink程序都是延迟执行的:当一个程序的main方法被执行时,数据加载和转换没有被立刻发生,相反,每个操作被创造,添加到该程序的计划里。当执行明确地被
execute()
触发时这些操作被真正执行。
4.指定的keys
- 一些转换(join, coGroup, keyBy, groupBy)要求的集合上定义的一个key。其他的转换(Reduce, GroupReduce, Aggregate, Windows)允许数据在被应用前通过一个key被分组。
- 一个DataSet被分组:
DataSet<...> input = // [...]
DataSet<...> reduced = input
.groupBy(/*define key here*/)
.reduceGroup(/*do something*/);一个key在DataStream中被指定:
DataStream<...> input = // [...]
DataStream<...> windowed = input
.keyBy(/*define key here*/)
.window(/*window specification*/);Flink的数据模型不是基于 键值( key-value)对的。keys是虚拟的:他们被定义为实际数据的函数来引导分组操作符。
5.指定转换函数
- 许多转换需要用户自定义函数。
- 实现一个接口:
class MyMapFunction implements MapFunction<String, Integer> {
public Integer map(String value) { return Integer.parseInt(value); }
};
data.map(new MyMapFunction()); - 匿名类:
data.map(new MapFunction<String, Integer> () {
public Integer map(String value) { return Integer.parseInt(value); }
}); - 需要用户定义函数的所有转换都可以将rich函数作为参数。相比:
class MyMapFunction implements MapFunction<String, Integer> {
public Integer map(String value) { return Integer.parseInt(value); }
};可以写成:
class MyMapFunction extends RichMapFunction<String, Integer> {
public Integer map(String value) { return Integer.parseInt(value); }
};像往常一样传递函数到map转换:
data.map(new MyMapFunction());
rich函数也可以被定义为一个匿名类:
data.map (new RichMapFunction<String, Integer>() {
public Integer map(String value) { return Integer.parseInt(value); }
});rich函数除了提供像map一样的用户自定义功能外,还提供四个方法:
open
,close
,getRuntimeContext
, andsetRuntimeContext。这些是有用的对于向函数传递参数,创建并最终确定本地状态,访问广播变量,和用于访问运行时信息,如累加器和计数器,和信息迭代。
6.支持的数据类型
- Java Tuples and Scala Case Classes:java元组和Scala case类 元组是包含固定数量的含有各种类型的字段的复合类型。
DataStream<Tuple2<String, Integer>> wordCounts = env.fromElements(
new Tuple2<String, Integer>("hello", 1),
new Tuple2<String, Integer>("world", 2)); wordCounts.map(new MapFunction<Tuple2<String, Integer>, Integer>() {
@Override
public Integer map(Tuple2<String, Integer> value) throws Exception {
return value.f1;
}
}); wordCounts.keyBy(0); // also valid .keyBy("f0") - java POJOs:Java和Scala类被Flink作为一种特殊的POJO数据类型对待,并且类必须是public的,它必须有一个没有参数的公共构造函数,所有的字段是公共或必须通过getter和setter函数来访问,对于一个被叫做foo的字段,getter和setter函数必须命名为
getFoo()
和setFoo()。
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"); // key by field expression "word" - Primitive Types 基本数据类型 Flink支持java和Scala基本数据类型。
- General class types 一般类类型 Flink支持许多Java和Scala类(API和自定义)。所有不确定为POJO类类型(参见上面的POJO需求)是Flink一般类类型。Flink将这些数据类型视为黑盒,无法访问其内容。
- Value 值类型通过实现org.apache.flinktypes.Value接口的读和写方法为那些操作提供定制代码。当通用串行化是效率无效率的时候使用值类型是合理的。一个例子是一个数据类型实现稀疏向量元素的数组。知道数组大多是零,一个可以用一个特殊的编码输出非零元素,而通用串行化只会写所有的数组元素。 Flink用预定义的值类型,对应于基本数据类型。 (
ByteValue
,ShortValue
,IntValue
,LongValue
,FloatValue
,DoubleValue
,StringValue
,CharValue
,BooleanValue
)。这些值类型作为可变的基本数据类型的变量,其价值可以更改,允许程序员重用对象和减轻垃圾收集器的压力。 - Hadoop Writables
- Special Types
7.Accumulators & Counters
- Accumulators有简单的结构包括添加操作和工作结束后可用的最后累积的结果。
- 最简单的accumulator是counter:你可以用Accumulator.add(V value)方法使他自己增量。工作结束后Flink将合并所有部分结果并将结果发送给客户端。Accumulators在调试或你想很快知道关于你的数据更多的时候是有用的。
- Flink有以下内置的Accumulators,每一个都实现了Accumulator接口:IntCounter,LongCounter, and IDoubleCounter。
- 如何使用accumulators: 首先你应该你想使用accumulator在用户定义的转换函数处必须创建一个accumulator对象(这里是一个计数器)。
private IntCounter numLines = new IntCounter();
第二,你必须注册accumulator对象,通常在rich函数的open()方法。在这里你也可以定义名字。
getRuntimeContext().addAccumulator("num-lines", this.numLines);
您现在可以在运算符函数任何地方使用这个accumulator,包括open()和close()方法。
this.numLines.add(1);
总的结果将被存储在从执行环境的execute()方法返回的JobExecutionResult对象中。
myJobExecutionResult.getAccumulatorResult("num-lines")
每个job中所有的accumulator共享一个命名空间,因此,您可以使用相同的accumulator在你的job的不同运算符函数中。Flink将内部合并(合)并具有相同名称的accumulator。
- 一般的,accumulators的结果只有在这个job结束之后才是可用的。
- Accumulator<V,R>是最灵活的:它定义了一个类型V用于值的增加,和最终结果类型R用于最终结果。
Apache Flink - 基本API概念的更多相关文章
- 【翻译】Flink Table Api & SQL —— 概念与通用API
本文翻译自官网:https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/common.html Flink Tabl ...
- Apache Flink -Streaming(DataStream API)
综述: 在Flink中DataStream程序是在数据流上实现了转换的常规程序. 1.示范程序 import org.apache.flink.api.common.functions.FlatMap ...
- 如何在 Apache Flink 中使用 Python API?
本文根据 Apache Flink 系列直播课程整理而成,由 Apache Flink PMC,阿里巴巴高级技术专家 孙金城 分享.重点为大家介绍 Flink Python API 的现状及未来规划, ...
- Apache Flink 流处理实例
维基百科在 IRC 频道上记录 Wiki 被修改的日志,我们可以通过监听这个 IRC 频道,来实时监控给定时间窗口内的修改事件.Apache Flink 作为流计算引擎,非常适合处理流数据,并且,类似 ...
- flink DataStream API使用及原理
传统的大数据处理方式一般是批处理式的,也就是说,今天所收集的数据,我们明天再把今天收集到的数据算出来,以供大家使用,但是在很多情况下,数据的时效性对于业务的成败是非常关键的. Spark 和 Flin ...
- 【翻译】Flink Table Api & SQL —— Table API
本文翻译自官网:Table API https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/tableApi.ht ...
- Apache Flink 为什么能够成为新一代大数据计算引擎?
众所周知,Apache Flink(以下简称 Flink)最早诞生于欧洲,2014 年由其创始团队捐赠给 Apache 基金会.如同其他诞生之初的项目,它新鲜,它开源,它适应了快速转的世界中更重视的速 ...
- 企业实践 | 如何更好地使用 Apache Flink 解决数据计算问题?
业务数据的指数级扩张,数据处理的速度可不能跟不上业务发展的步伐.基于 Flink 的数据平台构建.运用 Flink 解决业务场景中的具体问题等随着 Flink 被更广泛的应用于广告.金融风控.实时 B ...
- Flink SQL 核心概念剖析与编程案例实战
本次,我们从 0 开始逐步剖析 Flink SQL 的来龙去脉以及核心概念,并附带完整的示例程序,希望对大家有帮助! 本文大纲 一.快速体验 Flink SQL 为了快速搭建环境体验 Flink SQ ...
随机推荐
- centos 随机启动脚本编写
先说下问题背景 目前手上开发的产品是springboot微服务的,我们用jenkins来做的部署,部署脚本如下: 1.build脚本 负责从git服务器拉脚本 2.微服务脚本: #!/bin/shap ...
- 用jq动态给导航菜单添加active
点击后页面跳转到了新的链接,找到所有的li下的a标签,对其链接地址进行判断,如果和当前浏览器的地址一致,就认为是当前应该激活的菜单,添加active类,否则就取消. <ul class=&quo ...
- navicat 控制mysql某个数据库只属于某个用户
1.使用navicat 1)首先使用root用户新建连接 2)新建mysql用户 3)点击权限,选择添加权限,出现MySQL中已存在的数据库列表,选择你要为该新建用户开放的数据库,此处选择“maiba ...
- C# 中 Linq 操作 DataTable
方法一:更简洁 Console.WriteLine(dt.Rows.OfType<DataRow>().First(x => x.Field<string>(" ...
- Image Processing and Analysis_21_Scale Space:Scale-Space for Discrete Signals——1990
此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...
- Windows工作原理
Windows工作原理中心思想 Windows工作原理的中心思想就是“动态链接”概念.Windows自身带有一大套函数,应用程序就是通过调用这些函数来实现它的用户界面和在屏幕上显示文本与图形的.这些函 ...
- Linux高级网络设置——将多个网卡设置成一个网卡
Linux下可以设置网卡模式 模式0:负载均衡 模式1:主备模式,不提高网络带宽 模式3:多网卡同时发送相同的数据 准备实验环境: Redhat 6.4 企业版64位,最小化安装. 给虚拟机添加网卡 ...
- 定义一个类:实现功能可以返回随机的10个数字,随机的10个字母, 随机的10个字母和数字的组合;字母和数字的范围可以指定,类似(1~100)(A~z)
#习题2:定义一个类:实现功能可以返回随机的10个数字,随机的10个字母, #随机的10个字母和数字的组合:字母和数字的范围可以指定 class RandomString(): #随机数选择的范围作为 ...
- ndk学习之c++语言基础复习----C++线程与智能指针
线程 线程,有时被称为轻量进程,是程序执行的最小单元. C++11线程: 我们知道平常谈C++线程相关的东东基本都是基于之后要学习的posix相关的,其实在C++11有自己新式创建线程的方法,所以先来 ...
- 三种方法给Vmware虚拟机占用空间清理瘦身
随着VMware虚拟机使用时间的增长,其所占用的空间也越来越大,本文来说说怎么给VMware虚拟机占用的空间进行瘦身. 方法一:VMware自带的清理磁盘这个方法是VMware自带,具有普适性,对快照 ...