flink 处理实时数据的三重保障

  1. window+watermark 来处理乱序数据
    对于 TumblingEventTimeWindows window 的元数据startTime,endTime 和程序启动时间无关,当你指定出 window.size 时, window的startTime,endTime就分配好了

  2. allowedLateness 来处理迟到的数据
    相当于延迟了window 的生命周期, 【startTime,endTime) -> [startTime,endTime+ allowedLateness]

  3. sideOutput 是最后的兜底策略, 当window 的生命周期结束后, 延迟的数据可以通过侧输出收集起来,自定义后续的处理流程

测试

  1. 程序
import java.util.Date

import org.apache.flink.api.scala._
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.AssignerWithPeriodicWatermarks
import org.apache.flink.streaming.api.scala.{OutputTag, StreamExecutionEnvironment}
import org.apache.flink.streaming.api.watermark.Watermark
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.triggers.EventTimeTrigger object LastElement { case class Goods(var id: Int = 0, var count: Int = 0, var time: Long = 0L) {
override def toString: String = s"Goods(id=$id,count=$count,time=$time)"
} def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
env.setParallelism(1) // 创建延迟数据 OutputTag, 标记为 late-data
val lateOutputTag = OutputTag[Goods]("late-data") val stream = env
.socketTextStream("localhost", 9999)
.filter(_.nonEmpty)
.map(x => {
val arr = x.split(",")
Goods(arr(0).toInt, arr(1).toInt, arr(2).toLong) // id,count,time
})
.assignTimestampsAndWatermarks(new AssignerWithPeriodicWatermarks[Goods] {
val maxOutOfOrderness = 2L // 最大无序数据到达的时间,用来生成水印2ms
var currentMaxTimestamp: Long = _ override def getCurrentWatermark: Watermark = {
new Watermark(currentMaxTimestamp - maxOutOfOrderness)
} override def extractTimestamp(element: Goods, previousElementTimestamp: Long): Long = {
currentMaxTimestamp = Math.max(element.time, currentMaxTimestamp)
element.time
}
}) val streamFunc = stream
.keyBy(_.id)
.timeWindow(Time.milliseconds(10))
.trigger(EventTimeTrigger.create())
.allowedLateness(Time.milliseconds(3)) // 允许延时的最大时间
.sideOutputLateData(lateOutputTag) // 对延时数据进行标记
.reduce { (v1, v2) => Goods(v1.id, v1.count + v2.count, v2.time) } // lateOutputTag 从窗口结果中获取迟到数据局产生的统计结果
val lateStream = streamFunc.getSideOutput(lateOutputTag) stream
.print() streamFunc
.map(("_________sum: ", _))
.print() lateStream
.map(("+++++++++++late: ", _))
.print() env.execute(this.getClass.getSimpleName)
}
}

input:

1,1,0
1,1,9
1,2,10
1,1,5
1,2,11
1,1,8
1,2,13
1,1,2
1,2,17
1,1,3
1,3,20
1,3,21

output:

Goods(id=1,count=1,time=0)
Goods(id=1,count=1,time=9)
Goods(id=1,count=2,time=10)
Goods(id=1,count=1,time=5)
Goods(id=1,count=2,time=11)
(_________sum: ,Goods(id=1,count=3,time=5))
Goods(id=1,count=1,time=8)
(_________sum: ,Goods(id=1,count=4,time=8))
Goods(id=1,count=2,time=13)
Goods(id=1,count=1,time=2)
(_________sum: ,Goods(id=1,count=5,time=2))
Goods(id=1,count=2,time=17)
Goods(id=1,count=1,time=3)
(+++++++++++late: ,Goods(id=1,count=1,time=3))
Goods(id=1,count=3,time=20)
Goods(id=1,count=3,time=21)
(_________sum: ,Goods(id=1,count=8,time=17))

分析:

1,1,0  // win1 start
1,1,9 // win1 end 注意此时win1 没有关闭
1,2,10 // win2 start
1,1,5 // win1 这一条数据属于win1无序的数据,此时 watermark=7 < win1.endTime=9.
1,2,11 // win2 && win1 触发计算,原因是 watermark=9 >= win1.endTime=9 && win1中有数据。如果没有 allowedLateness(3ms)的话此时就已经 win1 关闭了,但是有延时3ms 所以还没有关闭
1,1,8 // win1 由于有 allowedLateness(3ms),这一条数据属于win1无序的数据,并触发 update;而不是 win1的 sideOutput 数据
1,2,13 // win2 && win1 处于 close 边缘,win1 真正的生命周期从 [0,9+2) -> [0,9+2+3]
1,1,2 // win1 allowedLateness(3ms) 导致 update
1,2,17 // win2 && win1 close
1,1,3 // win1 此时win1 已经close, 这条数据属于win1 的 sideOutput
1,3,20 // win3 start
1,3,21 // win3 && win2 触发计算 // 所以最后的结果:
win1: 1,5,2 + sideOutPut: 1,1,3
win2: 1,8,17
win3: 1,6,21

flink 处理实时数据的三重保障的更多相关文章

  1. 阿里云体验有奖:使用PolarDB-X与Flink搭建实时数据大屏

    体验简介 场景将提供一台配置了CentOS 8.5操作系统的ECS实例(云服务器).通过本教程的操作带您体验如何使用PolarDB-X与Flink搭建一个实时数据链路,模拟阿里巴巴双十一GMV大屏. ...

  2. Flink消费Kafka数据并把实时计算的结果导入到Redis

    1. 完成的场景 在很多大数据场景下,要求数据形成数据流的形式进行计算和存储.上篇博客介绍了Flink消费Kafka数据实现Wordcount计算,这篇博客需要完成的是将实时计算的结果写到redis. ...

  3. Flink实战| Flink+Redis实时防刷接口作弊

    随着人口红利的慢慢削减,互联网产品的厮杀愈加激烈,大家开始看好下沉市场的潜力,拼多多,趣头条等厂商通过拉新奖励,购物优惠等政策率先抢占用户,壮大起来.其他各厂商也紧随其后,纷纷推出自己产品的极速版,如 ...

  4. DataPipeline丨构建实时数据集成平台时,在技术选型上的考量点

    文 | 陈肃 DataPipeline  CTO 随着企业应用复杂性的上升和微服务架构的流行,数据正变得越来越以应用为中心. 服务之间仅在必要时以接口或者消息队列方式进行数据交互,从而避免了构建单一数 ...

  5. (二)基于商品属性的相似商品推荐算法——Flink SQL实时计算实现商品的隐式评分

    系列随笔: (总览)基于商品属性的相似商品推荐算法 (一)基于商品属性的相似商品推荐算法--整体框架及处理流程 (二)基于商品属性的相似商品推荐算法--Flink SQL实时计算实现商品的隐式评分 ( ...

  6. 指标统计:基于流计算 Oceanus(Flink) 实现实时 UVPV 统计

    作者:吴云涛,腾讯 CSIG 高级工程师导语 | 最近梳理了一下如何用 Flink 来实现实时的 UV.PV 指标的统计,并和公司内微视部门的同事交流.然后针对该场景做了简化,并发现使用 Flink ...

  7. Kafka ETL 之后,我们将如何定义新一代实时数据集成解决方案?

    上一个十年,以 Hadoop 为代表的大数据技术发展如火如荼,各种数据平台.数据湖.数据中台等产品和解决方案层出不穷,这些方案最常用的场景包括统一汇聚企业数据,并对这些离线数据进行分析洞察,来达到辅助 ...

  8. 搭建企业级实时数据融合平台难吗?Tapdata + ES + MongoDB 就能搞定

      摘要:如何打造一套企业级的实时数据融合平台?Tapdata 已经找到了最佳实践,下文将以 Tapdata 的零售行业客户为例,与您分享:基于 ES 和 MongoDB 来快速构建一套企业级的实时数 ...

  9. Tapdata肖贝贝:实时数据引擎系列(三) - 流处理引擎对比

      摘要:本文将选取市面上一些流计算框架包括 Flink .Spark .Hazelcast,从场景需求出发,在核心功能.资源与性能.用户体验.框架完整性.维护性等方面展开分析和测评,剖析实时数据框架 ...

随机推荐

  1. Vue中vue.config的配置

    vue-cli 3.x 脚手架搭建完成后,项目目录中没有 vue.config.js 文件,需要手动在根目录中创建 vue.config.js. vue.config.js 是一个可选的配置文件,如果 ...

  2. [LeetCode] 203. 移除链表元素(链表基本操作-删除)、876. 链表的中间结点(链表基本操作-找中间结点)

    题目 203. 移除链表元素 删除链表中等于给定值 val 的所有节点. 题解 删除结点:要注意虚拟头节点. 代码 class Solution { public ListNode removeEle ...

  3. zookeeper服务端

    服务端启动时,就启动线程通过NIO监听网络端口.每个连接都会有一个上下文环境对象,当接收到请求后,会在上下文环境对象中进行处理. 服务端启动线程,监听网络端口,(NIOServerCnxn.Facto ...

  4. Shiro框架--将Shrio的session改成HTTPSession数据

    重写 FormAuthenticationFilter类 的 onLoginSuccess()方法即可 import javax.servlet.ServletRequest; import java ...

  5. 接口鉴权,提供给第三方调用的接口,进行sign签名

    //场景:公司要跟第三方公司合作,提供接口给对方对接,这样需要对接口进行授权,不然任何人都可以调我们公司的接口,会导致安全隐患: 思路: 在每个接口请求参数都带上ApiKey 和sign签名: 我们在 ...

  6. Python-local variable 'raw_password' referenced before assignment

    where? 执行Python程序的时候,报这个错 why? 变量作用域问题,在分支中定义的变量,当满足条件的时候则可以正确得到变量,当不满足条件的时候则报这个错 way? 把变量从分支中抽离到分支上 ...

  7. Go-The process cannot access the file because it is being used by another process.

    where? Go程序在读取文件时候 why? 因为有其他进程也在读取和Go程序想要读取的文件,参数冲突 way? 关闭其他程序进程对该文件的读取操作

  8. 基于Excel参数化你的Selenium2测试-xlrd

    本篇文章转载至苦叶子:   前言 今天我们就如何使用xlrd模块来进行python selenium2 + excel自动化测试过程中的参数化进行演示说明,以解决大家在自动化测试实践过程中参数化的疑问 ...

  9. 071 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 03 综合案例-数组移位-显示数组当中所有元素的的方法

    071 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 03 综合案例-数组移位-显示数组当中所有元素的的方法 本文知识点:综合案例-数组移位-显示数组当中所有元素 ...

  10. DMZ是什么

    刚刚接触安全域,实在是佩服自己真的是菜,,,啥都不懂,看看过段时间能有多大进步吧... 概念 DMZ:它是一个缓冲区,一个隔离区.它是位于两台防火墙之间的区域,相对于INTER网来说安全级别高一些,但 ...