Structured Stream--Join Operations

本文介绍了Spark Structured Streaming的Join Operations,包括Stream-static Joins和Stream-Stream Joins。Stream-static Joins不需要状态管理,但部分外连接不支持。Stream-Stream Joins在Spark 2.3中引入,处理两个不断增长的流的join,使用watermark来处理延迟和乱序数据,并需要定义额外的条件限制状态存储,避免无限增长。
摘要由CSDN通过智能技术生成
Join Operations

自Spark-2.0 Structured Streaming引入的join的概念(inner和一些外连接)。支持和静态或者动态的Dataset/DataFrame做join操作。

Stream-static Joins
def main(args: Array[String]): Unit = {

    val spark = SparkSession
      .builder
      .appName("StructuredNetworkWordCount")
      .master("local[*]")
      .getOrCreate()

    spark.sparkContext.setLogLevel("ERROR")

    import spark.implicits._
    
    val userDF = spark.sparkContext.parallelize(List((1,"zs"),(2,"lisi")))
      .toDF("id","name")
    
    //1 apple 1 45
    val lineDF = spark.readStream.format("socket")
      .option("host", "train")
      .option("port", 9999)
      .load()
    
    
    val orderItemDF = lineDF.as[String]
      .map(t=>{
        val tokens = t.split(" ")
        (tokens(0).toInt,tokens(1),(tokens(2).toInt)*(tokens(3).toDouble))
      }).toDF("uid","item","cost")
    import org.apache.spark.sql.functions._
    val joinDF = orderItemDF.join(userDF, $"id" === $"uid")
      .groupBy("uid", "name")
      .agg(sum("cost").as("total_cost"))
    
    
   //3.产生StreamQuery对象
    val query:StreamingQuery = joinDF.writeStream
      .outputMode(OutputMode.Update())
      .format("console")
      .start()
    query.awaitTermination()
  }

注意: stream-static joins并不是状态的,所以不需要做状态管理,目前还有一些外连接还不支持,目前只支持innerleft outer

Stream-Stream Joins

在Spark-2.3添加了streaming-streaming的支持,实现两个流的join最大的挑战是在于找到一个时间点实现两个流的join,因为这两个流都没有结束。任意一个接受的流可以匹配另一个流中即将被接受的数据。所以在任意一个流中我们需要接收并将这些数据进行缓存,然后作为当前stream的状态,然后去匹配另外一个流的后续接收的数据,继而生成相应的join的结果集。和Streaming的聚合很类似我们使用watermarker处理late,乱序的数据,限制状态的使用。

内连接可以使用任意一些column作为连接条件,然而在Stream计算开始运行的时候,流计算的状态会持续的增长,因为必须存储所有传递过来的状态数据,然后和后续的新接受的数据做匹配。为了避免无限制的状态存储。一般需要定义额外的join的条件。例如限制一些old数据如果和新数据时间间隔大于某个阈值就不能匹配。因此可以删除这些陈旧的状态。简单来说需要做以下步骤:

  • 两边流计算需要定义watermarker延迟,这样系统可以知道两个流的时间差值。
  • 定制以下event time的限制条件,这样引擎可以计算出哪些数据old的不再需要了。可以使用以下两种方式定制
  1. 时间范围界定例如:JOIN ON leftTime BETWEEN rightTime AND rightTime + INTERVAL 1 HOUR
  2. 基于Event-time Window例如:JOIN ON leftTimeWindow = rightTimeWindow

案例1(Range案例)

def main(args: Array[String]): Unit = {
   

    val spark = SparkSession
      .builder
      .appName("StructuredNetworkWordCount")
      .master("local[*]")
      .getOrCreate()

    spark.sparkContext.setLogLevel("ERROR")

    import spark.implicits._

    //001 apple 1 4.5 1566113401000
    //创建DF
    val orderDF = spark.readStream
      .format("socket")
      .option("host", "train")
      .option("port", 9999)
      .load()
      .
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值