Flink__Flink1.10.0What is Apache Flink?__Applications

Apache Flink是一个可以在有限流数据流和无限流基础上进行有状态计算的大数据处理框架。Flink从下到上提供了不同层级的API抽象,并为常见的用例提供了专用的开发库。

构建流处理应用程序 (Building Blocks for Streaming Applications)

流处理框架如何控制 Stream, State,Time等因素,决定了框架能构建和执行什么类型的应用(The types of applications that can be built with and executed by a stream processing framework are defined by how well the framework controls streams, state, and time)。下面我们将逐一描述流处理应用的基础组件,并阐述Flink处理他们的方法。

Streams (流)

很明显,(数据) 流是流处理应用一个基本概念。然而一个流可以有不同的特性,这些特性将影响流能够及应该如何处理数据。Flink是一个具有具有多种处理功能的强大数据处理框架,它可以处理多种类型的流。

  • 有限流 和 无限流: 流可以是无限的 或 有限的。即,有固定数据大小或固定数据条数的数据集。Flink 具有处理无限流的强大特性,同时也有专用的算子 (Operators) 高效处理有限流(数据集)。
  • 实时流 和 有顺序流: 所有的数据都是以流的形式产生的。通常情况下处理数据有2种方式。当流数据产生时就立即处理,或者 将产生的流数据存储起来,即先储存到文件系统或存储对象中,之后再处理。Flink可以处理存储数据流或实时数据流。

Status (状态)

每一个非普通(non-trivial)流处理程序都是有状态的,也就是说只有那些只针对单个事件进行单独处理的应用流式应用才不需要关心应用状态。换句话说,任何一个具体基本业务处理逻辑的应用程序都需要记录 事件状态 或中间结果,以便在今后业务需要时访问这些状态。

image.png

在Flink应用中应用状态是一等公民。可以从Flink在上下文环境中提供的对状态处理的所有特性就能证明这一点。

  • 多种原始基础状态: Flink为不同基础数据结构提供了不同的状态类型: 如 原子值,List,Map等数据结构。开发人员可以根据不同函数对不同状态的访问处理形式来选择最高效,最适合的状态类型。
  • 插件式状态后端:Flink应用的状态被插件式的状态后端管理并定期执行Checkpoint操作。Flink具有不同类型的状态后端,这些状态后端把应用的状态保存在内存(Memory) 或 RockDB(一种高效的嵌入式磁盘存储)中。Flink也支持插件式的自定义的状态后端。
  • 精确一次的状态一致性:Flink的Checkpoint机制和故障恢复算法保证了应用失败后状态恢复的数据一致性。因此,Flink故障处理是透明的,不会影响应用程序的正确性。
  • 非常大的状态: 由于Flink的异步和增量的Checkpoint算法,使Flink能够维持TB级的应用状态。
  • 应用扩展: Flink通过将状态分配给不同规模Worker来支持有状态应用的水平扩展。

Time

时间是流处理应用的另一个重要组成部分。多数的事件流都有内部的时间语义,因为流的每个事件都是在特定的时间点生成的。此外,许多通用的流计算都是基于时间的,例如窗口聚合,sessionization(会话计算), 模式匹配,以及基于时间的Join。流式计算的另一个重要方面是应用如何测量时间,即区分 事件时间 和 处理时间。

Flink提供了一组丰富的与时间有关的特性。

  • 事件时间模式:使用事件时间定义的流处理应用基于事件内的timestamp(时间戳) 计算程序结果。因此不管是处理流式数据还是已经保存记录下来的数据,基于事件时间的数据处理保证了结果的正确性和一致性。
  • 水印支持: 在"事件时间"应用中Flink引入水印(Watermark)利用水印来衡量事件进展。水印是一种权衡结果延迟和完事性的一种灵活机制。
  • 迟到数据处理: 在以"事件时间"为基准流处理中使用水印时,可能发生所有相关事件到达之前计算已经完成的情况。这种事件叫迟到数据。Flink提供了多种选项来处理迟到数据,例如:通过 侧输出 重新路由这些数据并更新之前的处理结果。
  • 处理时间模式:除了事件模式外,Flink也支持处理时间语义,它是根据具体处理机器的本地时间来触发计算的。处理时间模式适用于一些对数据延迟有严格要求但允许损失一定数据精度的应用。

APIs 分层 (Layered APIs)

Flink提供了3层APIs. 每层API 在表达性,简洁性及不同使用场景之间提供了不同的权衡。


image.png

我们简要介绍一下每层API,讨论他们的应用,并展示一段样例代码。

The ProcessFunctions

ProcessFunctions 是Flink提供的最具有表达力的函数接口。Flink的ProcessFunctions函数接口用来处理1或2个流中独立的事件,或处理聚合窗口中的事件。ProcessFuntions函数提供了对时间和状态的细粒度控制。一个ProcessFunctions可以随意修改它自身的状态,注册时间定时器,时间定时器在将来的某个时刻触发函数回调。因此,许多基于事件状态驱动的应用,ProcessFunctions根据要求实现 基于单个事件的、复杂的业务处理。
下面展示了KeyedStream流中使用KeyedProcessFunction函数匹配符合START和END事件的例子。当START事件到达函数时,函数将事件的timestamp(时间戳)记录在state(状态)中,并启动一个4小时后触发的定时器。如果一个END事件在定时器触发之前到达,函数计算START事件和END事件之间的时间差值,清除状态,并返回时间差值。否则触发定时器并清除状态值。

/**
 * Matches keyed START and END events and computes the difference between 
 * both elements' timestamps. The first String field is the key attribute, 
 * the second String attribute marks START and END events.
 */
public static class StartEndDuration
    extends KeyedProcessFunction<String, Tuple2<String, String>, Tuple2<String, Long>> {

  private ValueState<Long> startTime;

  @Override
  public void open(Configuration conf) {
    // obtain state handle
    startTime = getRuntimeContext()
      .getState(new ValueStateDescriptor<Long>("startTime", Long.class));
  }

  /** Called for each processed event. */
  @Override
  public void processElement(
      Tuple2<String, String> in,
      Context ctx,
      Collector<Tuple2<String, Long>> out) throws Exception {

    switch (in.f1) {
      case "START":
        // set the start time if we receive a start event.
        startTime.update(ctx.timestamp());
        // register a timer in four hours from the start event.
        ctx.timerService()
          .registerEventTimeTimer(ctx.timestamp() + 4 * 60 * 60 * 1000);
        break;
      case "END":
        // emit the duration between start and end event
        Long sTime = startTime.value();
        if (sTime != null) {
          out.collect(Tuple2.of(in.f0, ctx.timestamp() - sTime));
          // clear the state
          startTime.clear();
        }
      default:
        // do nothing
    }
  }

  /** Called when a timer fires. */
  @Override
  public void onTimer(
      long timestamp,
      OnTimerContext ctx,
      Collector<Tuple2<String, Long>> out) {

    // Timeout interval exceeded. Cleaning up the state.
    startTime.clear();
  }
}

示例说明了KeyedProcessFunction的表达力,但高亮部分也说明他是一个冗长的接口。

The DataStream API

DataStream API 为许多长见的流处理操作提供语义支持,例如 窗口操作,事件转换,通过查询外部存储来丰富事件等。DataStream API支持Java和Scala,同时DataStream是基于函数的,例如 map(), reduce(),aggregate()。可以实现接口来定义函数,也可以是Java或Scala支持的lambda函数。
下面例子展示了如何定义一个clickstream,并统计每个会话的点击次数。

// a stream of website clicks
DataStream<Click> clicks = ...

DataStream<Tuple2<String, Long>> result = clicks
  // project clicks to userId and add a 1 for counting
  .map(
    // define function by implementing the MapFunction interface.
    new MapFunction<Click, Tuple2<String, Long>>() {
      @Override
      public Tuple2<String, Long> map(Click click) {
        return Tuple2.of(click.userId, 1L);
      }
    })
  // key by userId (field 0)
  .keyBy(0)
  // define session window with 30 minute gap
  .window(EventTimeSessionWindows.withGap(Time.minutes(30L)))
  // count clicks per session. Define function as lambda function.
  .reduce((a, b) -> Tuple2.of(a.f0, a.f1 + b.f1));

SQL & Table API

Flink提供了两种关系型API,Table API 和 SQL。两个API为批处理和流处理提供了统一的API,也就是说,查询在无限的数据流,或有限的记录流上以相同的语义执行,并产生相同的结果。Table API 和 SQL 利用 Apache Calcite来解析,验证,执行查询优化。Table API 和 SQL 可以与 DataStream 和 DataSet API无缝集成,并支持用户自下定义 标量函数,聚合函数,和 Table函数。

Flink关系型API的目的是要简化数据分析,数据管道,ETL应用的定义。
下面的示例展示了使用SQL查询一个基于Session窗口的点击流,并统计每个Session的点击次数。本例和DataStream API示例中的例子相同。

SELECT userId, COUNT(*)
FROM clicks
GROUP BY SESSION(clicktime, INTERVAL '30' MINUTE), userId

Libraries

Flink为常用的数据处理用例提供了若干类库。 这些类库通常嵌入在一个API中,而不是完全独立的。这使得类库API可以从Flink提供其他特征API中获益,并与其他类库集成。

  • 复杂事件处理(Complex Event Processing (CEP)): 模式检测是事件流处理中一个常见用例。Flink的CEP库提供了一个API来指定事件模式(考虑正则表达式或状态机制)。Flink CEP 库与 Flink DataStream API集成,这样可以在DataStream上执行模式计算。CEP 库的应用包括网络入侵检测,业务处理监控 和 欺诈检测。

  • DataSet API: 略。

  • Gelly: 略。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342