安装使用集群外客户端时,连接集群端口失败
问题
安装集群外客户端或使用集群外客户端时,有时会出现连接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.
解决方法
应用无法访问到SparkUI的IP:PORT。可能有以下原因:
- 可能原因一:集群节点与客户端节点网络不通。
解决方法:
查看客户端节点“/etc/hosts”文件中是否配置集群节点映射,在客户端节点执行命令:
ping sparkui的IP
如果ping不通,检查映射配置与网络设置。
- 可能原因二:客户端节点防火墙未关闭。
解决方法:
执行如下命令可查看是否关闭:
systemctl status firewalld(不同的操作系统查询命令不一致,此命令以CentOS为例)
如下图所示:dead表示关闭。
防火墙开则影响通信,执行如下命令关闭防火墙:
service firewalld stop(不同的操作系统查询命令不一致,此命令以CentOS为例)
- 可能原因三:端口被占用,每一个Spark任务都会占用一个SparkUI端口,默认为22600,如果被占用则依次递增端口重试。但是有个默认重试次数,为16次。16次重试都失败后,会放弃该任务的运行。
查看端口是否被占用:
ssh -v -p port username@ip
如果输出“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,从而规避问题。