当前位置: 首页 > news >正文

Spark源码中的AQS思想

1. AQS 是什么?

​AQS 核心是一个 ​​“状态变量(state)” + 一个 “FIFO 双向线程等待队列”​​。

工作流程简述:​

  1. 线程调用 acquire(1)尝试获取资源。

  2. AQS 调用子类重写的 tryAcquire(1)方法。

  3. 如果成功(通常是通过 CAS 将 state0改为 1),则线程继续执行。

  4. 如果失败,AQS 会将当前线程包装成一个 Node,​​CAS 操作插入到等待队列的尾部​​,然后线程可能会被挂起(LockSupport.park())。

  5. 当持有资源的线程释放时(调用 release(1)),它会调用 tryRelease(1),成功后,AQS 会负责​​唤醒队列中下一个等待的线程​​。

    可能读完上面的仍然不知道AQS具体用来作什么的,这里重点标记一下。 ​​AQS 是“通过一个状态变量和一個等待队列来构建同步器”的核心架构思想。

在 Spark 的核心源码中,不会直接找到​​一个 extends AbstractQueuedSynchronizer的类。这是因为 Spark 主要使用 Scala 编写,且作为一个分布式计算框架,其核心的同步问题(如任务调度、资源协调)是跨网络的,需要通过其他方式(如 RPC 消息、主从架构)来解决,而不是依赖于单机 JVM 内的锁机制。

然而,这​​绝不意味着​​ AQS 的思想与 Spark 无关。恰恰相反,​​AQS 所代表的“状态管理 + CAS + 队列同步”的核心思想,是 Spark 乃至所有高性能并发框架的基石​​。Spark 在解决单个 JVM 内的并发问题时,大量运用了与 AQS 完全一致的并发编程模式。

AQS 的核心理念在 Spark 中主要体现在以下两个层面:


层面一:JVM 内部的并发控制(直接应用AQS理念)

Spark 在 Driver 和 Executor 进程内部,需要管理多线程并发访问共享资源。在这里,你随处可见 AQS 思想的“影子”,但它们通常使用更底层的工具或更轻量的实现。

  1. volatile变量 + CAS 操作(AQS 的基石)​

    • state的等价物​​:Spark 中有大量用作状态标志的 volatile变量。

      • ​例如​​:org.apache.spark.SparkContext中的 @volatile private var stopped: Boolean。它相当于一个简单的“锁状态”,通知所有线程该上下文是否已停止。

    • ​CAS 的广泛应用​​:Spark 使用 AtomicInteger, AtomicLong, AtomicReference等原子类(其内部实现就是 CAS)来进行无锁计数和状态更新。

      • ​例如​​:生成唯一任务 ID、累加器(Accumulator)的更新、管理内存页分配等。这在 TaskMemoryManagerAccumulatorV2等类中非常常见。

  2. ​等待队列(AQS 队列的抽象体现)​

    • Spark 内部大量使用 java.util.concurrent包下的同步工具,而这些工具很多本身就是基于 AQS 实现的。

      • ​例如​​:CountDownLatch(基于 AQS 共享模式)被用于等待任务阶段完成。JobWaiter类中就使用了 countDownLatch

      • ​例如​​:线程池。Spark 内部使用的线程池,其底层实现就依赖于类似 AQS 的机制来管理等待执行的任务队列(BlockingQueue)。


层面二:分布式的协调与同步(AQS思想的延伸)

这是 Spark 更核心的部分。AQS 中“状态-队列”的思想被​​抽象和升华​​,用于解决分布式环境下的协调问题。

  1. ​Driver 的调度器:分布式状态机​

    • state的延伸​​:在 DAGSchedulerTaskScheduler中,每个作业(Job)、阶段(Stage)、任务(Task)都有其生命周期状态(如:WAITING、RUNNING、FAILED、SUCCESS)。这些状态由 Driver 统一管理,是集群的“全局状态”。

    • 队列的延伸​​:TaskScheduler维护着不同优先级或调度模式的​​作业队列​​和​​任务队列​​。当 Executor 资源空闲时,Driver 会从队列中取出任务分配给它们。这正是一个 ​​“FIFO 或公平的双向队列”​​ 在分布式场景下的体现。

  2. ​Executor 的心跳与任务执行​

    • Executor 会定期向 Driver 发送心跳,报告自己的​​状态​​(如:空闲、繁忙)和​​资源情况​​(可用的 CPU Core 数)。

    • Driver 根据这些心跳信息,决定将队列中的任务分配给哪个 Executor。这可以看作是一种​​跨进程的“获取/释放资源”信号​​。

总结

虽然在 Spark 源码中找不到直接继承 AbstractQueuedSynchronizer的类,但 ​​AQS 所代表的“通过一个状态变量和一個等待队列来构建同步器”的核心架构思想,是 Spark 并发设计的灵魂所在​​。

  • ​在单机层面​​:Spark 使用 volatileCAS和基于 AQS 的并发工具(如 CountDownLatch)来实现高效、无锁的并发控制。

  • ​在分布式层面​​:Spark 将这种思想扩展,用 ​​Driver 作为中央协调器​​,维护着​​全局状态​​和​​全局任务队列​​,通过 ​​RPC 消息机制​​ 来协调多个节点间的同步,从而构建了整个分布式计算框架。

http://www.dtcms.com/a/395542.html

相关文章:

  • lora微调大语言模型(qwen1.5-chat)
  • 数藏APP如何选择高防IP
  • 破壁之道:构建统一EDI平台,提速芯片设计与制造协作链路
  • 【完整源码+数据集+部署教程】房屋损坏图像分割系统: yolov8-seg-fasternet-bifpn
  • 整体设计 完整的逻辑链条 之6 从简约文字到公共逻辑:四种 “空” 驱动的整体构建方法论
  • 软考中项备考经验分享
  • 基于疾风气象大模型预测“桦加沙”台风轨迹的探索与展望
  • 光谱相机在护眼灯领域的应用
  • 坤驰科技携国产化MTCA解决方案,亮相大科学装置控制系统研讨会
  • 操作系统(一) :操作系统基本概念及特征
  • 魔百盒 Armbian OS 25.08 (基于 Debian 11 bullseye)换源
  • MacOS安装brew失败,无法访问github,怎么处理
  • 举办2025年iCAN大学生创新创业大赛未来机器人创业大赛
  • MissionPlanner架构梳理之(十八)视频流
  • 2025 前端突围战:当 React Server Components 遇上 AI 编程,我们该如何重构开发范式?
  • xss-labs闯关【1-11】
  • vue2利用canvas翻页浏览pdf文件
  • 仿生视觉芯片迈向实用化:《Advanced Science》报道双极性宽谱光电晶体管,赋能自动驾驶与机器感知
  • 如何在手机上把CAD图纸导出为PDF?
  • 【2025最新】02 Spring Boot 第一个小程序 for VS Code - 通过 Spring Initializr 扩展创建
  • map和set的使用和实现(C++)
  • Qt 系统相关 - 网络
  • Java中List转换成Map的两种方式
  • 嵌入式 - RAM10
  • Qwen新开源tongyi-DeepResearch:核心优势
  • Java Stream API性能优化实践指南
  • Qt配置序列化与反序列化实战:QSettings的深度应用指南
  • MySQL下载时出现“starting the server”或“initializing错误”的原因以及解决方案
  • MySQL 数据库核心知识点详解
  • 让机器人边思考边行动!新一代具身智能EO-1:统一架构突破VLA瓶颈