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的更多相关文章

  1. 面试官: Flink双流JOIN了解吗? 简单说说其实现原理

    摘要:今天和大家聊聊Flink双流Join问题.这是一个高频面试点,也是工作中常遇到的一种真实场景. 本文分享自华为云社区<万字直通面试:Flink双流JOIN>,作者:大数据兵工厂 . ...

  2. flink-----实时项目---day06-------1. 获取窗口迟到的数据 2.双流join(inner join和left join(有点小问题)) 3 订单Join案例(订单数据接入到kafka,订单数据的join实现,订单数据和迟到数据join的实现)

    1. 获取窗口迟到的数据 主要流程就是给迟到的数据打上标签,然后使用相应窗口流的实例调用sideOutputLateData(lateDataTag),从而获得窗口迟到的数据,进而进行相关的计算,具体 ...

  3. flink dataset join笔记

    1.dataset的join连接,通过key进行关联,一般情况下的join都是inner join,类似sql里的inner join key包括以下几种情况: a key expression a ...

  4. Apache Flink 漫谈系列 - JOIN 算子

    聊什么 在<Apache Flink 漫谈系列 - SQL概览>中我们介绍了JOIN算子的语义和基本的使用方式,介绍过程中大家发现Apache Flink在语法语义上是遵循ANSI-SQL ...

  5. Apache-Flink深度解析-JOIN 算子

    什么是JOIN 在<Apache Flink 漫谈系列 - SQL概览>中我对JOIN算子有过简单的介绍,这里我们以具体实例的方式让大家对JOIN算子加深印象.JOIN的本质是分别从N(N ...

  6. Flink sql 之 join 与 StreamPhysicalJoinRule (源码解析)

    源码分析基于flink1.14 Join是flink中最常用的操作之一,但是如果滥用的话会有很多的性能问题,了解一下Flink源码的实现原理是非常有必要的 本文的join主要是指flink sql的R ...

  7. Flink官网文档翻译

    http://ifeve.com/flink-quick-start/ http://vinoyang.com/2016/05/02/flink-concepts/ http://wuchong.me ...

  8. Flink 灵魂两百问,这谁顶得住?

    Flink 学习 https://github.com/zhisheng17/flink-learning 麻烦路过的各位亲给这个项目点个 star,太不易了,写了这么多,算是对我坚持下来的一种鼓励吧 ...

  9. Flink/CEP/规则引擎/风控

    基于 Apache Flink 和规则引擎的实时风控解决方案 ​ 对一个互联网产品来说,典型的风控场景包括:注册风控.登陆风控.交易风控.活动风控等,而风控的最佳效果是防患于未然,所以事前事中和事后三 ...

随机推荐

  1. 从源码构建Vim

    从源码构建Vim 引言 事情是介样滴,因为我是个Vim 重度使用者了差不多.. 但在大部分系统上能安装到的或者自带的都是比较老的版本,可能是7.x 之类的.也或者是你需要使用到Vim 的某些特性或者功 ...

  2. 分布式ID生成器(CosId)的设计与实现

    分布式ID生成器(CosId)设计与实现 CosId 简介 CosId 旨在提供通用.灵活.高性能的分布式 ID 生成器. 目前提供了俩类 ID 生成器: SnowflakeId : 单机 TPS 性 ...

  3. POJ1723,1050,HDU4864题解(贪心)

    POJ1723 Soldiers 思维题. 考虑y坐标,简单的货舱选址问题,选择中位数即可. 再考虑x坐标,由于直接研究布置方法非常困难,可以倒着想:不管如何移动,最后的坐标总是相邻的,且根据贪心的思 ...

  4. 【Azure 应用服务】App Service 通过配置web.config来添加请求返回的响应头(Response Header)

    问题描述 在Azure App Service上部署了站点,想要在网站的响应头中加一个字段(Cache-Control),并设置为固定值(Cache-Control:no-store) 效果类似于本地 ...

  5. intouch/ifix嵌入视频控件2(报警视频联动初步思路)

    在项目中有朋友遇到类似的需求,ifix中嵌入视频,并实现报警与视频的联动功能.诸如,重要设备启动时,摄像头自动弹窗,并持续一段时间自动弹窗关掉:设备故障时,摄像头自动截图,录像一段时间存储:设备停止时 ...

  6. xxe 回显与无回显

    转载学习于红日安全 一.有回显 (1)直接将外部实体引用的URI设置为敏感目录 <!DOCTYPE foo [<!ELEMENT foo ANY > <!ENTITY  xxe ...

  7. XSS靶机1

    参考文章https://blog.csdn.net/weixin_30897079/article/details/97314476 第一关 http://www.zixem.altervista.o ...

  8. 破解网站码验证,Java实现,不调用任何平台api接口

    package image.images; import java.io.File; import java.io.IOException; import java.io.InputStream; i ...

  9. Android技术分享| 实现视频连麦直播

    视频连麦产品端核心步骤分析 游客申请连麦/取消申请 主播同意/拒绝申请 音视频发布取消 支持很多观众观看 支持多人连麦 低延时 IM 弹幕 视频连麦技术端调研 emmm,大致可以分为视频采集.编码,传 ...

  10. 自学linux——5.网络设置

    网络设置 1.网卡配置文件位置:ls /etc/sysconfig/network-scripts/ 2.网卡配置文件命名:ifcfg-网卡名称 3.查看网卡配置文件:cat /etc/sysconf ...