我正在aws EMR中运行一个spark-sql作业,该作业从s3读取约100k个小JSON文件,进行一些转换,并将结果写回s3。我已经将shuffle分区和默认并行度设置为20,将executor内存设置为4GB。然而,对于NativeMethodAccessorImpl的其中一个阶段javaToPython。java,如我所理解的写入s3的UI所示,有近2.7k个任务,输入数据大小<1MB。具有collect操作的阶段的行为相同。我不明白为什么?我在这里错过了什么?我还通过减少应用程序中的分区数量(使用联合(对该应用程序进行了测试,但似乎没有任何变化。我正在运行pyspark 2.4.7和EMR-5.33.1
我认为要了解您所观察到的内容,您需要了解集群的详细信息和配置。
应用程序中的一些假设:
- 您没有在应用程序中实现线程
任务数由并行度(并发任务总数(定义,并行度由定义
- 执行人数量
- 每个执行器的核心数量
- 分区数
请阅读阶段如何划分为任务
有了这个,另一个想法是你提到了
约10万个小型JSON文件
如果您还没有,请确保查看并理解小文件问题
称为的部分
- 小文件的危险
状态
- 这很容易导致任务过多。如果它超过参数spark.driver.maxResultSize(默认1g(的配置将引发以下异常,影响任务的处理由:org.apache.spark.SparkException引起:作业由于阶段而中止失败:478个任务的序列化结果的总大小(2026.0 MB(为大于spark.driver.maxResultSize(1024.0 MB(当然,您可以将spark.driver.maxResultSize的默认配置增加到解决问题,但如果您不能从来源,你将来可能会遇到类似的问题
此外,当Spark处理任务时,一个分区被分配一个任务进行处理,并且在中处理多个分区平行的虽然并行处理可以改善处理效率,并不意味着任务越多越好。如果数据量小,任务多会影响效率。
了解任务是如何创建的(配置和应用程序(+您的Spark应用程序正在尝试吸收什么,将帮助您了解您的应用程序正在做什么。