1. package com.streamingjoin
  2.  
  3. import org.apache.flink.api.common.state.{ValueState, ValueStateDescriptor}
  4. import org.apache.flink.streaming.api.TimeCharacteristic
  5. import org.apache.flink.streaming.api.functions.co.KeyedCoProcessFunction
  6. import org.apache.flink.streaming.api.scala._
  7. import org.apache.flink.util.Collector
  8.  
  9. /**
  10. * 将五分钟之内的订单信息和支付信息进行对账,对不上的发出警告
  11. */
  12. object TwoStreamJoinDemo {
  13.  
  14. // 用来输出没有匹配到的订单支付事件
  15. val unmatchedOrders = new OutputTag[String]("unmatched-orders")
  16. // 用来输出没有匹配到的第三方支付事件
  17. val unmatchedPays = new OutputTag[String]("unmatched-pays")
  18.  
  19. def main(args: Array[String]): Unit = {
  20.  
  21. val env = StreamExecutionEnvironment.getExecutionEnvironment
  22. env.setParallelism(1)
  23. env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
  24.  
  25. val orders: KeyedStream[OrderEvent, String] = env.fromElements(
  26. OrderEvent("order_1", "pay", 2000L),
  27. OrderEvent("order_2", "pay", 5000L),
  28. OrderEvent("order_3", "pay", 6000L))
  29. .assignAscendingTimestamps(_.eventTime)
  30. .keyBy(_.orderId)
  31.  
  32. val pays: KeyedStream[PayEvent, String] = env
  33. .fromElements(
  34. PayEvent("order_1", "weixin", 7000L),
  35. PayEvent("order_2", "weixin", 8000L),
  36. PayEvent("order_4", "weixin", 9000L)
  37. )
  38. .assignAscendingTimestamps(_.eventTime)
  39. .keyBy(_.orderId)
  40.  
  41. val processed: DataStream[String] = orders.connect(pays).process(new MatchFunction)
  42.  
  43. processed.print()
  44. processed.getSideOutput(unmatchedOrders).print()
  45. processed.getSideOutput(unmatchedPays).print()
  46.  
  47. env.execute()
  48.  
  49. }
  50.  
  51. //订单支付事件
  52. case class OrderEvent(orderId: String,
  53. eventType: String,
  54. eventTime: Long)
  55.  
  56. //第三方支付事件,例如微信,支付宝
  57. case class PayEvent(orderId: String,
  58. eventType: String,
  59. eventTime: Long)
  60.  
  61. //进入同一条流中的数据肯定是同一个key,即OrderId
  62. //肯定会用到状态了
  63. class MatchFunction extends KeyedCoProcessFunction[String, OrderEvent, PayEvent, String] {
  64.  
  65. //状态的定义
  66. lazy private val orderState: ValueState[OrderEvent] = getRuntimeContext.getState(new ValueStateDescriptor[OrderEvent]("orderState", classOf[OrderEvent]))
  67. lazy private val payState: ValueState[PayEvent] = getRuntimeContext.getState(new ValueStateDescriptor[PayEvent]("payState", classOf[PayEvent]))
  68.  
  69. override def processElement1(value: OrderEvent, ctx: KeyedCoProcessFunction[String, OrderEvent, PayEvent, String]#Context, out: Collector[String]): Unit = {
  70. //从payState中查找数据,如果存在,说明匹配成功
  71. val pay = payState.value()
  72. if (pay != null) {
  73. payState.clear()
  74. out.collect("订单ID为 " + pay.orderId + " 的两条流对账成功")
  75. } else {
  76. //如果不存在,则说明可能对应的pay数据没有来,需要存入状态等待
  77. //定义一个5min的定时器,到时候再匹配,如果还没匹配上,则说明匹配失败发出警告
  78. orderState.update(value)
  79. ctx.timerService().registerEventTimeTimer(value.eventTime + 5000)
  80. }
  81. }
  82.  
  83. override def processElement2(value: PayEvent, ctx: KeyedCoProcessFunction[String, OrderEvent, PayEvent, String]#Context, out: Collector[String]): Unit = {
  84. val order = orderState.value()
  85. if (order != null) {
  86. orderState.clear()
  87. out.collect("订单ID为 " + order.orderId + " 的两条流对账成功!")
  88. } else {
  89. payState.update(value)
  90. ctx.timerService().registerEventTimeTimer(value.eventTime + 5000)
  91. }
  92. }
  93.  
  94. override def onTimer(timestamp: Long, ctx: KeyedCoProcessFunction[String, OrderEvent, PayEvent, String]#OnTimerContext, out: Collector[String]): Unit = {
  95.  
  96. if (orderState.value() != null) {
  97. //将警告信息发送到侧输出流中
  98. ctx.output(unmatchedOrders, s"订单ID为 ${orderState.value().orderId} 的两条流没有对账成功!")
  99. orderState.clear()
  100. }
  101.  
  102. if (payState.value() != null) {
  103. ctx.output(unmatchedPays, s"订单ID为 ${payState.value().orderId} 的两条流没有对账成功! ")
  104. payState.clear()
  105. }
  106.  
  107. }
  108. }
  109.  
  110. }

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. SpringMvc接受请求参数的几种情况演示

    说明: 通常get请求获取的参数是在url后面,而post请求获取的是请求体当中的参数.因此两者在请求方式上会有所不同. 1.直接将接受的参数写在controller对应方法的形参当中(适用于get提 ...

  2. 微信小程序云开发-云存储-获取带图片的商品列表

    一.将商品图片上传至云存储 如下图,已准备5张商品图片,并且已经将商品图片上传至云存储  二.数据库表添加图片字段 在数据库表goods添加字段image,该字段用来存储图片的url信息 image在 ...

  3. PAT甲级:1064 Complete Binary Search Tree (30分)

    PAT甲级:1064 Complete Binary Search Tree (30分) 题干 A Binary Search Tree (BST) is recursively defined as ...

  4. 解决 centerOS7部署ajango2.2.x版本 报SQLite 3.8.3 or later is required (found 3.7.17).错误

    在CentOS7上部署Django的时候,遇到了一些问题,写篇笔记记录解决过程. 报错信息 当python3 manage.py runserver启动django项目的时候,就会出现报错信息如下: ...

  5. 第九篇 -- 可以上网,连WIFI弹出网页

    最近在调试WIFI模块时,程序路径没走对,导致运行了其他的函数,修改了配置文件,之后每次连接WIFI时都会弹出网页,并且明明可以上网,下面电脑符号那儿还会出现黄标,甚是心烦.上网搜索一番,终是解决了. ...

  6. CC2B本地环境搭建步骤及部署问题解决

    由于最近的项目是之前没接触过的netbeans+glassfish,记录一下最近在工作中搭建本地环境的步骤及遇到的一些问题解决方法: 1.配置java jdk 此过程中遇到一个问题就是在配置系统环境变 ...

  7. Jenkins-CI 远程代码执行漏洞(CVE-2017-1000353)

    影响范围 所有Jenkins主版本均受到影响(包括<=2.56版本) 所有Jenkins LTS 均受到影响( 包括<=2.46.1版本) poc下载 https://github.com ...

  8. YOLO-V4 实现口罩识别(附加数据、数据批量处理程序)

    一.YOLO-v4概念 如果想要了解和认识yolo-v4的基本概念,首先要提的就是它的基础版本yolo-v1,对于yolo来说,最经典的算是yolo-v3.如果想要了解它的由来和历史的话,可以自行搜索 ...

  9. sql注入漏洞笔记随笔

    sql注入是从1998年出现的,是一个十分常见的漏洞,它是OWASP top10的第一名(注入) 在了解sql注入之前,我们需要先了解web框架 webapp:web网站,这种方式它采用的是B/S架构 ...

  10. 关于Linux下Texlive无法找到已安装字体的问题与解决

    关于Linux下Texlive无法找到已安装字体的问题与解决 当我在Ubuntu系统下使用Latex时,在编译渲染时报出了Font "xxx" does not contain r ...