Spark SQL读取Hive表的数据存储生命周期及EBS解决高磁盘占用问题咨询
Spark大表查询磁盘溢出问题解答
1. 无显式配置时Spark SQL读取Hive表的处理数据初始存储位置
Spark读取的Hive表源数据本身存放在Hive元数据指定的底层分布式存储(多数场景为HDFS或AWS S3)。作业运行阶段用于计算处理的临时数据,默认优先存储在Executor分配的堆内/堆外内存中,内存不足需要溢写磁盘时,初始写入路径为Worker节点本地文件系统的/tmp目录,该路径由默认配置项spark.local.dir决定,未显式配置时会自动读取操作系统的SPARK_LOCAL_DIRS环境变量,无该环境变量时默认使用系统临时目录。
2. 处理数据的完整生命周期
- 读取分片:Spark Driver拆分查询计划后,由各Executor拉取对应Hive表的分片数据,优先加载到Executor的内存存储区,作为RDD的内存分区参与计算。
- 内存溢出落盘:单分片数据大小超出Executor分配的内存存储阈值、或Shuffle Map端输出数据超过内存缓冲区容量(默认占Executor可用内存的20%)时,超出部分会序列化后溢写到上述本地磁盘临时目录。
- Shuffle聚合:Reduce端拉取各Map节点的溢写文件到本地,同样优先加载到内存处理,超出阈值继续溢写磁盘,完成合并排序后执行后续的聚合、关联等算子逻辑。
- 生命周期终止:作业无论执行成功或异常终止,Spark都会自动触发清理逻辑,删除本次作业生成的所有临时溢写文件,不会长期占用本地磁盘空间。
3. 新增EBS卷解决磁盘利用率过高问题的原理
多数AWS托管Spark集群(如EMR)默认给Worker节点挂载的根磁盘容量通常只有几十到上百GB,面对数十亿条记录的大表查询时,排序、关联、聚合等高Shuffle操作产生的临时溢写数据量很容易超过根磁盘的剩余容量,触发系统磁盘使用率告警,甚至直接导致作业被资源管理服务终止。
新增EBS卷挂载到Worker节点后,Spark集群的初始化脚本通常会自动将新挂载的块设备路径加入到spark.local.dir的可用路径池中,Spark会轮询所有可用的本地磁盘路径,将临时溢写数据均匀分散写入所有存储设备,相当于直接扩展了作业临时数据的可用存储上限,足以容纳大作业产生的全部临时数据,因此作业可以正常运行。
内容的提问来源于stack exchange,提问作者user7343922
相关产品推荐
相关产品推荐

