spark.driver.host配置在org.apache.spark.internal.config中。spark.driver.host与spark.driver.port一起决定spark driver的endpoint。
spark.driver.host默认值的取值逻辑如下
org.apache.spark.util.Utils.localCanonicalHostName()
判断是否有SPARK_LOCAL_HOSTNAME环境变量。
如果有配置SPARK_LOCAL_HOSTNAME环境变量,则直接使用该配置值
没有SPARK_LOCAL_HOSTNAME环境变量
localIpAddress = findLocalInetAddress() // 找到本地网络地址
判断是否配置了SPARK_LOCAL_IP环境变量
如果配置了SPARK_LOCAL_IP环境变量
InetAddress.getByName(ip) // 根据配置的ip获取hostname
如果没有配置SPARK_LOCAL_IP环境变量
address = InetAddress.getLocalHost // 获取本地hostname
根据address.isLoopbackAddress或isLinkLocalAddress进行特定逻辑处理,可能需要遍历所有网卡
localIpAddress.getCanonicalHostName
这里会获取服务器网卡的信息,从具体的逻辑看,会获取某种协议栈的第一个地址,即head地址。
1.InetAddress.getLocalHost信息打印方法
在spark.driver.host的默认值计算过程中,有涉及到InetAddress.getLocalHost、isLoopbackAddress和isLinkLocalAddress,为了方便我们进行问题分析,我们可以模拟java代码,获取对应方法和值。遵循以下三个步骤:
(1)编写Java代码,输出到文件Main.java,内容如下:
import java.net.InetAddress;
public class Main {
public static void main(String[] args) throws Exception {
InetAddress a = InetAddress.getLocalHost();
System.out.println(a.getCanonicalHostName());
System.out.println(a.isLoopbackAddress());
System.out.println(a.isLinkLocalAddress());
System.out.println(a);
}
}
(2)编译Main.java,得到Main.class。命令如下:
javac Main.java
(3)运行Main.class,命令如下:
# ipv6网路环境下
java -Djava.net.preferIPv6Addresses=true Main
# ipv4网络环境下
java -Djava.net.preferIPv4Stack=true Main
以上方法在调试IPV4和IPV6的环境中特别有用。
当然,如果掌握了arthas方法,那就更便捷了。但是arthas有个缺点是,如果进程存活时间不长,就比较难捕捉到重要的信息。
2.IPV6网络下spark通信问题
当前我们遇到一个问题是这样的:spark on yarn环境中,spark client可能不在yarn集群中的。如果通过yarn client提交任务,则在client端启动的spark driver会开启一个endpoint,用于接收NodeManager中spark executor的请求信息,比如心跳信息和状态上报请求等。yarn集群如果无法访问spark driver的话,则spark任务无法执行。