本地应用连接Spark集群写入Parquet文件时挂起问题排查
我搭建了一个包含1个Master和3个Workers的Spark集群,通过本地机器上的应用连接该集群。在应用中创建了如下Dataset:
List<String> points = Arrays.asList("UK", "US", "France", "Italy"); Dataset<String> dataset = spark.createDataset(points, Encoders.STRING());
执行dataset.show()后可正常确认Dataset已创建,但尝试将其写入本地磁盘的Parquet文件时:
dataset.write().mode(SaveMode.Append) .parquet(<Hadoop Path>);
应用陷入挂起,且持续输出如下日志:
WARN org.apache.spark.scheduler.TaskSchedulerImpl - Initial job has not accepted any resources; check your cluster UI to ensure that workers are registered and have sufficient resources
请问这是配置问题导致的吗?
这个问题大概率是配置或资源访问相关问题导致的,以下是具体排查和解决方向:
Worker节点资源不足
打开Spark集群UI(默认Master节点的8080端口),查看Worker节点的CPU、内存资源占用情况。如果Worker没有足够的资源分配给写入任务的executor,就会出现任务挂起。可以调整应用提交时的--executor-memory、--executor-cores参数,或者清理Worker节点上占用资源的其他进程。本地磁盘路径的访问权限/可达性问题
Spark任务是在Worker节点上执行的,如果你指定的<Hadoop Path>是本地路径(比如file:///xxx),会出现两种问题:- Worker会尝试写入自身节点的本地磁盘,而非你本地机器的磁盘;
- 如果路径指向你本地机器的目录,Worker节点大概率没有权限或无法访问该路径。
解决方法:
- 优先改用HDFS等分布式存储路径,确保所有Worker节点都能访问;
- 若必须写入本地,需将目标路径设置为所有Worker都能挂载访问的共享目录(如NFS),且Worker进程拥有该目录的读写权限。
Driver与Worker的网络连通性配置
本地应用作为Spark Driver,需确保Worker节点能访问到Driver的IP地址。如果Driver处于NAT网络环境(比如本地机器用内网IP),Worker可能无法和Driver建立连接,导致任务无法分配。需在应用中设置spark.driver.host为Worker可访问的公网IP或内网互通IP。集群节点注册状态异常
尝试重启Spark Master和所有Worker服务,部分情况下节点注册状态异常会导致资源调度失效,重启后可恢复正常。
内容的提问来源于stack exchange,提问作者vs777

