flink双流join
package com.streamingjoin import org.apache.flink.api.common.state.{ValueState, ValueStateDescriptor}
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.co.KeyedCoProcessFunction
import org.apache.flink.streaming.api.scala._
import org.apache.flink.util.Collector /**
* 将五分钟之内的订单信息和支付信息进行对账,对不上的发出警告
*/
object TwoStreamJoinDemo { // 用来输出没有匹配到的订单支付事件
val unmatchedOrders = new OutputTag[String]("unmatched-orders")
// 用来输出没有匹配到的第三方支付事件
val unmatchedPays = new OutputTag[String]("unmatched-pays") def main(args: Array[String]): Unit = { val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime) val orders: KeyedStream[OrderEvent, String] = env.fromElements(
OrderEvent("order_1", "pay", 2000L),
OrderEvent("order_2", "pay", 5000L),
OrderEvent("order_3", "pay", 6000L))
.assignAscendingTimestamps(_.eventTime)
.keyBy(_.orderId) val pays: KeyedStream[PayEvent, String] = env
.fromElements(
PayEvent("order_1", "weixin", 7000L),
PayEvent("order_2", "weixin", 8000L),
PayEvent("order_4", "weixin", 9000L)
)
.assignAscendingTimestamps(_.eventTime)
.keyBy(_.orderId) val processed: DataStream[String] = orders.connect(pays).process(new MatchFunction) processed.print()
processed.getSideOutput(unmatchedOrders).print()
processed.getSideOutput(unmatchedPays).print() env.execute() } //订单支付事件
case class OrderEvent(orderId: String,
eventType: String,
eventTime: Long) //第三方支付事件,例如微信,支付宝
case class PayEvent(orderId: String,
eventType: String,
eventTime: Long) //进入同一条流中的数据肯定是同一个key,即OrderId
//肯定会用到状态了
class MatchFunction extends KeyedCoProcessFunction[String, OrderEvent, PayEvent, String] { //状态的定义
lazy private val orderState: ValueState[OrderEvent] = getRuntimeContext.getState(new ValueStateDescriptor[OrderEvent]("orderState", classOf[OrderEvent]))
lazy private val payState: ValueState[PayEvent] = getRuntimeContext.getState(new ValueStateDescriptor[PayEvent]("payState", classOf[PayEvent])) override def processElement1(value: OrderEvent, ctx: KeyedCoProcessFunction[String, OrderEvent, PayEvent, String]#Context, out: Collector[String]): Unit = {
//从payState中查找数据,如果存在,说明匹配成功
val pay = payState.value()
if (pay != null) {
payState.clear()
out.collect("订单ID为 " + pay.orderId + " 的两条流对账成功")
} else {
//如果不存在,则说明可能对应的pay数据没有来,需要存入状态等待
//定义一个5min的定时器,到时候再匹配,如果还没匹配上,则说明匹配失败发出警告
orderState.update(value)
ctx.timerService().registerEventTimeTimer(value.eventTime + 5000)
}
} override def processElement2(value: PayEvent, ctx: KeyedCoProcessFunction[String, OrderEvent, PayEvent, String]#Context, out: Collector[String]): Unit = {
val order = orderState.value()
if (order != null) {
orderState.clear()
out.collect("订单ID为 " + order.orderId + " 的两条流对账成功!")
} else {
payState.update(value)
ctx.timerService().registerEventTimeTimer(value.eventTime + 5000)
}
} override def onTimer(timestamp: Long, ctx: KeyedCoProcessFunction[String, OrderEvent, PayEvent, String]#OnTimerContext, out: Collector[String]): Unit = { if (orderState.value() != null) {
//将警告信息发送到侧输出流中
ctx.output(unmatchedOrders, s"订单ID为 ${orderState.value().orderId} 的两条流没有对账成功!")
orderState.clear()
} if (payState.value() != null) {
ctx.output(unmatchedPays, s"订单ID为 ${payState.value().orderId} 的两条流没有对账成功! ")
payState.clear()
} }
} }
flink双流join的更多相关文章
- 面试官: Flink双流JOIN了解吗? 简单说说其实现原理
摘要:今天和大家聊聊Flink双流Join问题.这是一个高频面试点,也是工作中常遇到的一种真实场景. 本文分享自华为云社区<万字直通面试:Flink双流JOIN>,作者:大数据兵工厂 . ...
- flink-----实时项目---day06-------1. 获取窗口迟到的数据 2.双流join(inner join和left join(有点小问题)) 3 订单Join案例(订单数据接入到kafka,订单数据的join实现,订单数据和迟到数据join的实现)
1. 获取窗口迟到的数据 主要流程就是给迟到的数据打上标签,然后使用相应窗口流的实例调用sideOutputLateData(lateDataTag),从而获得窗口迟到的数据,进而进行相关的计算,具体 ...
- flink dataset join笔记
1.dataset的join连接,通过key进行关联,一般情况下的join都是inner join,类似sql里的inner join key包括以下几种情况: a key expression a ...
- Apache Flink 漫谈系列 - JOIN 算子
聊什么 在<Apache Flink 漫谈系列 - SQL概览>中我们介绍了JOIN算子的语义和基本的使用方式,介绍过程中大家发现Apache Flink在语法语义上是遵循ANSI-SQL ...
- Apache-Flink深度解析-JOIN 算子
什么是JOIN 在<Apache Flink 漫谈系列 - SQL概览>中我对JOIN算子有过简单的介绍,这里我们以具体实例的方式让大家对JOIN算子加深印象.JOIN的本质是分别从N(N ...
- Flink sql 之 join 与 StreamPhysicalJoinRule (源码解析)
源码分析基于flink1.14 Join是flink中最常用的操作之一,但是如果滥用的话会有很多的性能问题,了解一下Flink源码的实现原理是非常有必要的 本文的join主要是指flink sql的R ...
- Flink官网文档翻译
http://ifeve.com/flink-quick-start/ http://vinoyang.com/2016/05/02/flink-concepts/ http://wuchong.me ...
- Flink 灵魂两百问,这谁顶得住?
Flink 学习 https://github.com/zhisheng17/flink-learning 麻烦路过的各位亲给这个项目点个 star,太不易了,写了这么多,算是对我坚持下来的一种鼓励吧 ...
- Flink/CEP/规则引擎/风控
基于 Apache Flink 和规则引擎的实时风控解决方案 对一个互联网产品来说,典型的风控场景包括:注册风控.登陆风控.交易风控.活动风控等,而风控的最佳效果是防患于未然,所以事前事中和事后三 ...
随机推荐
- Oracle19c 如何用rman duplicate 克隆一个数据库。(Active方式)
Oracle19c 如何用rman duplicate 克隆一个数据库. 首先克隆有两种方法,一种是Backup-Based,一种是Active方式.官网文档链接https://docs.oracle ...
- Odoo开发规范
本文来源:https://www.jianshu.com/p/e892bf01f036 Odoo开发规范 模块结构 文件夹列表及对应作用 data/:演示和数据文件 models/:模型定义 cont ...
- DNS的原理和解析过程
DNS的解析原理和过程: 在Internet上域名和IP是对应的,DNS解析有两种:一种是正向解析,另外一种是反向解析. 正向解析:正向解析就是将域名转换成对应的 IP地址的过程,它应用于在浏览器地址 ...
- (JAVA2)写博客的好帮手:Typora
(二)写博客的好帮手:Typora 推荐文本编辑器 :Typora 文件后缀 : xxx.md 安装步骤 打开浏览器搜索Typora 进入官网后,点击Download(下载) 选择自己的操作系统 选择 ...
- 02.反射Reflection
1. 基本了解 1.1 反射概述 文字说明 审查元数据并收集关于它的类型信息的能力称为反射,其中元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个 ...
- 实战 | Hive 数据倾斜问题定位排查及解决
Hive 数据倾斜怎么发现,怎么定位,怎么解决 多数介绍数据倾斜的文章都是以大篇幅的理论为主,并没有给出具体的数据倾斜案例.当工作中遇到了倾斜问题,这些理论很难直接应用,导致我们面对倾斜时还是不知所措 ...
- 根据JavaScript中原生的XMLHttpRequest实现jQuery的Ajax
基本介绍 XmlHttpRequest XmlHttpRequest是JavaScript中原生的,历史悠久的一种发送网络请求的方案. 基本上所有前端框架对于网络请求的部分都是基于它来完成的. 在本章 ...
- Oracle中使用虚拟表DUAL或XMLTABLE返回顺序数列
在Oracle中使用虚拟表DUAL或XMLTABLE返回顺序数列 使用DUAL表和CONNECT BY LEVEL的特殊用法,返回一个1-10的顺序数列,示例代码如下: SELECT LEVEL FR ...
- 深度学习算子优化-FFT
作者:严健文 | 旷视 MegEngine 架构师 背景 在数字信号和数字图像领域, 对频域的研究是一个重要分支. 我们日常"加工"的图像都是像素级,被称为是图像的空域数据.空域数 ...
- 源码解析.Net中IConfiguration配置的实现
前言 关于IConfituration的使用,我觉得大部分人都已经比较熟悉了,如果不熟悉的可以看这里.因为本篇不准备讲IConfiguration都是怎么使用的,但是在源码部分的解读,网上资源相对少一 ...