如何处理Apache Spark/Hadoop Yarn中的动态端口问题?
问题描述
我搭建了一个包含1个NameNode和2个DataNode的Hadoop集群,在NameNode上安装了Yarn和Spark。执行以下命令运行SparkPi示例时:
spark-submit --deploy-mode cluster --class org.apache.spark.examples.SparkPi $SPARK_HOME/examples/jars/spark-examples_*.jar 10
频繁出现no route to host异常,核心错误信息如下:
Caused by: io.netty.channel.AbstractChannel$AnnotatedNoRouteToHostException: No route to host: lnx-pen205/xx.xx.xx.xx:9222 Caused by: java.net.NoRouteToHostException: No route to host
我发现Spark/Yarn运行时会随机分配端口,若固定spark.driver.port=9222并开放该端口,示例可正常运行,但启动其他会话(如pyspark shell)时会因端口占用失败。
需求:不关闭防火墙的前提下,允许Spark/Yarn动态分配的端口正常通信。
解决方案
核心思路是让Spark和Yarn在指定端口范围内动态分配端口,同时在防火墙上开放整个范围,既避免端口冲突,又保证集群节点间的通信权限。
1. 配置Spark端口范围
在Spark的spark-defaults.conf配置文件中添加以下参数,限制Spark使用的端口区间:
# Driver与Executor通信的端口范围 spark.driver.port 40000-40100 # BlockManager的端口范围 spark.blockManager.port 40101-40200 # Rpc通信的端口范围 spark.rpc.port 40201-40300
配置后Spark会在指定区间内随机选择可用端口,不会再因固定单个端口导致冲突。
2. 配置Yarn相关端口范围
修改Yarn的yarn-site.xml,限制NodeManager相关的动态端口范围:
<!-- NodeManager容器执行器端口范围 --> <property> <name>yarn.nodemanager.container-executor.address</name> <value>0.0.0.0:40301-40400</value> </property> <!-- NodeManager RPC通信端口范围 --> <property> <name>yarn.nodemanager.address</name> <value>0.0.0.0:40401-40500</value> </property> <!-- NodeManager WebUI端口范围 --> <property> <name>yarn.nodemanager.webapp.address</name> <value>0.0.0.0:40501-40600</value> </property>
3. 开放防火墙端口范围
在集群所有节点上,开放上述配置的端口范围(以下以Linux系统为例):
若使用iptables
# 开放Spark相关端口,替换为你的集群内网IP段 iptables -A INPUT -p tcp --dport 40000:40300 -s 192.168.1.0/24 -j ACCEPT # 开放Yarn相关端口 iptables -A INPUT -p tcp --dport 40301:40600 -s 192.168.1.0/24 -j ACCEPT # 保存规则 iptables-save > /etc/iptables/rules.v4
若使用firewalld
# 开放Spark端口范围 firewall-cmd --add-port=40000-40300/tcp --permanent # 开放Yarn端口范围 firewall-cmd --add-port=40301-40600/tcp --permanent # 重新加载规则 firewall-cmd --reload
注意:将192.168.1.0/24替换为你实际的集群内网IP段,避免开放不必要的外部访问权限。
4. 验证配置
重启Spark和Yarn服务:
# 重启Yarn服务 stop-yarn.sh && start-yarn.sh # 若使用Spark Standalone模式,重启Spark集群 stop-all.sh && start-all.sh
再次运行SparkPi示例,同时检查端口分配情况:
# 查看Spark进程使用的端口 netstat -tulpn | grep spark
确认端口在配置的范围内,且示例程序能正常运行即可。
内容的提问来源于stack exchange,提问作者alD
相关产品推荐
相关产品推荐

