一FlinkTime类型

有3类时间,分别是数据本身的产生时间、进入Flink系统的时间和被处理的时间,在Flink系统中的数据可以有三种时间属性:

Event Time 是每条数据在其生产设备上发生的时间。这段时间通常嵌入在记录数据中,然后进入Flink,可以从记录中提取事件的时间戳;Event Time即使在数据发生乱序,延迟或者从备份或持久性日志中重新获取数据的情况下,也能提供正确的结果。这个时间是最有价值的,和挂在任何电脑/操作系统的时钟时间无关。

Processing Time 是指执行相应操作的机器的系统时间。如果流计算系统基于Processing Time来处理,对流处理系统来说是最简单的,所有基于时间的操作(如Time Window)将使用运行相应算子的机器的系统时钟。然而,在分布式和异步环境中,Processing Time并不能保证确定性,它容易受到Event到达系统的速度(例如来自消息队列)以及数据在Flink系统内部处理的先后顺序的影响,所以Processing Time不能准确地反应数据发生的时间序列情况。

Ingestion Time是事件进入Flink的时间。 在Source算子处产生,也就是在Source处获取到这个数据的时间,Ingestion Time在概念上位于Event Time和Processing Time之间。在Source处获取数据的时间,不受Flink分布式系统内部处理Event的先后顺序和数据传输的影响,相对稳定一些,但是Ingestion Time和Processing Time一样,不能准确地反应数据发生的时间序列情况。

二 Watermark机制

上面提到Event Time是最能反映数据时间属性的,但是Event Time可能会发生延迟或乱序,Flink系统本身只能逐个处理数据,如何应对Event Time可能会发生延迟或乱序情况呢?

比如需要统计从10:00到11:00发生某个事件的次数,也就是对Event Time是在10:00和11:00之间的数据统计个数。Event Time可能会发生延迟或乱序的情况下,Flink系统怎么判断10:00到11:00发生的事件数据都已到达,可以给出统计结果了呢?长时间地等待会推迟结果输出时间,而且占用更多系统资源。

Watermark是一个对Event Time的标识,内容方面Watermark是个时间戳,一个带有时间戳X的Watermark到达,相当于告诉Flink系统,任何Event Time小于X的数据都已到达。比如上面的例子,如果Flink收到一个时间戳是11:01的Watermark,它就可以把之前统计的Event Time在[10:00,11:01)之间的事件个数输出,清空相关被占用的资源。这里需要注意窗口的长度问题,只有窗口采集完成的数据,才会统计。

三 Watermark生成

Periodic - 一定时间间隔或者达到一定的记录条数会产生一个watermark。

Punctuated – 基于event time通过一定的逻辑产生watermark,比如收到一个数据就产生一个WaterMark,时间是event time - 5秒。

这两种产生方式,都有机制来保证产生的watermark是单调递增的。

即使有了watermark,如果现实中,数据没有满足watermark所保证的条件怎么办?比如Flink处理了11:01的watermark,但是之后遇到了event time是10:00~11:00之间的数据怎么办?首先如果这种事情出现的概率非常小,不影响所要求的准确度,可以直接把数据丢弃;如果这种事情出现的概率比较大,就要调整产生water mark的机制了。

除了把违反watermark机制的数据丢弃,也有不丢弃的处理方法,比如通过一些机制来更新之前统计的结果,这种方式会有一定的性能开销。

四代码示例

package org.tonny.flink.bi.job.water;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.flink.api.common.functions.FilterFunction;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.tuple.Tuple3;
import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.AssignerWithPeriodicWatermarks;
import org.apache.flink.streaming.api.watermark.Watermark;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.StringUtils;

/**
 *
在指定的linux机器上开启nc -l 9900
 *
输入的数据格式:
 
* hello1 1567059808519
 * hello2 1567059809519
 * hello3 1567059810519
 */
public
class
WaterMarkJob {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env
= StreamExecutionEnvironment.getExecutionEnvironment();
       
env.getConfig().disableSysoutLogging();//关闭日志打印
       
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); 
//设置时间分配器

env.setParallelism(1); 
//设置并行度
       
env.getConfig().setAutoWatermarkInterval(3000);//9秒发出一个watermark

DataStream<String> text =
env.socketTextStream("localhost", 9900);

DataStream<Tuple3<String,
Long, Integer>> counts = text
                // 设置过滤
               
.filter(new FilterClass())
                // 设置分词
               
.map(new LineSplitter())
                //设置watermark方法
               
.assignTimestampsAndWatermarks(new PeriodicWatermarks())
                .keyBy(0)
                //设置滚动窗口大小
               
.timeWindow(Time.seconds(60))
                .sum(2);

counts.print();
        env.execute("Window WordCount");

}

public static class PeriodicWatermarks implements AssignerWithPeriodicWatermarks<Tuple3<String,
Long, Integer>> {
        private long currentMaxTimestamp = 0L;

private final long maxOutOfOrderness = 10000L;  
//这个控制失序已经延迟的度量,时间戳10秒以前的数据

//获取EventTime
        
@Override
        public long extractTimestamp(Tuple3<String, Long,
Integer> element, long previousElementTimestamp) {
            if (element == null) {
                return currentMaxTimestamp;
            }

long timestamp = element.f1;
            currentMaxTimestamp = Math.max(timestamp, currentMaxTimestamp);
            System.out.println("get timestamp is " + timestamp + " currentMaxTimestamp " + currentMaxTimestamp);
            return timestamp;
        }

//获取Watermark
       
@Override
        public Watermark getCurrentWatermark() {
            System.out.println("wall clock is " + System.currentTimeMillis() + " new watermark " + (currentMaxTimestamp - maxOutOfOrderness));
            return new Watermark(currentMaxTimestamp - maxOutOfOrderness);
        }
    }

//构造出element以及它的event time.然后把次数赋值为1
   
public static final class LineSplitter implements MapFunction<String, Tuple3<String,
Long, Integer>> {
        @Override
        public Tuple3<String, Long, Integer> map(String
value) throws Exception {
            if (org.apache.commons.lang3.StringUtils.isBlank(value))
{
                return null;
            }

String[] tokens =
value.toLowerCase().split("\\W+");
            if (ArrayUtils.isEmpty(tokens) ||
ArrayUtils.getLength(tokens) < 2) {
                return null;
            }
            long eventtime = 0L;
            try {
                eventtime = Long.parseLong(tokens[1]);
            } catch (NumberFormatException e) {
                return null;
            }
            return new Tuple3<String, Long,
Integer>(tokens[0],
eventtime, 1);
        }
    }

/**
     *
过滤掉为nullwhitespace的字符串
    
*/
   
public static final class FilterClass implements FilterFunction<String> {
        @Override
        public boolean filter(String value) throws Exception {
            if (StringUtils.isNullOrWhitespaceOnly(value))
{
                return false;
            } else {
                return true;
            }
        }

}
}

Flink的时间类型和watermark机制的更多相关文章

  1. 数据库时间类型和 util 包下时间类型转换

    Java 中的类型 1. java.sql 包下给出三个数据库相关的日期时间类型,分别是 java.sql.Date, 表示日期,只有年月日,没有时分秒. java.sql.Time, 表示时间, 只 ...

  2. [白话解析] Flink的Watermark机制

    [白话解析] Flink的Watermark机制 0x00 摘要 对于Flink来说,Watermark是个很难绕过去的概念.本文将从整体的思路上来说,运用感性直觉的思考来帮大家梳理Watermark ...

  3. flink的watermark机制你学会了吗?

    大家好,今天我们来聊一聊flink的Watermark机制. 这也是flink系列的的第一篇文章,如果对flink.大数据感兴趣的小伙伴,记得点个关注呀. 背景 ​ flink作为先进的流水计算引擎, ...

  4. Flink中的window、watermark和ProcessFunction

    一.Flink中的window 1,window简述  window 是一种切割无限数据为有限块进行处理的手段.Window 是无限数据流处理的核心,Window 将一个无限的 stream 拆分成有 ...

  5. DATETIME类型和BIGINT 类型互相转换

    项目中使用BIGINT来存放时间,以下代码用来转换时间类型和BIGINT类型 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ========= ...

  6. Timestame类型和String 类型的转化

    Timestame类型和String 类型的转化 String转化为Timestamp: SimpleDateFormat df = new SimpleDateFormat("yyyy-M ...

  7. 数据类型和typeof操作符

    虽然学习js有一段时间了,但是对js的基础语法却是有些生疏.最近在看jquery源码,决定随带总结一些基础的语法知识.今天总结一下数据类型和typeof,这在写js的时候,是不得不知道的知识. 数据类 ...

  8. Sql Server中的数据类型和Mysql中的数据类型的对应关系(转)

    Sql Server中的数据类型和Mysql中的数据类型的对应关系(转):https://blog.csdn.net/lilong329329/article/details/78899477 一.S ...

  9. 函数----基础,参数传递,返回类型和return语句

    一.函数基础1.形参和实参 实参是形参的初始值.第一个实参初始化第一个形参,第二个实参初始化第二个形参,以此类推.尽管实参与形参存在对应关系,但是并没有规定实参的求值顺序.编译器能以任意可行的顺序对实 ...

随机推荐

  1. 后盾网lavarel视频项目---Vue项目使用vue-awesome-swiper轮播插件

    后盾网lavarel视频项目---Vue项目使用vue-awesome-swiper轮播插件 一.总结 一句话总结: vue中的插件的使用和js插件的使用一样的简单,只是vue插件的引入过程有些不同 ...

  2. Bootstrap4项目开发实战视频教程

    一.企业网站项目 课件 0.课程简介 1.顶部区域的制作 2.导航区域的制作 3.轮播区域的制作 4.产品区域的制作 5.最新资讯区域的制作 6.底部区域的制作 二.化妆品网站项目 1.项目初始化_导 ...

  3. Python接口测试-模块引用与映射

    PyCharm中发现模块引用老是有各种问题 可以用映射来解决,例如需要调用登录模块里面的东西的时,可以这样处理: 登录模块:1-login.py import this import requests ...

  4. 前端知识点回顾之重点篇——ES6的Promise对象

    Promise Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异 ...

  5. docker进入容器的四种方法

    在使用Docker创建了容器之后,大家比较关心的就是如何进入该容器了,其实进入Docker容器有好几多种方式,这里我们就讲一下常用的几种进入Docker容器的方法. 进入Docker容器比较常见的几种 ...

  6. 最新create-react-native-app搭建rn教程

    一.前置条件: 1.nodeJS环境 2.npm 3.yarn 二.安装及项目初始化 1.安装脚手架 npm install -g create-react-native-app 2.用脚手架初始化创 ...

  7. 九十五:CMS系统之cms后台模板渲染

    定义一个宏,用于渲染static文件的时候,只需要传文件名就可以,上下两个“-”是解决渲染的时候源代码换行的情况 {% macro static(filename) -%} {{ url_for('s ...

  8. Hadoop HDFS命令学习笔记

    cat Usage: hadoop fs -cat [-ignoreCrc] URI [URI ...] Copies source paths to stdout. Options The -ign ...

  9. 实时更新Excel文档外部数据源的数据

    实时更新Excel文档外部数据源的数据 单元格区域.Excel 表.数据透视表或数据透视图均可以连接到外部数据源(数据源:用于连接数据库的一组存储的"源"信息.数据源包含数据库服务 ...

  10. Go项目实战:打造高并发日志采集系统(六)

    前情回顾 前文我们完成了日志采集系统的日志文件监控,配置文件热更新,协程异常检测和保活机制. 本节目标 本节加入kafka消息队列,kafka前文也介绍过了,可以对消息进行排队,解耦合和流量控制的作用 ...