Spark分区大小超Executor内存等场景运行机制相关问题咨询
Spark运行机制场景问题解答
问题1:无缓存仅执行窄转换,单分区大小超出Executor可用内存时的处理逻辑
- 常规无状态的
map()/filter()类窄转换采用流水线式逐条处理逻辑,不需要将整个分区全量加载到内存再执行计算:核心拉取分区数据后,逐条读取记录、执行算子逻辑,处理完的记录直接向下游传递,不需要在内存中留存全分区数据,只要算子本身没有自定义的全量缓存逻辑,哪怕单分区远大于Executor可用内存,也不会出现OOM问题。 - 只有当你在算子中实现了需要加载全分区数据的逻辑(比如全分区排序、自定义集合存储全量记录)时,才会触发内存不足问题。
问题2:未主动调用缓存接口,Spark是否会自动将分区存储到磁盘
默认不会自动持久化全量分区数据到磁盘,仅两类场景会触发自动落盘:
- 执行包含Shuffle的算子时,Shuffle Map端的中间结果会自动写入Executor本地磁盘,供Reduce端拉取使用
- Shuffle过程中如果内存不足以存放临时聚合/排序数据,会自动将部分中间数据溢写到磁盘
如果你的作业全是窄转换没有Shuffle,处理完的分区数据会直接流向Action算子的输出逻辑,不会自动落盘,下次触发Action时会重新基于RDD血统重新计算全链路逻辑。
问题3:分区数大于集群可用核心数时剩余分区的调度逻辑
是的,剩余3个分区对应的任务会进入调度队列等待核心释放:
- 集群27个核心对应27个并行任务槽,第一批会同时执行27个分区对应的任务
- 只要任意一个任务执行完成释放核心,调度器就会将排队的3个任务依次分配到空闲核心上执行,默认FIFO调度策略下不会出现饥饿问题。
问题4:MEMORY_AND_DISK存储级别下的内存溢出处理与存储位置
- 首先可以明确:分区大小超出Executor存储内存时,会自动将全分区数据溢出到磁盘。该存储级别的逻辑就是优先尝试将分区全量存入内存,内存不足时直接将整个分区写入磁盘,不会只存部分数据到内存。
- 溢出数据默认存储在Executor所在Worker节点的Spark本地工作目录,对应集群配置的
SPARK_LOCAL_DIRS(Spark2.x+也可通过spark.local.dir参数配置)路径,你配置该参数指向外置HDD目录就会存储在外置HDD,未特殊配置的话默认存到系统临时目录。
内容的提问来源于stack exchange,提问作者Bolshoi Booze
相关产品推荐
相关产品推荐

