Structured Streaming使用

Structured Streaming

简介

Structured Streaming 构建在SparkSQL之上的流处理引擎。可以使用户继续使用DataSet/dataFrame操作流数据。并且提供了多种计算模型可供选择,默认情况下,使用的依然是Spark的marco batch这种计算模型能够到100ms左右的end-to-end的精准一次的容错计算。除此之外也提供了基于EventTime 语义的窗口计算(DStream 基于Processor Time不同)。同时在spark-2.3版本又提出新的计算模型Continuous Processing 可以达到1ms左右的精准一次的容错计算。

快速入门案例

使用Structured Streaming实现通过接收SocketServer发送过来的文本数据,实现wordcount。

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.11</artifactId>
    <version>2.4.3</version>
</dependency>
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.11</artifactId>
    <version>2.4.3</version>
</dependency>
//1.构建SparkSession
val spark=SparkSession.builder()
    .appName("wordcount")
    .master("local[6]")
    .getOrCreate()

import spark.implicits._

//2.创建输入流-readStream
var lines= spark.readStream
    .format("socket")
    .option("host","CentOS")
    .option("port",9999)
    .load()

//3.对dataframe实现转换
var wordCounts = lines.as[String]
    .f


//4.构建query 输出
val query = wordCounts.writeStream
    .format("console")
    .outputMode(OutputMode.Update())//有状态持续计算 Complete| Update
    .start()

//5.等待流结束
query.awaitTermination()

程序结构

1.构建SparkSession 对象
2.借助于SparkSession#readStream加载动态的Dataframe
3.使用dataframe API或者是SQL语句 实现对动态数据计算
4.通过DataFrame#writeStream方法构建StreamQuery对象
5.调用StreamQuery#awaitTermination等待关闭指令

基本概念

Structure Stream的核心思想是通过将实时数据流看成是一个持续插入table.因此用户就可以使用SQL查询DynamicTable|UnboundedTable。底层Spark通过StreamQuery实现对数据持续计算。

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/fq*aQAYOzqc5.png

当对Input执行转换的时候系统产生一张结果表ResultTable,当有新的数据产生的时候,系统会往Input Table插入一行数据,这会最终导致系统更新ResultTable,每一次的更新系统将更新的数据写到外围系统-Sink.

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/gXQ4djSFBXTp.png

Output定义如何将Result写出到外围系统,目前Spark支持三种输出模式:

  • Complete Mode - 整个ResultTable的数据会被写到外围系统。
  • Update Mode - 只会讲ResultTable中被更新的行,写到外围系统(spark-2.1.1+支持)
  • Append Mode - 只有新数据插入ResultTable的时候,才会将结果输出。注意:这种模式只适用于被插入结果表的数据都是只读的情况下,才可以将输出模式定义为Append(查询当中不应该出现聚合算子,当然也有特例,例如流中声明watermarker)

由于Structure Streaming计算的特点,Spark会在内存当中存储程序计算中间状态用于生产结果表的数据,Spark并不会存储Input Table的数据,一旦处理完成之后,读取的数据会被丢弃。整个聚合的过程无需用户干预(对比Storm,Storm状态管理需要将数据写到外围系统)。

故障容错

Structure Streaming通过checkpoint和write ahead log去记录每一次批处理的数据源的偏移量(区间),可以保证在失败的时候可以重复的读取数据源。其次Structure Streaming也提供了Sink的幂等写的特性(在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同),因此Structure Streaming实现**end-to-end exactly-once **语义的故障恢复。

Structure Streaming API

自Spark-2.0版本以后Dataframe/Dataset才可以处理有界数据和无界数据。Structure Streaming也是用SparkSession方式去创建Dataset/DataFrame ,同时所有Dataset/DataFrame 的操作保持和Spark SQL中Dataset/DataFrame 一致。因此我们不在针对Dataset/DataFrame 的API和SQL展开讲解-略。

Input Sources
File Source

目前支持支持text, csv, json, orc, parquet等格式的文件,当这些数据被放入到采样目录,系统会以流的形式读取采样目录下的文件.

//1.创建SparkSession
val spark=SparkSession
.builder()
.master("local[6]")
.appName("printline")
.getOrCreate()
import spark.implicits._

var df=spark.readStream
.format("text")//json/csv/parquet/orc 等
.load("file:///D:/results/text")

//2 lisi true 28
var userDF=df.as[String].map(line=>line.split("\\s+"))
.map(tokens=>(tokens(0).toInt,tokens(1),tokens(2).toBoolean,tokens(3).toInt))
.toDF("id","name","sex","age")

val query = userDF.writeStream.format("console")
.outputMode(OutputMode.Append())
.start()

query.awaitTermination()
Socket source(debug)
//1.构建SparkSession
    val spark=SparkSession.builder()
      .appName("wordcount")
      .master("local[6]")
      .getOrCreate()

    import spark.implicits._

    //2.创建输入流-readStream   DynamicTable
    var lines= spark.readStream
      .format("socket")
      .option("host","CentOS")
      .option("port",9999)
      .load()

    //3.对dataframe实现转换 - ResultTable
    var wordCounts = lines.as[String]
         .flatMap(line=>line.split("\\s+"))
       //  .groupBy("value").count()

    //4.构建query 输出
    val query = wordCounts.writeStream
      .format("console")
      .outputMode(OutputMode.Append())//有状态持续计算 Complete| Update
      .start()

    //5.等待流结束
    query.awaitTermination()
  }
<
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值