• Flink程序是实现分布式集合转换的常规程序。集合最初是从源创建的。通过接收器(slink)返回结果,接收器可以将数据写到某个文件或stdout。Flink可以在各种环境(context)中运行,本地JVM或集群。

1.数据集和数据流

  • Flink用特殊的类DataSet and DataStream来表示程序中的数据。可以认为他们是可以包含重复数据的不可变数据集合。在DataSet中数据是有限的,而在DataStream中数据是无限的。
  • 这些集合不同于java里的集合,他们是不可变的,一旦被创造就不能改动,也不能简单的抽查里面的元素。
  • 最初的集合是通过在Flink程序里添加一个源被创造的,新的集合是使用API方法(如mapfilter)通过转换得到的。

2.剖析一个Flink程序

  • 每个程序包含相同的基本部分:
  1. 获得一个执行环境(execution environment).
  2. 加载/创建初始数据。
  3. 指定转换这些数据。
  4. 指定放置计算结果的位置。
  5. 触发程序执行。
  • 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一样的用户自定义功能外,还提供四个方法:openclosegetRuntimeContext, and setRuntimeContext。这些是有用的对于向函数传递参数,创建并最终确定本地状态,访问广播变量,和用于访问运行时信息,如累加器和计数器,和信息迭代。

6.支持的数据类型

  1. 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")
  2. 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"
  3. Primitive Types   基本数据类型   Flink支持java和Scala基本数据类型。
  4. General class types  一般类类型   Flink支持许多Java和Scala类(API和自定义)。所有不确定为POJO类类型(参见上面的POJO需求)是Flink一般类类型。Flink将这些数据类型视为黑盒,无法访问其内容。
  5. Value    值类型通过实现org.apache.flinktypes.Value接口的读和写方法为那些操作提供定制代码。当通用串行化是效率无效率的时候使用值类型是合理的。一个例子是一个数据类型实现稀疏向量元素的数组。知道数组大多是零,一个可以用一个特殊的编码输出非零元素,而通用串行化只会写所有的数组元素。    Flink用预定义的值类型,对应于基本数据类型。 (ByteValueShortValueIntValueLongValueFloatValueDoubleValueStringValueCharValueBooleanValue)。这些值类型作为可变的基本数据类型的变量,其价值可以更改,允许程序员重用对象和减轻垃圾收集器的压力。
  6. Hadoop Writables
  7. 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概念的更多相关文章

  1. 【翻译】Flink Table Api & SQL —— 概念与通用API

    本文翻译自官网:https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/common.html Flink Tabl ...

  2. Apache Flink -Streaming(DataStream API)

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

  3. 如何在 Apache Flink 中使用 Python API?

    本文根据 Apache Flink 系列直播课程整理而成,由 Apache Flink PMC,阿里巴巴高级技术专家 孙金城 分享.重点为大家介绍 Flink Python API 的现状及未来规划, ...

  4. Apache Flink 流处理实例

    维基百科在 IRC 频道上记录 Wiki 被修改的日志,我们可以通过监听这个 IRC 频道,来实时监控给定时间窗口内的修改事件.Apache Flink 作为流计算引擎,非常适合处理流数据,并且,类似 ...

  5. flink DataStream API使用及原理

    传统的大数据处理方式一般是批处理式的,也就是说,今天所收集的数据,我们明天再把今天收集到的数据算出来,以供大家使用,但是在很多情况下,数据的时效性对于业务的成败是非常关键的. Spark 和 Flin ...

  6. 【翻译】Flink Table Api & SQL —— Table API

    本文翻译自官网:Table API  https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/tableApi.ht ...

  7. Apache Flink 为什么能够成为新一代大数据计算引擎?

    众所周知,Apache Flink(以下简称 Flink)最早诞生于欧洲,2014 年由其创始团队捐赠给 Apache 基金会.如同其他诞生之初的项目,它新鲜,它开源,它适应了快速转的世界中更重视的速 ...

  8. 企业实践 | 如何更好地使用 Apache Flink 解决数据计算问题?

    业务数据的指数级扩张,数据处理的速度可不能跟不上业务发展的步伐.基于 Flink 的数据平台构建.运用 Flink 解决业务场景中的具体问题等随着 Flink 被更广泛的应用于广告.金融风控.实时 B ...

  9. Flink SQL 核心概念剖析与编程案例实战

    本次,我们从 0 开始逐步剖析 Flink SQL 的来龙去脉以及核心概念,并附带完整的示例程序,希望对大家有帮助! 本文大纲 一.快速体验 Flink SQL 为了快速搭建环境体验 Flink SQ ...

随机推荐

  1. ROUTE: route addition failed

    ROUTE: route addition failed 1)报FlushIpNetTable failed on interface错误 应对:以管理员身份运行OpenV-P-N 2)报Warnin ...

  2. MVC方式显示数据(数据库)

    新建实体数据模型 选择ADO.NET实体数据模型,名称改为数据库名 因为使用现有数据库,所以选择来自数据库的EF设计器,只演示所以只选择一个表,空模型可后期增加表 选择从数据库更新模型 新建数据库连接 ...

  3. PowerBulider获取计算机mac地址

    PowerBulider获取计算机mac地址 1.下载GETNET.DLL获取网络资源的API 2.PB的全局函数中的引入需要API,常用API列表如下 //得到计算机名字 function bool ...

  4. [Docker][Hadoop]基于Docker1.12.3 搭建Hadoop 2.7.2 集群以及简单分析

    一 Hadoop简介 Hadoop 2.7.2 Doc refer to http://hadoop.apache.org/docs/r2.7.2/ HDFS (The following is a ...

  5. Auth2.0 例子【转载】

    本文转载自:https://www.cnblogs.com/flashsun/p/7424071.html 1.引言 本篇文章是介绍OAuth2.0中最经典最常用的一种授权模式:授权码模式 非常简单的 ...

  6. Codeforces 567D - One-Dimensional Battle Ships - [树状数组+二分]

    题目链接:https://codeforces.com/problemset/problem/567/D 题意: 在一个 $1 \times n$ 的网格上,初始摆放着 $k$ 只船,每只船的长度均为 ...

  7. 在linux中安装VM tools

    step 1:虚拟机选择安装 Vmware tools ,在DVD中将.tar.gz的文件包拖到桌面中: step 2:打开终端,切换到桌面,cd /home/whoami/桌面 cd /home/u ...

  8. PHP获取不到url传递参数中#&等特殊字符解决方法

    有些符号在URL中是不能直接传递的,无法传入PHP处理,比如#&等符号,通过$_GET是获取不到的,比如一个域名https://localhost/url.php?url=yangyufei+ ...

  9. 如何查看JVM的内存

    学过java的人都知道,jvm是解释运行java的,java能够作为跨平台语言,也是因为jvm的存在,合理的使用jvm内存可以帮助程序很好的运行.那么,怎么查看jvm的内存使用情况呢,下面本文介绍一下 ...

  10. BZOJ 4008 亚瑟王(概率DP 奥妙重重)

    题意 中文题面,就不解释了 分析 显然这道题直接求期望太麻烦,想想转化问题(这转化太神了). 定义f(i,j)f(i,j)f(i,j)表示第iii张卡总共被经过jjj次的概率,有转移方程式 f(i,j ...