Flink-时间窗口

        在流数据处理应用中,一个很重要、也很常见的操作就是窗口计算。所谓的“窗口”,一 般就是划定的一段时间范围,也就是“时间窗”;对在这范围内的数据进行处理,就是所谓的 窗口计算。所以窗口和时间往往是分不开的。

时间语义 

1、处理时间(Processing Time) 

        处理时间的概念非常简单,就是指执行处理操作的机器的系统时间。 在这种时间语义下处理窗口非常简单粗暴,不需要各个节点之间进行协调同步,也不需要 考虑数据在流中的位置,简单来说就是“我的地盘听我的”。所以处理时间是最简单的时间语义。

2、事件时间(Event Time)

        事件时间,是指每个事件在对应的设备上发生的时间,也就是数据生成的时间。 数据一旦产生,这个时间自然就确定了,所以它可以作为一个属性嵌入到数据中。这其实 就是这条数据记录的“时间戳”(Timestamp)。

水位线

        在事件时间语义下,我们不依赖系统时间,而是基于数据自带的时间戳去定义了一个时钟, 用来表示当前时间的进展。于是每个并行子任务都会有一个自己的逻辑时钟,它的前进是靠数 据的时间戳来驱动的。

        我们可以把时钟也以数据的形式传递出去,告诉下游任务当前时间的进展;而且这个时钟 的传递不会因为窗口聚合之类的运算而停滞。一种简单的想法是,在数据流中加入一个时钟标 记,记录当前的事件时间;这个标记可以直接广播到下游,当下游任务收到这个标记,就可以 更新自己的时钟了。由于类似于水流中用来做标志的记号,在 Flink 中,这种用来衡量事件时 间(Event Time)进展的标记,就被称作“水位线”(Watermark)。

        具体实现上,水位线可以看作一条特殊的数据记录,它是插入到数据流中的一个标记点, 主要内容就是一个时间戳,用来指示当前的事件时间。而它插入流中的位置,就应该是在某个 数据到来之后;这样就可以从这个数据中提取时间戳,作为当前水位线的时间戳了。

  1. 水位线是插入到数据流中的一个标记,可以认为是一个特殊的数据
  2. 水位线主要的内容是一个时间戳,用来表示当前事件时间的进展
  3. 水位线是基于数据的时间戳生成的
  4. 水位线的时间戳必须单调递增,以确保任务的事件时间时钟一直向前推进
  5. 水位线可以通过设置延迟,来保证正确处理乱序数据
  6. 一个水位线 Watermark(t),表示在当前流中事件时间已经达到了时间戳 t, 这代表 t 之 前的所有数据都到齐了,之后流中不会出现时间戳 t’ ≤ t 的数据 

水位线生成策略

 在Flink 的 DataStream API 中 , 有 一 个 单 独 用 于 生 成 水 位 线 的 方 法:                        assignTimestampsAndWatermarks(),它主要用来为流中的数据分配时间戳,并生成水位线来指 示事件时间。

        有序流的水位线生成策略

object f1 {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    //设置全局并行度
    env.setParallelism(1)
    //获取当前的运行配置
      //setAutoWatermarkInterval(时间戳)自动生成水位线的时间间隔
    env.getConfig.setAutoWatermarkInterval(500L)
    //数据
    val stream = env.fromElements(
      Event(4, "aa", 1000L),
      Event(5, "bb", 2000L),
      Event(6, "cc", 2500L),
      Event(7, "dd", 4000L)
    )
    //设置水位线
      //1、有序流的水位线生成策略
    stream.assignTimestampsAndWatermarks(WatermarkStrategy.forMonotonousTimestamps[Event]()
    .withTimestampAssigner(
      new SerializableTimestampAssigner[Event] {
        override def extractTimestamp(t: Event, l: Long): Long = t.time //指定字段中的time为时间戳
      }
    ))

    //执行
    env.execute()
  }
  case class Event(id: Int, name: String, time: Long )
}

相关推荐

  1. Flink-时间窗口

    2023-12-06 15:52:02       71 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-06 15:52:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-06 15:52:02       106 阅读
  3. 在Django里面运行非项目文件

    2023-12-06 15:52:02       87 阅读
  4. Python语言-面向对象

    2023-12-06 15:52:02       96 阅读

热门阅读

  1. AGI = 大模型 + 知识图谱 + 强化学习

    2023-12-06 15:52:02       66 阅读
  2. 数据库事务

    2023-12-06 15:52:02       59 阅读
  3. Angular中的单向和双向数据绑定

    2023-12-06 15:52:02       53 阅读
  4. php时间和centos时间不一致

    2023-12-06 15:52:02       51 阅读
  5. 苍穹外卖--在redis中缓存菜品数据,加快查询速度

    2023-12-06 15:52:02       51 阅读
  6. 1091 Acute Stroke (三维搜索)

    2023-12-06 15:52:02       62 阅读
  7. HTML h1和h2的三点区别

    2023-12-06 15:52:02       57 阅读
  8. 如何在centos服务器上安装docker保姆教程

    2023-12-06 15:52:02       51 阅读
  9. 代码随想录二刷 |字符串 |右旋转字符串

    2023-12-06 15:52:02       62 阅读
  10. 深入理解Python包管理工具pip的基本命令和使用

    2023-12-06 15:52:02       43 阅读
  11. Linux ubuntu20.04 安装使用 Intel sgx

    2023-12-06 15:52:02       49 阅读