Flink 时间语义、水印、窗口

一、前言

本文主要关于Flink1.12.0中关于时间语义,watermark,以及windows的一些使用和理解。

二、背景

准备重新梳理下flink的相关应用,以及flink源码解读,更深入的了解和学习下flink的使用。开始部分文章会写flink应用层的使用,以及一些代码例子。后面会针对源码进行剖析~~

三、时间语义、watermark

在flink中时间语义常用有以下两种
1、eventtime 事件时间,可以理解这条记录产生的时间 ,一般都是在记录的某个字段里。
2、processtime 处理时间,这是flinktask处理时的系统时间,可以理解为数据到task后开始处理的时间 。
定义时间语义有啥用呢?
我理解是为了窗口计算。因为窗口需要通过时间来划分,这个时间就需要你上面自己定义。
那么watermark又是干啥的?
watermark是为了允许乱序和迟来的数据。举个例子,现在有个场景需要每十分钟统计过去十分钟的订单数据,假设这个订单数据在kakfa中时乱序的,某个分区的订单时间顺序可能是 10:01 ,10:03,10:08,10:11,10:09,10:13
在上面的顺序中如果按照正常时间执行的话窗口是10:00-10:10这个区间,所以在10:11这条数据来了后,这个窗口就相当于被触发了,那么后面10:09这条数据就不会再被计算到。。这个时候如果想让这条记录被处理到,可以加入水印-2min,当10:11这条记录来的时候他的watermark是10:11-2min=10:09 那么这个窗口还是未被触发的,后面的10:09就不会被遗漏。当10:13这条记录来的时候才会被触发~

下面来看看watermark和eventtime生成的代码:

测试类 关于eventtime的例子:接入订单流数据,设置eventtime字段,并设置水印延迟2s,然后按5s的窗口滚动计算窗口内的订单金额。~

package com.realtime.flink.test

import java.time.Duration

import com.realtime.flink.dto
import com.realtime.flink.dto.OrderDto
import com.realtime.flink.source.OrderSource
import org.apache.flink.api.common.eventtime.{
   SerializableTimestampAssigner, WatermarkStrategy}
import org.apache.flink.api.common.functions.{
   AggregateFunction, RichFlatMapFunction}
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.assigners.{
   TumblingEventTimeWindows, TumblingProcessingTimeWindows}
import org.apache.flink.streaming.api.windowing.time.Time
object EventTimeTest {
   
  def main(args: Array[String]): Unit = {
   
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)
    val conf = env.getConfig
    conf.setAutoWatermarkInterval(1000)
    val strategy = WatermarkStrategy.forBoundedOutOfOrderness(Duration.ofSeconds(2)).withTimestampAssigner(new SerializableTimestampAssigner[OrderDto] {
   
      override def extractTimestamp(element: OrderDto, recordTimestamp: Long): Long = {
   
        element.getOrderTime
      }
    });
    env.addSource(new OrderSource)
      .assignTimestampsAndWatermarks(strategy)
      .windowAll(TumblingEventTimeWindows.of(Time.seconds(5)))
      .aggregate (new AggregateFunction[OrderDto,(String,Double),(String,Double)] {
   
        override def createAccumulator(): (String, Double) = {
   
          ("",0L)
        }

        override def add(in: OrderDto, acc: (String, Double)): (String, Double) = {
   
          ("",in.getOrderPrice+acc._2)
        }

        override def getResult(acc: (String, Double)): (String, Double) = {
   
          acc
        }

        override def merge(acc: (String, D
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值