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 和规则引擎的实时风控解决方案 对一个互联网产品来说,典型的风控场景包括:注册风控.登陆风控.交易风控.活动风控等,而风控的最佳效果是防患于未然,所以事前事中和事后三 ...
随机推荐
- html自定义加载动画
整体代码 HTML 实现自定义加载动画,话不多说如下代码所示: <!DOCTYPE html> <html lang="en"> <head> ...
- 给你的Mac 整个好用的命令行iTerm2 + zsh + oh-my-zsh + powerlevel10k
给你的Mac 整个好用的命令行iTerm2 + zsh + oh-my-zsh + powerlevel10k 介绍 iTerm2 是一个MacOS 下的终端模拟器,和其他的终端本质上没啥大不同.但相 ...
- CSS设置height为100%无效的情况
CSS设置height为100%无效的情况 笔者是小白,不是特别懂前端.今天写一个静态的HTML页面,然后想要一个div占据页面的100%,但是尝试了很多办法都没有实现,不知道什么原因. 后来取百度搜 ...
- informix数据库分页
需求描述 当查询结果返回大量数据情况下,比如报表查询.需要按一定条件排序提供分页呈现数据. INFORMIX实现方案:Informix 数据库提供了非常便捷.高效的SQL. SELECT SKIP M ...
- 第四篇--Beyond Compare4 试用期30天后
30天后删除BCUnrar.dll这个文件,继续使用30天.还有就是注册表中regedit-->HEKY_CURRENT_USER-->Software-->Scooter Soft ...
- Java逻辑运算符&与&&
& 和&&的区别 && 短路与 ,一个条件不成立,跳出判断 & 与 , 全部判断 boolean b1 = false; int num = 9; if ...
- r正则表达式
/t 制表符. /n 新行. . 匹配任意字符. | 匹配表达式左边和右边的字符. 例如, "ab|bc" 匹配 "ab" 或者 "bc". ...
- YOLO-v4 口罩识别
YOLO-v4 口罩识别 一.YOLO-v4概念 如果想要了解和认识yolo-v4的基本概念,首先要提的就是它的基础版本yolo-v1,对于yolo来说,最经典的算是yolo-v3.如果想要了解它的由 ...
- ECDSA高性能硬件实现——算法详解与模块划分
ECDSA全称椭圆曲线数字签名算法,它是基于素数域的椭圆曲线对信息进行加签与验签.其核心在于对信息的加签,及对加签的信息进行验签,那么下面介绍该算法流程. 假设Alice希望对消息m进行签名,并将消息 ...
- 还怕问源码?Github上神级Android三方源码解析手册,已有7.6 KStar
或许对于许多Android开发者来说,所谓的Android工程师的工作"不过就是用XML实现设计师的美术图,用JSON解析服务器的数据,再把数据显示到界面上"就好了,源码什么的,看 ...