Apache Flink基本编程模型

2020-04-14 14:44:16 浏览数 (1)

前一篇文章中<一文了解Flink数据-有界数据与无界数据>大致讲解了Apache Flink数据的形态问题。Apache Flink实现分布式集合数据集转换、抽取、分组、统计等。根据数据源的类型,即为有界数据与无界数据,提供了DataSet与DataStream的基础API。

DataSet与DataStream

根据数据源的类型,即为有界数据与无界数据。Apache Flink提供可以编写流处理与批处理的程序。其中DataSet API用于批处理,DataStream API用于流式处理。对于DataSet来说可以认为其中存储的是可重复有界的数据集合。而DataStream中存储的可以认为是重复的无界的数据集合。

Flink提供了不同级别的抽象来实现批处理或流处理任务的开发。

Flink的基本构建就是数据流与转换,(Flink 中DataSet API中使用的也是内部流)。从整体概念上来讲,流是持续的不会产生中断的数据记录流。而转换则是讲一个或多个流的进行转换、计算、聚合等产生一个或多个流。

程序在执行时会映射出一个或者多个数据流,每个数据流都以一个或者多个源为开头,例如Kakfa、File等或者是通过与计算得来。数据流之间类似于一个有向无环图DAG。

通过两个例子来看DataSet和DataStream。

  • 批处理
代码语言:javascript复制
val env = ExecutionEnvironment.getExecutionEnvironment
    // 创建DataSource
    val text = env.fromElements(
      "Best Data Processing Engine")
    //flatMap : 把字符串转换为小写,并且按照空白分割为一个个的单词.
    //filter: 过滤非空结果
    //map: 把切割的单词转换为 单词,1
    //groupBy:按照下标位0进行分组
    //sum: 计算 下标位1的结果
    val counts = text.flatMap { _.toLowerCase.split("\W ")
      .filter { _.nonEmpty } }
      .map { (_, 1) }
      .groupBy(0)
      .sum(1)
    //打印结果到控制台
    counts.print()
  • 流式处理
代码语言:javascript复制
val env = StreamExecutionEnvironment.getExecutionEnvironment
    val text = env.socketTextStream("localhost",9999)
    //flatMap : 把字符串转换为小写,并且按照空白分割为一个个的单词.
    //filter: 过滤非空结果
    //map: 把切割的单词转换为 单词,1
    //timeWindow: 按照时间,每5s获取进行一次计算
    //sum: 计算 下标位1的结果
    val counts = text.flatMap { _.toLowerCase.split("\W ")
      .filter { _.nonEmpty } }
      .map { (_, 1) }
      .keyBy(0)
      .timeWindow(Time.seconds(5))
      .sum(1)

    //打印结果到控制台
    counts.print()

从上面看,流式处理与批处理的代码实现基本上是一样的,流式处理的数据在通过 nc -lk 9999开启一个socket。Flink连接socket之后就可以进行执行。数据相对与批处理来说是无界的持续数据集。而代码上增加了一个Window。

Windows 窗口

窗口是批处理上不存在的一个过程。流处理与批处理的工作方式不同,例如流处理无法聚合计算元素总数,因为流数据通常都是无界的。所以流上的聚合是由窗口来界定的。(5s,100条)。

Apache Flink中窗口有翻滚窗口,滑动窗口与会话窗口。基于对数据集的切割能够实现基于时间的窗口(TimeWindow)、基于数据驱动的窗口(CountWindow)等。

时间(Event Time,Processing Time,Ingestion Time)

既然存在时间窗口,那么就会对时间做一个基本的定义。一般来讲,时间基本上存在与事件处理的当前时间。也就是处理引擎当前的时间。 Apache Flink对于提供了不同的时间概念:

  • 事件时间(创建时间的时间):类似于我们使用log输出日志的时候所打印的时间。
  • 摄取时间:是指事件源输入到Flink的时间。
  • 处理时间:基于时间的操作,每次操作的时间。

常规情况下对时间进行区分可以理解为

  1. log4j输出一条日志的头带有的时间为 事件时间
  2. 采集程序把数据写入到kafka,Apache Flink实时读取Kafka中的数据,读取到该条数据的时间为摄取时间。
  3. ApacheFlink进行翻滚窗口处理,翻滚时间为5分钟,那么处理到该条数据的时间则为处理时间。

有状态的计算

虽然数据流是无界的数据流,持续产生。但是Apache Flink会记录基于窗口的多个事件的结果。批处理时不需要把数据的当前状态进行存储。而流式计算需要持久的执行,基本上都是以月为单位的执行。那么就需要保存把计算过程持久的存储起来,下次计算的结果直接进行累加。

容错

Apache Flink提供了容错的机制,基于状态与检查点进行执行。该机制确保了当出现故障时系统可以退回到检查点。Apache Flink从容错可处理上可以实现(at least once, exactly once)

0 人点赞