Spark每日半小时(29)——结构化流式编程:编程模型

编程模型

结构化流中的关键思想是将实时数据流视为连续追加的表。这导致新的流处理模型非常类似于批处理模型。我们将流式计算表示为静态表上的标准处理查询,Spark将其作为无界输入表上的增量查询运行。接下来我们更详细的去了解这个模型。

基本概念

将输入数据流视为“输入表”。到达流的每个数据项都像一个新行被附加到输入表。

æµä½ä¸ºè¡¨

对输入的查询将生成“结果表”。每个出发间隔(例如,每1秒),新行将附加到输入表,最终更新结果表。每当结果表更新时,我们都希望将更改的结果行写入外部接收器。

模å

“输出”定义为写入外部存储器的内容。输出可以以不同的模式定义:

  • 完整模式:整个更新的结果表将写入外部存储器。有存储连接器决定如何处理整个表的写入。
  • 追加模式:自上次出发后,只有结果表中附加的新行才会写入外部存储器。这仅适用于预计结果表中的现有行不会更改的查询。
  • 更新模式:只有自上次出发后在结果表中更新的行才会写入外部存储(自Spark 2.1.1起可用)。注意,这与完整模式的不同之处在于此模式仅输出自上次触发后已更改的行。如果查询不包含聚合,则它将等同于追加模式。

注意,每种模式适用于某些类型的查询,下来将对此进行详细讨论。

为了说明此模型的使用,让我们在之前的示例中理解模型吧。第一个DataFrame lines是输入表,最终DataFrame wordCounts是结果表。需要注意的是在流媒体的查询lines数据帧生成wordCounts是完全一样的,因为他是一个静态的数据帧。但是,当启动此查询时,Spark将不断检查套接字连接中的新数据。如果有新数据,Spark将运行“增量”查询,该查询将先前运行的计数与新数据相结合,以计算更新的计数,如下所示:

模å

注意,Structured Streaming不会实现整个表。它从流数据源读取最新的可用数据,逐步处理以更新结果,然后丢弃源数据。它仅保留更新结果所需的最小中间状态数据(例如,前面示例中的中间计数)。

该模型与许多其他流处理引擎明显不同。许多流系统要求用户自己维护运行聚合,因此必须推断容错和数据一致性(至少一次,或至多一次,或完全一次)。在此模型中,Spark负责在有新数据时更新结果表,从而减轻用户对其的判断。作为一个示例,让我们看看这个模型如何处理基于事件事件的处理和迟到的数据。

处理事件时间和后期数据

时间时间时嵌入数据本身的时间。对于许多应用程序,我们可能希望在此时间时间运行。例如,如果我们想每分钟获取IoT设备生成的事件数,那么我们可能希望使用生成数据的时间(即数据中的事件事件),而不是Spark接收它们的事件。此事件事件在此模型中非常自然的表达了-来自设备的每个事件都是表中的一行,事件时间是行中的列值。这允许基于窗口的聚合(例如,每分钟的事件数)在事件时间列上只是一种特殊类型的分组和聚合-每个时间窗口是一个组,每行可以属于多个窗口/组。

此外,该模型自然地处理基于其事件时间到达地时间晚于预期的数据。由于Spark正在更新结果表,因此它可以在存在延迟数据时完全控制更新旧聚合,以及清理旧聚合以限制中间状态数据的大小。从Spark2.1开始,Spark支持水印,允许用户指定后期数据的阈值,并允许引擎相应地清理就状态。

容错语义

提供端到端地一次性语义是结构化流地涉及背后地关键目标之一。为实现这一目标,Spark设计了结构化流媒体源,接收器和执行引擎,以可靠地跟踪处理地确切进度,以便通过重新启动 and/or 重新处理来处理任何类型的故障。假设每个流源都具有偏移(类似于Kafka偏移或Kinesis序列号)以跟踪流中的读取位置。引擎使用检查点和欲写日志来记录每个触发器中正在处理的数据的偏移范围。流式接收器涉及为处理重新处理的幂等功能。结合使用可重放的源和幂等接收器,结构化流可以确保端到端的一次性语义的任何容错。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值