Structured Streaming 之窗口事件时间聚合操作

Spark StreamingExactly Once 指的是:

  • 每条数据从输入源传递到 Spark 应用程序 Exactly Once
  • 每条数据只会分到 Exactly Once batch 处理
  • 输出端文件系统保证幂等关系

Structured Streaming 返回的是 DataFrame/DataSet,我们可以对其应用各种操作 - 从无类型,类似 SQL 的操作(例如 selectwheregroupBy)到类型化的 RDD 类操作(例如 mapfilterflatMap)。

基本操作:选择,投影,聚合

case class DeviceData(device: String, deviceType: String,
signal: Double, time: DateTime) val df: DataFrame = ... // streaming DataFrame with IOT device data with schema { device: string, deviceType: string, signal: double, time: string }
val ds: Dataset[DeviceData] = df.as[DeviceData] // streaming Dataset with IOT device data // Select the devices which have signal more than 10
df.select("device").where("signal > 10") // using untyped APIs
ds.filter(_.signal > 10).map(_.device) // using typed APIs // Running count of the number of updates for each device type
df.groupBy("deviceType").count() // using untyped API // Running average signal for each device type
import org.apache.spark.sql.expressions.scalalang.typed
ds.groupByKey(_.deviceType).agg(typed.avg(_.signal)) // using typed API

不支持的操作:

但是,不是所有适用于静态 DataFrames/DataSet 的操作在流式 DataFrames/DataSet 中受支持。从 Spark 2.0 开始,一些不受支持的操作如下:

  • 在流 DataFrame/DataSet 上还不支持多个流聚集(即,流 DF 上的聚合链)。
  • 不支持 limittake(N)
  • 不支持 Distinct
  • sort 操作仅在聚合后在完整输出模式下支持
  • 流和静态流的外连接支持是有条件的:
    • 不支持带有流 DataSet 的完全外连接
    • 不支持右侧的流的左外连接
    • 不支持左侧的流的右外部联接
  • 不支持两个流之间的任何 join
  • 此外,还有一些方法不能用于流DataSet,它们是将立即运行查询并返回结果的操作,这对流DataSet没有意义。相反,这些功能可以通过显式地启动流查询来完成。
  • count() - 无法从流 DataSet 返回单个计数。
    相反,使用 ds.groupBy.count() 返回包含运行计数的流DataSet
  • foreach() - 使用 ds.writeStream.foreach(...)(参见下一节)。
  • show() - 而是使用控制台接收器

如果您尝试任何这些操作,您将看到一个 AnalysisException 如“操作 XYZ 不支持与流 DataFrames/DataSet”。

事件时间上的窗口操作

事件时间是嵌入在数据本身的时间,对于许多应用程序,我们可能希望根据事件时间进行聚合操作,为此,Spark2.x 提供了基于滑动窗口的事件时间集合操作。基于分组的聚合操作和基于窗口的聚合操作是非常相似的,在分组聚合中,依据用户指定的分组列中的每个唯一值维护聚合值,在基于窗口的聚合的情况下,对于行的事件时间落入的每个窗口维持聚合值。

structured-streaming-window
import spark.implicits._

val words = ... // streaming DataFrame of schema { timestamp: Timestamp, word: String }

// Group the data by window and word and compute the count of each group
val windowedCounts = words.groupBy(
window($"timestamp", "10 minutes", "5 minutes"),
$"word"
).count()

该段代码用于用于统计每10分钟内,接受到的不同词的个数,其中window($"timestamp", "10 minutes", "5 minutes")的含义为:假设初始时间 t=12:00,定义时间窗口为10分钟,每5分钟窗口滑动一次,也就是每5分钟对大小为10分钟的时间窗口进行一次聚合操作,并且聚合操作完成后,窗口向前滑动5分钟,产生新的窗口,如上图的一些列窗口 12:00-12:10,12:05-12:15,12:10-12:20。

在这里每个word包含两个时间,word产生的时间和流接收到word的时间,这里的timestamp就是word产生的时间,在很多情况下,word产生后,可能会延迟很久才被流接收,为了处理这种情况,Structured Streaming 引进了Watermarking(时间水印)功能,以保证能正确的对流的聚合结构进行更新

structured-streaming-late-data

Watermarking的计算方法Watermarking

  • In every trigger, while aggregate the data, we also scan for the max value of event time in the trigger data
  • After trigger completes, compute watermark = MAX(event time before trigger, max event time in trigger)

Watermarking表示多长时间以前的数据将不再更新,也就是说每次窗口滑动之前会进行Watermarking的计算,首先统计这次聚合操作返回的最大事件时间,然后减去所然忍受的延迟时间就是Watermarking,当一组数据或新接收的数据事件时间小于Watermarking时,则该数据不会更新,在内存中就不会维护该组数据的状态

mw1

Structured Streaming 支持两种更新模式:

  1. Update 删除不再更新的时间窗口,每次触发聚合操作时,输出更新的窗口
structured-streaming-watermark-update-mode

2. Append 当确定不会更新窗口时,将会输出该窗口的数据并删除,保证每个窗口的数据只会输出一次

structured-streaming-watermark-append-mode

3. Complete 不删除任何数据,在 Result Table 中保留所有数据,每次触发操作输出所有窗口数据

Structured-Streaming之窗口操作的更多相关文章

  1. Spark Structured Streaming框架(4)之窗口管理详解

    1. 结构 1.1 概述 Structured Streaming组件滑动窗口功能由三个参数决定其功能:窗口时间.滑动步长和触发时间. 窗口时间:是指确定数据操作的长度: 滑动步长:是指窗口每次向前移 ...

  2. Spark2.3(三十四):Spark Structured Streaming之withWaterMark和windows窗口是否可以实现最近一小时统计

    WaterMark除了可以限定来迟数据范围,是否可以实现最近一小时统计? WaterMark目的用来限定参数计算数据的范围:比如当前计算数据内max timestamp是12::00,waterMar ...

  3. streaming窗口操作

    之前一直对窗口操作不太理解.认为spark streaming本身已经是分片计算,还需要窗口操作干啥. 窗口操作最为简单易懂的场景就是,在M时间间隔计算一次N时间内的热搜.当M=N的时候,就像上述所说 ...

  4. Structured Streaming Programming Guide结构化流编程指南

    目录 Overview Quick Example Programming Model Basic Concepts Handling Event-time and Late Data Fault T ...

  5. DataFlow编程模型与Spark Structured streaming

    流式(streaming)和批量( batch):流式数据,实际上更准确的说法应该是unbounded data(processing),也就是无边界的连续的数据的处理:对应的批量计算,更准确的说法是 ...

  6. Structured streaming

    Structured streaming是spark 2.0以后新增的用于实时处理的技术.与spark streaming不同的是,Structured streaming打开了数据源到数据落地之间的 ...

  7. Structured Streaming编程向导

    简介 Structured Streaming is a scalable and fault-tolerant stream processing engine built on the Spark ...

  8. Apache Spark 2.2.0 中文文档 - Structured Streaming 编程指南 | ApacheCN

    Structured Streaming 编程指南 概述 快速示例 Programming Model (编程模型) 基本概念 处理 Event-time 和延迟数据 容错语义 API 使用 Data ...

  9. Spark之Structured Streaming

    目录 Part V. Streaming Stream Processing Fundamentals Structured Streaming Basics Event-Time and State ...

随机推荐

  1. hdu1556 Color the ball 简单线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1556 简单的线段树的应用 直接贴代码了: 代码: #include<iostream> # ...

  2. Java线程安全 关于原子性与volatile的试验

    1. 变量递增试验 static /*volatile*/ int shared=0;//volatile也无法保证++操作的原子性 static synchronized int incrShare ...

  3. 0基础搭建Hadoop大数据处理-编程

    Hadoop的编程可以是在Linux环境或Winows环境中,在此以Windows环境为示例,以Eclipse工具为主(也可以用IDEA).网上也有很多开发的文章,在此也参考他们的内容只作简单的介绍和 ...

  4. Day4-生成器generator

    列表生成式 需求:列表[0,1,2,3,4,5,6,7,8,9]每个值加1,如何实现? 方法1:列表追加 >>> a = [0,1,2,3,4,5,6,7,8,9] >> ...

  5. 新鲜小玩意儿- deviceOrientation移动设备旋转事件

    <javascript高级程序设计>第三版 其中事件的章节 提到一个有意思的事件 deviceOrientation 也就是 设备(device) - orientation(方向) 贴代 ...

  6. 16、Collection接口及其子接口Set和List(常用类LinkedList,ArrayList,Vector和Stack)

    16.Collection接口 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些Collection允许相同 ...

  7. AjaxPro.AjaxMethod 简单应用,

    用AjaxPro无刷新实现站内信息实时提示功能,用AjaxPro.2.dll实现表数据绑定和无刷新分页 首先,必不可少的就是dll-----AjaxPro.2 下载地址:http://down7.pc ...

  8. c语言项目开发流程二部曲

    一.在第一部曲中我们介绍了电子词典项目开发的前5步,下面继续我们的步伐. 6.函数接口设计,这一步不是一蹴而就的,在项目进行中得不断修改,下面是我电子词典项目接口. /**************函数 ...

  9. 使用sqlserver搭建高可用双机热备的Quartz集群部署【附源码】

    一般拿Timer和Quartz相比较的,简直就是对Quartz的侮辱,两者的功能根本就不在一个层级上,如本篇介绍的Quartz强大的序列化机制,可以序列到 sqlserver,mysql,当然还可以在 ...

  10. ORACLE的监听日志太大,客户端无法连接

    数据库sqlplus能连接,plsql连接失败,也不报错,就定位到了是不是监听出了什么问题,删除监听,重建监听,重启监听,各种尝试都没解决问题. 却是监听日志太大导致的问题,一下是处理步骤: 查看监听 ...