Spark SQL架构及高级用法

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: Spark SQL基于Catalyst优化器与Tungsten引擎,提供高效的数据处理能力。其架构涵盖SQL解析、逻辑计划优化、物理计划生成及分布式执行,支持复杂数据类型、窗口函数与多样化聚合操作,结合自适应查询与代码生成技术,实现高性能大数据分析。

Spark SQL 架构概述

架构核心组件

  • API层(用户接口)

    • 输入方式:SQL查询;DataFrame/Dataset API。
    • 统一性: 所有接口最终转换为逻辑计划树(Logical Plan),进入优化流程。
  • 编译器层(Catalyst 优化器)

    • 核心引擎: 基于规则的优化器(Rule-Based Optimizer, RBO)与成本优化器(Cost-Based Optimizer, CBO)。

    • 处理流程:

      | 阶段 | 输入 | 输出 | 关键动作 |
      | :------- | :------------- | :----------------- | :-------------------------------------------------------- |
      | 解析 | SQL/API 操作 | 未解析逻辑计划 | 构建语法树(AST),校验语法正确性 |
      | 分析 | 未解析逻辑计划 | 解析后逻辑计划 | 绑定元数据(表/列名、数据类型)、解析函数、检查语义正确性 |
      | 优化 | 解析后逻辑计划 | 优化后逻辑计划 | 应用优化规则(如谓词下推、列剪裁、常量折叠、连接重排序) |

    • 优化规则示例:

      Predicate Pushdown(谓词下推):将过滤条件推至数据源层,减少 I/O。

      Column Pruning(列裁剪):仅读取查询涉及的列,减少数据传输。

  • 执行计划层(Planner)

    • 物理计划生成:将优化后的逻辑计划转换为物理计划(Physical Plan)

    • 策略匹配: 根据数据分布、资源情况选择最优执行策略(如 BroadcastHashJoin vs SortMergeJoin)。

    • 物理优化:

      全阶段代码生成(Whole-Stage Codegen):将多个操作合并为单个 JVM 函数,减少虚函数调用开销。

      谓词下推至数据源:支持 Parquet/ORC 等格式的过滤条件下推。

  • 执行引擎层(Tungsten + Spark Core)

    • Tungsten 引擎:

      堆外内存管理:避免 JVM GC 开销,直接操作二进制数据。

      向量化计算:按列处理数据,提升 CPU 缓存命中率。

    • 分布式执行:

      物理计划转为 RDD DAG → 分解为 Stage → 调度 TaskExecutor 并行执行。

      利用 Spark Core 的血缘(Lineage)、内存管理、Shuffle 服务。

关键性能技术

  • Catalyst 优化器
    • 动态优化: 在逻辑计划阶段应用启发式规则,减少冗余计算。
    • 自适应查询(AQE, Spark 3.0+):运行时根据 Shuffle 数据量动态调整 Join 策略、分区数。
  • Tungsten 执行引擎
    • 内存效率: 紧凑二进制格式存储数据,减少内存占用 50%+。
    • 代码生成: 将查询编译为字节码,性能接近手写代码。
  • 统一数据源接入
    • Data Source API V2: 支持扩展自定义数据源(如 Kafka、Cassandra),并实现下推优化。

Spark SQL高级语法

复杂数据类型

  • 数组 (ARRAY):同类型元素的有序集合(索引从0开始)。

    • size():数组长度。
    • explode():展开数组为多行。
    • array_contains(arr, value):检查元素是否存在。
    • transform(arr, x -> x * 2):对每个元素应用Lambda函数。
  • 映射(MAP):键值对集合(键唯一)。

    • element_at(map, key):按键取值。

    • map_keys()/map_values():获取所有键/值。

    • map_concat(map1, map2):合并两个Map。

  • 结构体 (STRUCT<field1:T1, ...>):包含多个字段的复合类型(类似JSON对象)。

高级聚合与分组

  • GROUPING SETS:自定义聚合维度组合,无关字段用NULL值填充。

    SELECT city, department, SUM(salary) AS total_salary
    FROM employees
    GROUP BY GROUPING SETS (
        (city, department), (city), ()                  
    )
    
  • ROLLUP:层级聚合

    SELECT country, province, city,COUNT(*) AS count
    FROM locations
    GROUP BY ROLLUP(country, province, city)
    -- SQL结果会显示(country, province, city)、(country, province)、(country)、()的聚合结果
    
  • CUBE:所有维度聚合

    SELECT year, product, SUM(revenue) 
    FROM sales
    GROUP BY CUBE(year, product)
    -- SQL结果会显示(year, profucr)、(year)、(product)、()的聚合结果
    
  • 聚合过滤(FILTER 子句):对特定条件聚合 (比WHERE更高效)

    SELECT department,
        SUM(salary) FILTER (WHERE age > 30) AS senior_salary,
        AVG(salary) FILTER (WHERE gender = 'F') AS female_avg
    FROM employees
    GROUP BY department
    

窗口函数

  • 核心结构

    SELECT
        RANK() OVER (
            PARTITION BY dim 
            ORDER BY metric DESC
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -- 窗口范围
        ) AS rank
    FROM table
    
  • 聚合函数SUM()、AVG()、COUNT()、MAX()、MIN()

  • 排名函数
    • ROW_NUMBER():为窗口内的每一行分配一个唯一的序号,序号连续且不重复。
    • RANK():排名函数,允许有并列的名次,名次后面会出现空位。
    • ENSE_RANK():排名函数,允许有并列的名次,名次后面不会空出位置,即序号连续。
  • 分组窗口函数
    • NTILE():将窗口内的行分为指定数量的组,每组的行数尽可能相等。
  • 分布窗口函数
    • PERCENT_RANK():计算每一行的相对排名,返回一个介于0到1之间的值,表示当前行在分区中的排名百分比。
    • CUME_DIST():计算小于或等于当前行的行数占窗口总行数的比例。
  • 取值窗口函数

    • LAG():访问当前行之前的第n行数据。
    • LEAD():访问当前行之后的第n行数据。
    • FIRST_VALUE():获取窗口内第一行的值。
    • LAST_VALUE():获取窗口内最后一行的值。
    • NTH_VALUE():获取窗口内第n行的值,如果存在多行则返回第一个。
  • 窗口范围

    • UNBOUNDED PRECEDING:从分区中的第一行开始(前面所有行)。
    • CURRENT ROW:包括当前行。
    • N PRECEDING:从当前行之前的第 nN行开始。
    • N FOLLOWING:包括当前行之后第 N 行。
    • UNBOUNDED FOLLOWING:到分区中的最后一行结束(后面所有行)。

Spark SQL内置函数

  • 聚合函数 (Aggregate Functions)

    | 函数 | 返回值 | 说明 |
    | :------------------------ | :----- | :-------------------------- |
    | approx_count_distinct | Long | 近似去重计数 (rsd=相对误差) |
    | collect_list | Array | 收集值到数组 (保留重复) |
    | collect_set | Array | 收集值到集合 (去重) |
    | corr | Double | 相关系数 (-1~1) |
    | covar_pop/covar_samp | Double | 总体/样本协方差 |
    | kurtosis | Double | 峰度 |
    | skewness | Double | 偏度 |
    | percentile_approx | Double | 近似百分位数 |

  • 数组函数 (Array Functions)

    | 函数 | 说明 |
    | :--------------------------- | :--------- |
    | array(e1, e2, ...) | 转换为数组 |
    | array_contains(arr, val) | 数组包含 |
    | array_distinct | 数组去重 |
    | array_position(arr, val) | 数组索引值 |
    | size | 数组大小 |

  • Map 函数 (Map Functions)

    | 函数 | 说明 |
    | :----------------------- | :----------------- |
    | map(k1,v1, k2,v2) | 转化为map |
    | element_at(map, key) | 根据键获取值 |
    | map_keys/map_values | 获取键列表、值列表 |
    | map_entries | 获取map entry |

  • 日期时间函数 (Datetime Functions)

    | 函数 | 说明 | 示例 |
    | :-------------------- | :------- | :-------------------------------------------- |
    | date_add/date_sub | 日期加减 | date_add('2025-07-01', 7)2025-07-08 |
    | datediff | 日期差 | datediff('2025-06-01','2025-06-30')30 |
    | date_format | 格式化 | date_format(ts, 'yyyy-MM')"2025-07" |
    | trunc | 截断日期 | trunc('2025-07-01', 'MONTH')2025-07-01 |
    | window | 时间窗口 | 流处理中按时间聚合 |

  • JSON 函数 (JSON Functions)

    | 函数 | 说明 | 示例 |
    | :------------------ | :----------- | :----------------------------------------------------- |
    | get_json_object | JSON路径取值 | get_json_object('{"a":1}', '$.a')1 |
    | json_tuple | 多字段提取 | json_tuple('{"name":"Bob"}', 'name')Bob |
    | from_json | 解析为结构体 | from_json('{"id":1}', 'id INT') |
    | to_json | 结构体转JSON | to_json(struct('Tom' AS name))'{"name":"Tom"}' |
    | schema_of_json | 推断Schema | schema_of_json('[{"a":1}]')ARRAY<STRUCT<a:INT>> |

  • 字符串函数 (String Functions)

    | 函数 | 说明 | 示例 |
    | :----------------- | ---------------- | :------------------------------------------------------ |
    | concat_ws | 字符串拼接join | concat_ws('-','2025','07')"2025-07" |
    | split | 字符串解析转数组 | split('a,b,c', ',')["a","b","c"] |
    | regexp_extract | 正则表达式 | regexp_extract('id=100','id=(\\d+)',1)"100" |
    | translate | 字符串子串转化 | translate('hello','el','ip')"hippo" |
    | parse_url | 解析URL | parse_url('http://a.com?q=spark','QUERY')"q=spark" |

相关文章
|
18天前
|
SQL Kubernetes Java
Java 最新技术实操:从基础到进阶的详细指南
本文介绍了Java 17及后续版本的核心技术实操,涵盖新特性、集合框架、异常处理和多线程编程等内容。主要包括:密封类(Sealed Classes)的继承层级控制、模式匹配(Pattern Matching)简化类型判断、文本块(Text Blocks)处理多行字符串;集合框架中的工厂方法和Stream API高级操作;异常处理的最佳实践如自动资源管理(ARM)和自定义异常;多线程编程中的CompletableFuture异步编程和ReentrantLock显式锁使用。
70 7
|
1月前
|
存储 Linux 网络安全
深入浅出Docker
Docker是一种基于容器技术的开源平台,用于自动化应用的部署、扩展和管理。其核心组件包括镜像(Image)、容器(Container)和仓库(Registry)。镜像是静态只读模板,采用分层存储结构;容器是镜像的运行实例,通过Linux Namespace和Cgroups实现隔离与资源限制;仓库用于集中存储和分发镜像。Docker支持数据持久化(Volumes)、多种网络配置(如Bridge、Host、Overlay等)以及高效的操作命令,帮助企业实现快速开发、测试和部署流程。
|
1月前
|
Java 数据库连接 API
2025 更新必看:Java 编程基础入门级超级完整版指南
本教程为2025更新版Java编程基础入门指南,涵盖开发环境搭建(SDKMAN!管理JDK、VS Code配置)、Java 17+新特性(文本块、Switch表达式增强、Record类)、面向对象编程(接口默认方法、抽象类与模板方法)、集合框架深度应用(Stream API高级操作、并发集合)、模式匹配与密封类等。还包括学生成绩管理系统实战项目,涉及Maven构建、Lombok简化代码、JDBC数据库操作及JavaFX界面开发。同时提供JUnit测试、日志框架使用技巧及进阶学习资源推荐,助你掌握Java核心技术并迈向高级开发。
131 5
|
1月前
|
安全 数据挖掘 API
车辆车型大全 API 实战指南:推动交通行业智能化
车辆车型大全API由探数平台提供,旨在解决企业班车、物流运输及汽车销售等行业对标准化车型数据的需求。传统人工维护车型库效率低且易出错,而该API覆盖主流品牌与车系,包含品牌、车系、销售车型及配置参数等详细信息,适用于车队管理、电商平台及汽车资讯平台。API提供四个子接口:获取品牌、车系、销售车型与配置详情信息,支持高效查询。通过HTTP POST请求即可调用,返回结构化数据,助力企业实现智能化运营与科学决策,在绿色智能交通时代发挥重要作用。
96 4
|
27天前
|
前端开发 测试技术 API
一文掌握软件分支管理
本文详细介绍了软件分支管理的实践经验,结合具体项目案例,从版本号、分支命名、标签管理到合并策略等方面展开。通过清晰的规则和流程图示,帮助团队避免版本混乱,提升研发效率。强调主干与开发分支的核心作用,同时提醒合理控制分支数量,确保协作顺畅。适用于不同类型的项目,助力团队建立适合自身的版本管理体系。
346 69
一文掌握软件分支管理
|
6天前
|
人工智能 自然语言处理 搜索推荐
AI 搜索 MCP 最佳实践
本文介绍了如何通过 MCP 协议,快速调用阿里云 OpenSearch 、ElasticSearch 等工具,帮助企业快速集成工具链、降低开发复杂度、提升业务效率。
89 29
AI 搜索 MCP 最佳实践
|
6天前
|
数据采集 JSON API
Excel数据治理新思路:引入智能体实现自动纠错【Python+Agent】
本文介绍如何利用智能体与Python代码批量处理Excel中的脏数据,解决人工录入导致的格式混乱、逻辑错误等问题。通过构建具备数据校验、异常标记及自动修正功能的系统,将数小时的人工核查任务缩短至分钟级,大幅提升数据一致性和办公效率。
|
7天前
|
人工智能 IDE 定位技术
通义灵码 AI IDE 上线,第一时间测评体验
通义灵码 AI IDE 重磅上线,开启智能编程新纪元!无需插件,开箱即用,依托通义千问大模型,实现高效、智能的编程体验。支持 MCP 工具链,可快速调用多种服务(如12306余票查询、高德地图标注等),大幅提升开发效率。结合 Qwen3 强大的 Agent 能力,开发者可通过自然语言快速构建功能,如智能选票系统、地图可视化页面等。行间代码预测、AI 规则定制、记忆能力等功能,让 AI 更懂你的编码习惯。Lingma IDE 不仅是工具,更是开发者身边的智能助手,助力 AI 编程落地实践。立即下载体验,感受未来编程的魅力!
108 15
|
26天前
|
人工智能 安全 机器人
无代码革命:10分钟打造企业专属数据库查询AI机器人
随着数字化转型加速,企业对高效智能交互解决方案的需求日益增长。阿里云AppFlow推出的AI助手产品,借助创新网页集成技术,助力企业打造专业数据库查询助手。本文详细介绍通过三步流程将AI助手转化为数据库交互工具的核心优势与操作指南,包括全场景适配、智能渲染引擎及零代码配置等三大技术突破。同时提供Web集成与企业微信集成方案,帮助企业实现便捷部署与安全管理,提升内外部用户体验。
无代码革命:10分钟打造企业专属数据库查询AI机器人
|
25天前
|
人工智能 物联网
“一丹一世界”三等奖 |咖菲猫咪_商业海报案例分享
“一丹一世界”三等奖 |咖菲猫咪_商业海报案例分享
222 85