点一下关注吧!!!非常感谢!!持续更新!!!
🚀 AI篇持续更新中!(长期更新)
AI炼丹日志-31- 千呼万唤始出来 GPT-5 发布!"快的模型 + 深度思考模型 + 实时路由",持续打造实用AI工具指南!📐🤖
💻 Java篇正式开启!(300篇)
目前2025年09月15日更新到: Java-124 深入浅出 MySQL Seata框架详解:分布式事务的四种模式与核心架构 MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!
📊 大数据板块已完成多项干货更新(300篇):
包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈! 大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

章节内容
上节我们完成了如下的内容:
- Spark SQL JOIN
- Boardcast JOIN
- Shuffle JOIN
- SQL解析过程
- SparkSQL 常见的优化逻辑

背景概述
随着大数据技术的不断发展,人们对于大数据的实时性处理要求也不断提高,传统的MapReduce等批处理框架在某些特定领域,例如实时用户推荐、用户行为分析这些应用场景上逐渐不能满足人们对实时性的需求,因为诞生了一批如 S3、Samza、Storm、Flink等流式分析、实时计算框架。
Spark Streaming 是 Spark 核心组件之一,用于实时数据处理。它能够将实时数据流分批处理,转换为可操作的分布式数据集 (RDDs),从而实现流数据的实时处理和分析。
Spark Streaming 核心概念详解
DStream(离散流)
DStream(Discretized Stream,离散化流)是 Spark Streaming 提供的高级抽象,表示一个连续的数据流。DStream 本质上是由一系列连续的 RDD 组成,每个 RDD 包含特定时间间隔内到达的数据。这种设计使得 Spark Streaming 能够利用 Spark 核心的批处理能力来处理实时数据流。
DStream 数据来源
-
外部数据源:
- Kafka:分布式消息队列系统
- Flume:日志收集系统
- HDFS/S3:分布式文件系统中的文件
- Socket:网络套接字连接
- Twitter API:社交媒体数据流
-
内部转换:
- 通过现有的 DStream 进行转换操作(如 map、filter、reduceByKey 等)产生新的 DStream
- 通过对 RDD 序列进行转换产生
特性与优势
- 容错性:自动从故障中恢复,确保数据不丢失
- 可扩展性:可以方便地扩展到上千个节点
- 高吞吐:能够处理每秒数百万条记录
- 低延迟:可在秒级延迟内处理数据
示例代码:
scala
// 从Socket源创建DStream
val lines = ssc.socketTextStream("localhost", 9999)
// 对DStream进行转换
val words = lines.flatMap(_.split(" "))
val wordCounts = words.map(x => (x, 1)).reduceByKey(_ + _)
wordCounts.print()
Batch Interval(批处理间隔)
Batch Interval 是 Spark Streaming 中最重要的配置参数之一,它决定了数据流被划分为小批次的时间间隔长度。这个参数需要在创建 StreamingContext 时指定。
关键特征
- 处理周期:每个批次的数据会在对应的 Batch Interval 时间内被收集和处理
- 配置范围 :通常设置在 500 毫秒到几秒之间
- 常见设置:1秒、2秒、5秒、10秒
- 性能影响 :
- 较小的间隔:降低延迟但增加系统开销
- 较大的间隔:提高吞吐但增加延迟
配置建议
- 考虑数据速率:根据输入数据的速率合理设置
- 考虑应用需求:根据应用对延迟的容忍度选择
- 考虑集群资源:确保集群能够在一个 Batch Interval 内完成处理
示例配置:
scala
// 创建StreamingContext,设置批处理间隔为2秒
val ssc = new StreamingContext(sparkConf, Seconds(2))
实际应用场景
- 实时监控:设置较短的批处理间隔(如1秒)快速响应异常
- 日志分析:可以设置较长的间隔(如10秒)提高吞吐量
- 金融交易:需要平衡延迟和准确性,通常选择2-5秒
注意:Batch Interval 一旦设置,在运行过程中不能动态修改。如需改变,需要停止并重启 Streaming 应用。
架构概念
Spark Streaming 的架构主要包括如下组件:
- 输入源: Spark Streaming 支持多种输入源,如 Kafka、Flume、HDFS、S3 等。
- 处理引擎: 核心是 Spark Core 的 RDD 处理引擎,利用它来执行批处理操作。
- 输出操作: 处理后的数据可以输出到文件系统、数据库、仪表板等。
编程模型
Spark Streaming 使用与 Spark 相同的编程模型,支持常见的 Map、Reduce、Join、Window 等操作。你可以通过在 DStream 上调用这些操作来进行实时数据处理。
- Transformation: 如 map、flatMap、filter 等。
- Window Operations: Spark Streaming 提供了基于时间窗口的操作,例如窗口化计算,通过 window 和 slide 函数实现。
容错性
- 检查点机制: 为了处理故障和保证数据一致性,Spark Streaming 提供了检查点机制,可以将中间状态保存到可靠的存储系统(如 HDFS),从而在故障恢复时重建这些状态。
- 数据重放: 在 Kafka 等消息队列中,消息是基于偏移量的,这使得 Spark Streaming 可以在故障发生时重新处理未处理的消息,确保数据的可靠性和一致性。
什么是 Spark Streaming
-
Spark Streaming 类似于 Apache Storm(来一条处理一条、延迟低、响应快、吞吐量低),用于流式数据的处理。
-
Spark Streaming 具有高吞吐量和容错能力强的特点。
-
Spark Streaming 支持的数据输入源很多,例如:Kafka(最重要的数据源)、Flume、TCP套接字等。
-
数据输入后可用高度抽象API:map reduce join window等进行运算
-
处理结果可存 HDFS、数据库等
-
Spark Streaming 可以与 MLib、GraphX融合
Spark Streaming 与 Spark 基于RDD的概念比较类似,Spark Streaming 使用离散化流(Discretized Stream)作为抽象表示,成为 DStream。 DStream是随着时间推移而收到的数据的序列,在内部,每个时间区间收到的数据都作为RDD存在,DStream是由这些RDD所组成的序列。
DStream 可以从各种输入源创建,比如 Flume、Kafka或者HDFS,创建出来的DStream支持两种操作:
- 转化操作,会生成一个新的DStream
- 输出操作(output operation),把数据写入外部系统中
DStream 提供了许多与RDD所支持的操作相类似的操作支持,还增加了与时间相关的的新操作,比如滑动窗口。
Spark Streaming 架构
Spark Streaming 使用 mini-batch 架构,把流式计算当作一系列连续的小规模批处理来对待。 Spark Streaming 从各种输入源中读取数据,并把数据分组小批次,新的批次按均匀的时间间隔创建出来。 在每个时间区间开始的时候,一个新的批次就创建出来,在该区间内收到的数据都会被添加到这个批次中,在时间区间结束时,批次停止增长。
时间区间的大小是由批次间隔这个参数决定的,批次间隔一般设置在500ms到几秒之间,由开发者配置。 每个输入批次都形成一个RDD,以Spark作业的方式处理并生成其他的RDD,处理的结果可以批处理的方式传给外部的系统。
Spark Streaming的编程抽象是离散化流,也就是DStream。它是一个RDD序列,每个RDD代表数据流中的一个时间片内的编程。

应用于DStream上的转换操作都会转换为底层RDD上的操作。如对行DStream中的每个RDD应用FlatMap操作以生成单词DStream的RDD。

这些底层RDD转换是Spark引擎完成的,DStream操作隐藏了大部分的细节,为开发人员提供了更高级的API以方便使用。
Spark Streaming为每个输入源启动对应的接收器,接收器运行在Executor中,从输入源收集数据并保存为RDD。 默认情况下接收到数据后会复制到另一个Executor中,进行容错。 Driver中的 StreamingContext 会周期性的运行 Spark作业来处理这些数据。
Spark Streaming运行流程
- 客户端提交Spark Streaming作业后启动Driver,Driver启动Receiver,Receiver接收数据源的数据
- 每个作业包含多个Executor,每个Executor以线程的方式运行Task,Spark Streaming至少包含一个Receive Task(一般情况下)
- Receive接收数据后生成Block,并把BlockId汇报给Driver,然后备份到另一个Executor上
- ReceiveTracker维护Receiver汇报的BlockId
- Driver定时启动JobGenerator,根据DStream的关系生成逻辑RDD,然后创建JobSet,交给JobScheduler。
- JobScheduler 负责调度JobSet,交给DAGScheduler,DAGScheduler根据逻辑RDD,生成Stages,每个Stage包含一到多个Task,将Task提交给TaskScheduler。
- TaskScheduler负责把Task调度到Executor上,并维护Task的运行状态
Spark Streaming 优缺点
与传统流式框架相比,Spark Streaming 最大的不同点在与它对待数据是粗粒度的处理方式,即一次处理一小批数据,而其他框架往往采用细粒度的处理模式,即依次处理一条数据,Spark Streaming这样的设计实现既为其带来了显而易见的优点,又引入了不少不可避免的缺点。
优点概括
- Spark Streaming 内部的实现和调度方式高度依赖Spark的DAG调度器和RDD,这就决定了Spark Streaming的设计初衷必须是粗粒度的方式的。同时,由于Spark内部调度器足够快速和高效,可以快速地处理小批量数据,这就获得准实时的特性
- Spark Streaming 的粗粒度执行方式使其确保 "处理且仅处理一次"的特性(EOS),同时也可以更方便地实现容错恢复机制
- 由于Spark Streaming的DStream本质上RDD在流式数据上的抽象,因为基于RDD的各种操作也有相应的基本DStream的版本,这样就大大降低了用户对于新框架的学习成本,在了解Spark的情况下用户将很容易使用Spark Streaming。
- 由于 DStream 是在RDD上的抽象,那么也就更容易与RDD进行交互操作,在需要将流式数据和批处理数据结合进行分析的情况下,将会变得方便。
缺点概括
- Spark Streaming 的粗粒度处理方式也造成了不可避免的延迟,在细粒度处理方式下,理想情况下每一条记录都会被实时处理,而在Spark Streaming中,数据需要汇总到一定量都再一次性处理,这么增加了数据处理的延迟,这种延迟是由框架设计引入的,并不是由网络或其他情况造成的。
Structured Streaming
Spark Streaming 计算逻辑是把数据按时间划分为DStream,存在以下问题:
- 框架自身只能根据BatchTime单元进行数据处理,很难处理基于EventTime(即时间戳)的数据,很难处理延迟,乱序的数据
- 流式和批量处理的API不完全一致,两种使用场景中,程序代码还是需要一定的转换
- 端到端的数据容错保障逻辑需要用户自己构建,难以处理增量更新和持久化存储等一致性问题
基于以上问题,提出了下一代 Structure Streaming。将数据源映射为一张无界长度的表,通过表的计算,输出结果映射为另一张表。 以结构化的方式去操作流式数据,简化了实时计算过程,同时还复用Catalyst引擎来优化SQL操作,此外还能支持增量计算和基于EventTime的计算。
与 Kafka 集成
Kafka 是 Spark Streaming 最常用的消息队列之一。通过 Kafka 与 Spark Streaming 的紧密集成,可以实现高吞吐量、低延迟的流数据处理。
- Direct Approach: 直接从 Kafka 读取数据,不需要中间的 Receiver,确保了精确一次的语义。
- Offset 管理: 可以手动管理 Kafka 的偏移量,保证在出错时可以继续处理上次未处理的消息。
应用场景
- 实时监控: 使用 Spark Streaming 可以实现系统和应用程序的实时监控与报警系统。
- 日志处理: 处理实时生成的日志数据,进行在线分析和异常检测。
- 金融分析: 用于实时处理股票交易、风险评估等金融数据。 -社交媒体分析: 实时分析社交媒体数据,监测舆情和用户行为。
性能调优
- 并行度: 通过增加并行度来提高吞吐量。
- 内存管理: 需要合理设置内存参数,防止 OOM 错误。
- 反压机制: Spark Streaming 提供了背压机制,可以动态调整数据处理速率,防止系统过载。