2. Spark核心概念速览:RDD、DataFrame、Dataset、SparkSession、DAG调度、宽窄依赖
在深入贷后预警实时计算之前,必须建立对Spark核心抽象的统一认知。本章以“速览”方式梳理六大核心概念,后续章节将在此基础上展开具体实现。
2.1 三大数据抽象:RDD、DataFrame、Dataset
Spark提供了三种主要的数据抽象,分别面向不同的使用场景和性能需求。理解它们的演进关系与适用边界,是正确选择API的前提。
| 特性 | RDD (Resilient Distributed Dataset) | DataFrame | Dataset |
|---|---|---|---|
| 引入版本 | Spark 1.0 | Spark 1.3 | Spark 1.6 |
| 数据表示 | Java/Scala对象,无Schema | Row对象,带Schema(列名+类型) | 强类型JVM对象,带Schema |
| 类型安全 | 编译时安全 | 运行时检查 | 编译时安全 |
| 性能优化 | 依赖开发者手动优化 | Catalyst优化器 + Tungsten执行 | Catalyst优化器 + Tungsten执行 |
| 适用场景 | 底层转换、非结构化数据 | SQL分析、数据集成、快速开发 | 需要类型安全 + 性能的复杂ETL |
| 贷后预警场景 | 自定义分区逻辑、原始日志解析 | 预警规则SQL、指标聚合 | 预警策略实体建模 |
选型建议:在贷后预警实时计算中,优先使用DataFrame进行SQL化规则计算;当需要封装预警策略为强类型对象(如
WarningRule、RiskEvent)时,使用Dataset;仅在需要自定义分区器或处理非结构化日志时回退到RDD。
2.2 SparkSession:统一入口
SparkSession是Spark 2.0引入的统一编程入口,替代了旧的SparkContext、SQLContext、HiveContext。在贷后预警应用中,所有操作都从SparkSession开始。
// 创建SparkSession(贷后预警实时任务典型配置)
val spark = SparkSession.builder()
.appName("PostLoanWarningRealTime")
.config("spark.sql.shuffle.partitions", "8") // 控制并行度
.config("spark.streaming.backpressure.enabled", "true") // 背压
.getOrCreate()
// 读取Kafka数据流(DataFrame API)
val kafkaDF = spark.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "node1:9092,node2:9092")
.option("subscribe", "post_loan_events")
.load()
关键点:SparkSession内部封装了SparkContext(负责集群通信与资源调度)、SQLContext(负责SQL解析与优化)以及StreamingContext(负责流式处理上下文)。在结构化流(Structured Streaming)中,无需显式创建StreamingContext,SparkSession即可管理流作业。
2.3 DAG调度与宽窄依赖
DAG(有向无环图)调度是Spark的核心执行机制。理解DAG如何划分Stage、宽窄依赖如何影响数据Shuffle,是调优实时计算性能的基础。
2.3.1 宽依赖 vs 窄依赖
| 对比维度 | 窄依赖 (Narrow Dependency) | 宽依赖 (Wide Dependency) |
|---|---|---|
| 父RDD分区与子RDD分区关系 | 一个父分区最多被子分区使用一次 | 一个父分区被子分区多次使用(多对多) |
| 是否触发Shuffle | 否,数据在同一个节点流水线执行 | 是,需要跨节点重新分区 |
| 典型算子 | map、filter、union、mapPartitions |
groupByKey、reduceByKey、join(非广播)、repartition |
| 容错恢复代价 | 低,只需重新计算丢失分区的父分区 | 高,需要重新计算所有父分区 |
| 贷后预警影响 | 适合过滤、转换等预处理 | 预警规则中的分组聚合、跨客户关联查询 |
2.3.2 DAG调度流程
Spark DAG调度器将用户代码转换为物理执行计划,核心步骤为:
- 构建逻辑DAG:根据RDD/DataFrame的依赖关系生成有向无环图。
- 划分Stage:从DAG末端反向遍历,遇到宽依赖(Shuffle)时切分Stage。
- 提交Task:每个Stage内部生成多个Task,由TaskScheduler分发到Executor执行。
- 流水线执行:同一Stage内的窄依赖算子在一个Task内连续执行,避免中间结果落盘。
2.4 核心概念在贷后预警中的映射
将上述概念映射到贷后预警实时计算场景,可以更直观地理解每个抽象的实际作用:
- SparkSession:负责连接Kafka数据源、定义预警规则UDF、启动流式计算。
- DataFrame:承载Kafka中的JSON事件,使用SQL表达“逾期天数 > 30 且 客户等级为高风险”等规则。
- Dataset<WarningRule>:将预警规则解析为强类型对象,利用Encoder提升序列化性能。
- DAG调度:将“读取→解析→过滤→聚合→输出”转换为Stage,Shuffle发生在按客户ID分组聚合时。
- 宽窄依赖:窄依赖用于事件过滤、字段转换;宽依赖用于跨分区统计(如计算客户历史逾期次数)。
常见误区:不要认为RDD已被淘汰。在贷后预警中,当需要自定义数据分区策略(如按客户ID哈希分区到指定Executor)或处理二进制协议数据时,RDD仍然是唯一选择。DataFrame/Dataset在底层最终也会编译为RDD操作。
2.5 概念关系总览
2.6 本章小结
- RDD是底层抽象,提供细粒度控制;DataFrame是结构化数据首选,享受Catalyst优化;Dataset兼顾类型安全与性能。
- SparkSession统一了所有上下文,是贷后预警应用的唯一入口。
- DAG调度将作业划分为Stage,宽依赖触发Shuffle并切分Stage,窄依赖支持流水线执行。
- 在贷后预警实时计算中,合理利用窄依赖减少Shuffle,优先使用DataFrame API编写预警规则,是保证低延迟的关键。