flink处理延迟

flink主要是处理实时数据的,在处理实时数据的过程中,难免会遇到乱序的存在。以事件时间举例,先发生的事件后到处理算子。flink针对乱序数据的处理主要有三种方式:

  • 拨慢水位线的生成,这种情况会在声明的窗口时间中,类似延迟窗口时间的大小,实际是把水位线的生成减小了1秒,导致窗口延迟关闭。下面的例子声明创建了一个滚动事件时间窗口,有效期是5秒,但是在生成水位线的时候,会拨慢1秒,如果是1000毫秒开始,实际计算触发的时间是6000毫秒时触发,窗口有效期是[0,4999)
.assignTimestampsAndWatermarks(WatermarkStrategy.
<Tuple3<String, String, Long>>forBoundedOutOfOrderness(Duration.ofSeconds(1))
.withTimestampAssigner(new SerializableTimestampAssigner<Tuple3<String, String, Long>>() {
@Override
public long extractTimestamp(Tuple3<String, String, Long> element, long recordTimestamp) {
return element.f2;
}
})
).keyBy(data -> data.f0)
.window(TumblingEventTimeWindows.of(Time.seconds(5))) Bob,成都,1000
Bob,成都,4000
Bob,成都,5000
Bob,成都,6000
窗口 0 - 5000 中共有 2 个元素,窗口关闭时,当前水位线4999
  • allowedLateness延长窗口时间

    上面的水位线到达临界点时,触发计算,触发计算的同时,关闭窗口,再迟到的数据就不再处理了。allowedLateness的原理就是延长窗口的关闭时间,水位线到点了,触发计算,但是窗口暂时不会关闭在allowedLateness周期内,再迟到的数据仍然允许再次处理
ds.map(new MapFunction<String, Tuple3<String,String,Long>>() {
@Override
public Tuple3<String, String, Long> map(String value) throws Exception {
String[] split = value.split(","); System.out.println(value);
return Tuple3.of(split[0],split[1],Long.valueOf(split[2]));
}
}).assignTimestampsAndWatermarks(WatermarkStrategy.
<Tuple3<String, String, Long>>forBoundedOutOfOrderness(Duration.ofSeconds(1))
.withTimestampAssigner(new SerializableTimestampAssigner<Tuple3<String, String, Long>>() {
@Override
public long extractTimestamp(Tuple3<String, String, Long> element, long recordTimestamp) {
return element.f2;
}
})
).keyBy(data -> data.f0)
.window(TumblingEventTimeWindows.of(Time.seconds(5)))
.allowedLateness(Time.minutes(1)) Bob,成都,1000
Bob,成都,3000
Bob,成都,5000
Bob,成都,6000
窗口 0 - 5000 中共有 2 个元素,窗口关闭时,当前水位线4999
Bob,成都,16000
窗口 5000 - 10000 中共有 2 个元素,窗口关闭时,当前水位线14999
Bob,成都,4000
窗口 0 - 5000 中共有 3 个元素,窗口关闭时,当前水位线14999
  • sideOutputLateData侧输出流

    上面的两种方式,都是通过延迟水位线或者延长窗口的方式来处理的,实际处理过程中都会占据资源,不可能一直延迟水位线或者让窗口一直存在,在允许范围内的数据处理完毕之后,还得有一种兜底方案,处理极限情况,那就是直接把迟到的数据输出到侧输出流。
OutputTag<Tuple3<String, String, Long>> lateTag = new OutputTag<Tuple3<String, String, Long>>("late"){};
env.setParallelism(1);
SingleOutputStreamOperator<String> process = ds.map(new MapFunction<String, Tuple3<String, String, Long>>() {
@Override
public Tuple3<String, String, Long> map(String value) throws Exception {
String[] split = value.split(","); System.out.println(value);
return Tuple3.of(split[0], split[1], Long.valueOf(split[2]));
}
}).assignTimestampsAndWatermarks(WatermarkStrategy.
<Tuple3<String, String, Long>>forBoundedOutOfOrderness(Duration.ofSeconds(1))
.withTimestampAssigner(new SerializableTimestampAssigner<Tuple3<String, String, Long>>() {
@Override
public long extractTimestamp(Tuple3<String, String, Long> element, long recordTimestamp) {
return element.f2;
}
})
).keyBy(data -> data.f0)
.window(TumblingEventTimeWindows.of(Time.seconds(5)))
.allowedLateness(Time.minutes(1))
.sideOutputLateData(lateTag)

完整的测试代码如下

public class SideOutPutLateTest {

    public static void main(String[] args) throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStreamSource<String> ds = env.socketTextStream("hadoop103", 9999);

        OutputTag<Tuple3<String, String, Long>> lateTag = new OutputTag<Tuple3<String, String, Long>>("late"){};
env.setParallelism(1);
SingleOutputStreamOperator<String> process = ds.map(new MapFunction<String, Tuple3<String, String, Long>>() {
@Override
public Tuple3<String, String, Long> map(String value) throws Exception {
String[] split = value.split(","); System.out.println(value);
return Tuple3.of(split[0], split[1], Long.valueOf(split[2]));
}
}).assignTimestampsAndWatermarks(WatermarkStrategy.
<Tuple3<String, String, Long>>forBoundedOutOfOrderness(Duration.ofSeconds(1))
.withTimestampAssigner(new SerializableTimestampAssigner<Tuple3<String, String, Long>>() {
@Override
public long extractTimestamp(Tuple3<String, String, Long> element, long recordTimestamp) {
return element.f2;
}
})
).keyBy(data -> data.f0)
.window(TumblingEventTimeWindows.of(Time.seconds(5)))
.allowedLateness(Time.minutes(1))
.sideOutputLateData(lateTag)
.process(new ProcessWindowFunction<Tuple3<String, String, Long>, String, String, TimeWindow>() {
@Override
public void process(String s, ProcessWindowFunction<Tuple3<String, String, Long>, String, String, TimeWindow>.Context context, Iterable<Tuple3<String, String, Long>> iterable, Collector<String> collector) throws Exception {
long start = context.window().getStart();
long end = context.window().getEnd();
long watermark = context.currentWatermark();
long count = iterable.spliterator().getExactSizeIfKnown(); collector.collect(" 窗口 " + start + " - " + end + " 中共有 " + count + " 个元素,窗口关闭时,当前水位线" +
+watermark); }
});
// ds.print();
process.print();
process.getSideOutput(lateTag).print("迟到数据");
env.execute();
}
}

flink处理延迟的更多相关文章

  1. 深入理解Flink核心技术(转载)

    作者:李呈祥 Flink项目是大数据处理领域最近冉冉升起的一颗新星,其不同于其他大数据项目的诸多特性吸引了越来越多的人关注Flink项目.本文将深入分析Flink一些关键的技术与特性,希望能够帮助读者 ...

  2. Storm VS Flink ——性能对比

    1.背景 Apache Flink 和 Apache Storm 是当前业界广泛使用的两个分布式实时计算框架.其中 Apache Storm(以下简称"Storm")在美团点评实时 ...

  3. 深入了解 Flink 网络栈(二):监控、指标和处理背压

    在之前的文章中,我们从高级抽象到底层细节各个层面全面介绍了 Flink 网络栈的工作机制.作为这一系列的第二篇文章,本文将在第一篇的基础上更进一步,主要探讨如何监视与网络相关的指标,从而识别背压等因素 ...

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

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

  5. [Flink] Flink的waterMark的通俗理解

    导读 Flink 为实时计算提供了三种时间,即事件时间(event time).摄入时间(ingestion time)和处理时间(processing time). 遇到的问题: 假设在一个5秒的T ...

  6. flink进阶篇

    Flink 面试--进阶篇 1.Flink是如何支持批流一体的? 2.Flink是如何做到高效的数据交换的? 3.Flink是如何做容错的? 4.Flink 分布式快照的原理是什么? 5.Flink ...

  7. 《基于Apache Flink的流处理》读书笔记

    前段时间详细地阅读了 <Apache Flink的流处理> 这本书,作者是 Fabian Hueske&Vasiliki Kalavri,国内崔星灿翻译的,这本书非常详细.全面得介 ...

  8. Flink 中LatencyMarks延迟监控(源码分析)

    流式计算中处理延迟是一个非常重要的监控metric flink中通过开启配置   metrics.latency.interval  来开启latency后就可以在metric中看到askManage ...

  9. 使用Apache Flink 和 Apache Hudi 创建低延迟数据湖管道

    近年来出现了从单体架构向微服务架构的转变.微服务架构使应用程序更容易扩展和更快地开发,支持创新并加快新功能上线时间.但是这种方法会导致数据存在于不同的孤岛中,这使得执行分析变得困难.为了获得更深入和更 ...

随机推荐

  1. Postman大势已去

    作为一名前端,日常开发过程中除了写业务代码,前后端联调更是重要的一环.但这一环却往往是整个开发中最繁琐也最累人的一环.任谁都想早点下班,然而提升联调效率并不是个纯技术相关的问题,而是需要有良好工作流程 ...

  2. java实现二叉树的Node节点定义手撕8种遍历(一遍过)

    java实现二叉树的Node节点定义手撕8种遍历(一遍过) 用java的思想和程序从最基本的怎么将一个int型的数组变成Node树状结构说起,再到递归前序遍历,递归中序遍历,递归后序遍历,非递归前序遍 ...

  3. Rust如何开发eBPF应用(一)?

    前言 eBPF是一项革命性的技术,可以在Linux内核中运行沙盒程序,而无需重新编译内核或加载内核模块.它能够在许多内核 hook 点安全地执行字节码,主要应用在云原生网络.安全.跟踪监控等方面. e ...

  4. java 中为什么重写 equals 后需要重写 hashCode

    本文为博主原创,未经允许不得转载: 1. equals 和 hashCode 方法之间的关系 这两个方法都是 Object 的方法,意味着 若一个对象在没有重写 这两个方法时,都会默认采用 Objec ...

  5. 彻底解决Failed to execute goal on project xxxxx

    1.错误内容:Could not resolve dependencies for project 今天在使用mvn clean package命令对一个子项目打包的时候出现如下错误(但是使用mave ...

  6. 在jupyterlab中实现实时协同功能

    1 简介 当你在使用jupyter时,有没有想象过如果我们可以把正在编写代码的jupyter界面共享给其他人,使得别人可以在其他地方实时看到与你同步的jupyter界面,这样一来无论是与他人沟通代码逻 ...

  7. [AcWing 770] 单词替换

    点击查看代码 #include<iostream> #include<sstream> using namespace std; string s, a ,b; int mai ...

  8. 【ACM程序设计】并查集

    并查集 并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有:求连通子图.求最小生成树的Kruskal算法和求最近公共祖先( ...

  9. 详谈:pNFS增强文件系统架构

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 通过 NFS(由服务器.客户机软件和两者之间的协议组成) ...

  10. 关闭BottomSheetDialogFragment从后台返回后的动画

    问题 显示BottomSheetDialogFragment后.将当前应用放于后台,切换到其他APP,然后再返回当前应用.此时会看到BottomSheetDialogFragment从下而上的动画再次 ...