Skip to content

分布式集群运行spark任务时出现的各种问题 #61

@CWINDOWX

Description

@CWINDOWX

折腾了十几个小时,终于让一个spark任务可以完整地跑在分布式集群上了。以下是我遇到的各种问题和我的解决办法:

最开始有个什么问题我忘了,不过解决办法是开放slave的50010端口。

  1. 提交spark任务之后没反应,在web ui里也看不见任务被提交了

请尝试在提交任务的时候显式指定资源分配,例如:

    --executor-cores 2 \
    --executor-memory 2g \
    --driver-memory 2g \
    --num-executors 3 \
    --conf spark.network.timeout=600s \
    --conf spark.executor.heartbeatInterval=60s \
    --conf spark.executor.memoryOverhead=1g \

2.提交任务之后报错:ARN TaskSchedulerImpl: Initial job has not accepted any resources; check your cluster UI to ensure that workers are registered and have sufficient resources

这个问题有可能是因为slave的excutor要连接到Driver的地址是master节点上的一个随机端口,由于该端口可能没有开放,所以会失败。我的解决办法是在提交的时候显式设定端口

    --conf spark.driver.bindAddress=192.168.0.41 \    (用master的内网ip)
    --conf spark.driver.host=master \
    --conf spark.driver.port=40000 \                 
    --conf spark.driver.blockManager.port=40001 \
    --conf spark.rpc.driver.port=40002 \

记得还要在master云服务器的安全组里放开对应的端口。(比如示例是40000,40001,40002)

3.开始运行spark任务的时候,卡在某个地方,报这样的错:
org.apache.spark.shuffle.FetchFailedException: Failed to connect to /192.168.0.187:38170
...
Caused by: io.netty.channel.AbstractChannel$AnnotatedNoRouteToHostException: No route to host: /192.168.0.187:38170

核心的的报错代码是Failed to connect to 某个slave的内网IP,No route to host 某个slave的内网IP

这个问题的主要原因是,slave在注册到master的spark上的时候,是用内网IP注册的,这导致slave之间进行通信的时候是用的内网IP,如果slave是不同网络下的云服务器,就不可能通过内网IP访问到其他的slave

第一个解决办法是让slave用公网IP注册到master上,但我试了很多办法都没有成功(包括但不限于,加spark_local_ip,改各种参数,host里改公网IP之类的),如果可以做到,还是推荐用这个办法。

第二个解决办法对于服务器是在一个区域里的,我更推荐。我也是在之前的Issue里找到的。简单地说,就是要让各个服务器配置在一个内网里,如果大家都在一个内网,那就可以用内网地址进行访问了,同时这样会加快任务的运行速度,具体如何配置请看附件。

云服务器配置到一个内网.pdf

附件的前提是各个云服务器要在一个区域,如果不在一个区域,那么就要做些复杂的操作,需要创建新的云服务器,保证这些云服务器在一个区域,同时为了不重新做以前的事,要把旧服务器的配置完全复制过来。具体请按照这个教程执行云服务器的跨区域镜像复制:https://support.huaweicloud.com/usermanual-ims/ims_01_0332.html

大致操作如下:创建一个新的云服务器,保证云服务器都在一个区域里(可用区无所谓),对原本的服务器进行镜像生成,选择完整镜像。这里会让你买一个云备份服务器,选择按需计费即可,有学校发的代金卷不用怕花钱,而且搞完所有操作后直接删了就行。买好新服务器之后,同时做好原服务器的镜像之后,就请按照上面那个教程把镜像跨区域复制(提交委托的时候请用旧版控制台,不然找不到IMS)

镜像跨区域复制成功后,在新的云服务器上选择切换操作系统,镜像选择私有镜像,也就是才复制过来的镜像。操作完之后,新的服务器的配置就和老的基本上差不多了(可以ssh到新的云服务器查看一下有没有hadoop这个用户,有就说明镜像过来了),但还需要更改一些东西。

因为新的服务器的IP变化了,所以请修改host文件里的IP地址。接下来尝试是否可以ssh到各个slave,以及slave可不可以ssh回 master,如果不可以,请用ssh-keygen -R 指令删掉以前的ssh记录,具体删什么可以拿错误代码问ai。

当新的云服务器之间可以做到互相ssh之后,就再试试hadoop和spark集群可不可以开起来,再试着执行之前的sprak任务,看看是不是还是卡在原来的地方,卡在原本的位置说明是对的,配置完全被镜像过来了

接下来就请跟着附件把同一个区域的云服务器配置到一个内网里,配置完之后再提交spark任务,应该就可以正常跑起来了。(而且是通过内网跑的,所以会更快)

如果还不可以,有可能也和第二个问题一样,slave之间的通信是随机端口,此时请显示指定端口
--conf spark.blockManager.port=39000
同时在slave的安全组上放开对应端口

我觉得实验开始创建云服务器的时候,大家最好都选择同一个区域的云服务器,主要为了防止我这种情况。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions