Spark流式编程介绍 -编程模型

本文深入解析Spark结构化流处理模型,阐述其如何通过不断增长的表概念处理实时数据流,实现增量查询。探讨基本概念,如写入表、结果表及三种输出模式:完全模式、增量模式和更新模式。并分析事件时间、延迟数据处理和容错性的关键特性。

来源Spark官方文档
http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#programming-model

编程模型

结构化流中的核心概念就是将活动数据流当作一个会不断增长的表。这是一个新的流处理模型,但是与批处理模型很相似。你在做流式计算就像是标准针对静态表的批查询,Spark会在一个无限输入的表上进行增量查询。我们来从更多详细内容来理解这个模型。

基本概念

将输入的数据流理解为“写入表”,每个流中到达的数据就像是写入表中新增的一行。
Stream as a Table
针对输入的查询会生成“结果表”。每个触发间隔之间(比如1秒钟),就会有新的行添加到“写入表”,最终更新结果表。当结果表变更后,我们能够将变更的结果行写入外部存储。
Model
“输出(Output)”定义为写入外部存储的内容。输出存在几种模式:

  • 完全模式(Complete Mode) :整个更新后的结果表会全部写入外部存储。具体的全表写入方式取决于与存储的底层连接。
  • 增量模式(Append Mode) :从上次触发后的新增结果表数据才会写入外部存储。这个模式只适用于那些预期结果表中的存量数据不会变化的查询。
  • 更新模式(Update Mode) : 从上次触发后的更新结果表数据才会写入外部存储(从Spark 2.1.1开始生效)。注意本模式和完全模式的差异,本模式下只会输出上次触发后的变更行。如果查询不包含聚合,基本会和增量模式相同。

要注意每个模式都有确定的适配的查询,这个会在稍后讨论。
为了解释这个模型的使用方式,我们用上面的快速示例来辅助理解模型。第一个DataFrame类型的变量 line 就是写入表,而最后DataFrame类型的变量 wordCounts 就是结果表。注意针对流的查询方法,从 line 生成 wordCounts 和一个静态的DataFrame完全相同。当查询开始之后,Spark会持续检查从socket链接传入的新数据。如果存在新数据,Spark会运行“增量”查询,并且针对新数据计算更新的计数,整合之前运行的计数,如下图所示。
Model
注意结构化流并没有存储整张表。从数据源读取最近有效的数据,增量的处理并且更新结果数据,然后丢弃源数据。Spark只保留最小中间状态数据,用于更新结果(例如上面例子中的中间统计结果计数)。
这个模型明显和其他的流处理引擎不同。许多流处理系统要求用户自行维护运行聚合,因为有诸如容错性(fault-tolerance)、数据一致性(data consistency:at-least-once, at-most-once, exactly-once)。在这个模型中,当有新数据时,由Spark负责更新结果表,因此解放了用户无需关注。我们以模型处理事件时间和延迟数据作为例子来看下。

处理事件时间和延迟数据

事件时间是包含在数据本身的。很多应用都希望基于事件时间操作。例如你的想要获取物联网设备每分钟产生事件数量,然后你可能希望使用数据生成的时间(这就是事件时间),而不是Spark接收到他们的时间。事件时间在这个模型中是很自然的,因为每个设备产生事件都是都是表中的一行数据,而事件时间就是一行数据中的一列。这样基于窗口的聚合(例如每分钟的事件数量)可以作为基于事件时间列做的特别的分组和聚合。每个时间窗口都是一个分组,每行数据也可以属于多个窗口或分组。因此类似这种基于事件时间的聚合查询能够在静态数据集(例如收集的设备事件日志)和动态数据流,能够是用户的使用比较简单。
此外模型天然的能够基于事件时间处理延迟到达的数据。当Spark更新结果表时,他仍然能够针对延迟数据来更新历史聚合的结果,也同时可以清除历史聚合数据,从而限制中间状态数据的大小。从Spark2.1开始,我们支持水位线概念(watermarking),允许用户指定延迟数据的阈值,系统也能够清理旧状态数据。稍后会在窗口操作章节介绍。

容错性

保证唯一投送端到端是结构化流的设计中的关键目标之一。为了达成这样的目标,我们设计了结构化流的源(Source)、汇(Sink)以及执行引擎能够可靠的跟踪处理进度,从而能够重启/重新处理来应对各种故障。每个数据流的源应该都有偏移量概念(类似Kafka的偏移量,或者Amazon Kinesis 的序列编号)来跟踪流中的读取位置。引擎使用保存点和先写日志来记录每次处理的数据偏移边界。流的汇设计天然就支持重新处理的幂等性。整合起来,使用可重放的源与幂等的汇,结构化流在面对任何故障时都能保证端对端严格一致性(end-to-end exactly-once semantics)

流式编程是一种在大数据处理中广泛使用的编程范式,尤其适用于实时数据处理和分析。它允许开发者以声明式的方式处理数据集合,简化了并行和异步操作的实现。以下是一些流式编程中常用的框架和技术: ### Apache Kafka Streams Kafka Streams 是 Apache Kafka 提供的一个客户端库,用于构建实时流处理应用程序。它可以轻松地将 Kafka 作为数据源,并对数据进行实时转换和分析。Kafka Streams 支持状态管理和窗口化操作,非常适合用于构建高吞吐量、低延迟的流处理应用。[^1] ### Apache Flink Apache Flink 是一个分布式流处理框架,支持有状态的计算,并能够处理无界和有界数据流。Flink 提供了低延迟、高吞吐量的流处理能力,并支持事件时间处理和状态一致性保证。Flink 的 API 支持 Java 和 Scala,同时也提供了 SQL 接口用于流处理。[^1] ### Apache Spark Streaming Spark Streaming 是 Apache Spark 的一个扩展模块,用于构建可扩展的流处理应用。它基于微批处理模型,将数据流分割成小批次进行处理。Spark Streaming 支持多种数据源,如 Kafka、Flume、HDFS 等,并且可以与 Spark 的其他模块(如机器学习库 MLlib 和图计算库 GraphX)无缝集成。[^1] ### Akka Streams Akka Streams 是基于 Akka Actor 模型构建的流处理库,提供了一种声明式的方式来处理数据流。它支持背压机制,确保生产者和消费者之间的数据流平衡,避免内存溢出问题。Akka Streams 可以与 Akka HTTP 等模块结合使用,构建高性能的流式 Web 应用。 ### Java Stream API Java Stream API 是 Java 8 引入的一个新特性,用于简化集合数据的处理。它允许开发者使用声明式语法(如 filter、map、reduce 等操作)对集合进行操作。Java Stream API 主要用于处理内存中的数据集,并且支持并行处理以提高性能。[^2] ### RxJava RxJava 是一个基于观察者模式的异步编程库,支持流式处理。它提供了一套丰富的操作符,可以方便地进行数据转换、过滤和组合。RxJava 支持背压和错误处理机制,非常适合用于构建响应式应用程序。 ### Spring Cloud Stream Spring Cloud Stream 是 Spring 生态系统的一部分,提供了一个用于构建消息驱动微服务的框架。它抽象了底层消息中间件(如 Kafka 和 RabbitMQ),使得开发者可以专注于业务逻辑的实现。Spring Cloud Stream 支持动态缩放和分区,非常适合用于构建弹性流处理应用。 ### 示例代码:使用 Java Stream API 进行简单流处理 ```java import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StreamExample { public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve"); // 使用 Stream API 过滤并转换数据 List<String> filteredNames = names.stream() .filter(name -> name.length() > 3) .map(String::toUpperCase) .collect(Collectors.toList()); System.out.println(filteredNames); // 输出: [ALICE, CHARLIE, DAVID] } } ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值