安装使用集群外客户端时,连接集群端口失败
问题
安装集群外客户端或使用集群外客户端时,有时会出现连接Spark任务端口失败的问题。
异常信息:Failed to bind SparkUi
Cannot assign requested address: Service ‘sparkDriver’ failed after 16 retries (on a random free port)! Consider explicitly setting the appropriate binding address for the service ‘sparkDriver’ (for example spark.driver.bindAddress for SparkDriver) to the correct binding address.
原因
- 集群节点与客户端节点网络不通。
- 客户端节点防火墙未关闭。
- 端口被占用:每一个Spark任务都会占用一个SparkUI端口,默认为22600,如果被占用则依次递增端口重试。但是有个默认重试次数,为16次。16次重试都失败后,会放弃该任务的运行。
- 客户端Spark配置参数错误。
- 代码问题。
解决方法
应用无法访问到SparkUI的IP:PORT。有以下可能:
- 查看集群节点与客户端节点是否通信:
查看客户端节点“/etc/hosts”文件中是否配置集群节点映射,在客户端节点执行命令:
ping sparkui的IP
如果ping不同,检查映射配置与网络设置。
- 关闭客户端节点防火墙设置。
systemctl status firewalld(不同的操作系统查询命令不一致,此命令以CentOS为例)
如下图所示:dead表示关闭。
防火墙开则影响通信,执行如下命令关闭防火墙:
service firewalld stop(不同的操作系统查询命令不一致,此命令以CentOS为例)
- 查看端口是否被占用:
如果输出“Connection established”,则表示连接成功,端口已被占用。
Spark UI端口范围由配置文件spark-defaults.conf中的参数“spark.random.port.min”和“spark.random.port.max”决定,若该范围端口都已被占用,则
导致无端口可用从而连接失败。
解决方案:调节重连次数spark.port.maxRetries=50,并且调节executor随机端口范围spark.random.port.max+100
- 查看Spark配置参数:
在客户端节点执行命令cat spark-env.sh,查看SPARK_LOCAL_HOSTNAME,是否为本机IP。
该问题容易出现在从其他节点直接拷贝客户端时,配置参数未修改。
需修改SPARK_LOCAL_HOSTNAME为本机IP
注:如果集群使用EIP通信,则需要设置
- spark-default.conf中添加spark.driver.host = EIP(客户端节点弹性公网IP)
- spark-default.conf中添加spark.driver.bindAddress=本地IP
- spark-env.sh中修改SPARK_LOCAL_HOSTNAME=EIP(客户端节点弹性公网IP)
- 如果通信与配置均无问题,则从代码层面排查:
Spark在启动任务时会在客户端创建sparkDriverEnv并绑定DRIVER_BIND_ADDRESS,该逻辑并没有走到服务端,所以该问题产生的原因也是客户端节点操作系统环境问题导致sparkDriver获取不到对应的主机IP。
可以尝试执行export SPARK_LOCAL_HOSTNAME=172.0.0.1或者设置spark.driver.bindAddress=127.0.0.1,使提交任务driver端可以加载到loopbackAddress,从而规避问题。