我有Apache Mesos 0.22.1集群(3个主服务器和5个从服务器),在HA配置和Spark 1.5.1框架中运行Cloudera HDFS(2.5.0-cdh5.3.1)。
当我尝试spark-submit编译的HdfsTest.scala示例应用程序(来自Spark 1.5.1源代码)时 - 它在执行程序日志中失败并出现java.lang.IllegalArgumentException: java.net.UnknownHostException: hdfs
错误。仅当我将HDFS HA路径作为参数hdfs://hdfs/<file>
传递时才会出现此错误,当我通过hdfs://namenode1.hdfs.mesos:50071/tesfile
时 - 一切正常。
启用TRACE日志记录后我发现的是Spark驱动程序实际上正确读取了hdfs://hdfs
URL,但Spark执行程序没有。
我的Scala应用代码:
import org.apache.spark._
object HdfsTest {
def main(args: Array[String]) {
val sparkConf = new SparkConf().setAppName("HdfsTest")
val sc = new SparkContext(sparkConf)
val file = sc.textFile(args(0))
val mapped = file.map(s => s.length).cache()
for (iter <- 1 to 10) {
val start = System.currentTimeMillis()
for (x <- mapped) { x + 2 }
val end = System.currentTimeMillis()
println("Iteration " + iter + " took " + (end-start) + " ms")
}
sc.stop()
}
}
我编译此代码并以群集模式将jar文件提交给Spark:
/opt/spark/bin/spark-submit --deploy-mode cluster --class com.cisco.hdfs.HdfsTest http://1.2.3.4/HdfsTest-0.0.1.jar hdfs://hdfs/testfile
我的spark-defaults.conf文件:
spark.master spark://1.2.3.4:7077
spark.eventLog.enabled true
spark.driver.memory 1g
我的spark-env.sh文件:
export HADOOP_HOME=/opt/spark
export HADOOP_CONF_DIR=/opt/spark/conf
我在/ opt / spark目录中的每个slave上都部署了spark。
我可以使用&#34; hdfs dfs -ls hdfs:// hdfs /&#34;来访问HDFS。在控制台中执行命令,无需指定活动的namenode地址和端口。
core-site.xml:
----------------------------------------------------------------------
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://hdfs</value>
</property>
</configuration>
hdfs-site.xml:
----------------------------------------------------------------------
<configuration>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.nameservice.id</name>
<value>hdfs</value>
</property>
<property>
<name>dfs.nameservices</name>
<value>hdfs</value>
</property>
<property>
<name>dfs.ha.namenodes.hdfs</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.hdfs.nn1</name>
<value>namenode1.hdfs.mesos:50071</value>
</property>
<property>
<name>dfs.namenode.http-address.hdfs.nn1</name>
<value>namenode1.hdfs.mesos:50070</value>
</property>
<property>
<name>dfs.namenode.rpc-address.hdfs.nn2</name>
<value>namenode2.hdfs.mesos:50071</value>
</property>
<property>
<name>dfs.namenode.http-address.hdfs.nn2</name>
<value>namenode2.hdfs.mesos:50070</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.hdfs</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider </value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://journalnode1.hdfs.mesos:8485;journalnode2.hdfs.mesos:8485;journalnode3.hdfs.mesos:8485/hdfs</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>master.mesos:2181</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/var/lib/hdfs/data/jn</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///var/lib/hdfs/data/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///var/lib/hdfs/data/data</value>
</property>
<property>
<name>dfs.ha.fencing.methods</name>
<value>shell(/bin/true)</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.datanode.du.reserved</name>
<value>10485760</value>
</property>
<property>
<name>dfs.datanode.balance.bandwidthPerSec</name>
<value>41943040</value>
</property>
<property>
<name>dfs.namenode.safemode.threshold-pct</name>
<value>0.90</value>
</property>
<property>
<name>dfs.namenode.heartbeat.recheck-interval</name>
<value>60000</value>
</property>
<property>
<name>dfs.datanode.handler.count</name>
<value>10</value>
</property>
<property>
<name>dfs.namenode.handler.count</name>
<value>20</value>
</property>
<property>
<name>dfs.image.compress</name>
<value>true</value>
</property>
<property>
<name>dfs.image.compression.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
<property>
<name>dfs.namenode.invalidate.work.pct.per.iteration</name>
<value>0.35f</value>
</property>
<property>
<name>dfs.namenode.replication.work.multiplier.per.iteration</name>
<value>4</value>
</property>
<property>
<name>dfs.namenode.datanode.registration.ip-hostname-check</name>
<value>false</value>
</property>
<property>
<name>dfs.client.read.shortcircuit</name>
<value>true</value>
</property>
<property>
<name>dfs.client.read.shortcircuit.streams.cache.size</name>
<value>1000</value>
</property>
<property>
<name>dfs.client.read.shortcircuit.streams.cache.size.expiry.ms</name>
<value>1000</value>
</property>
<property>
<name>dfs.domain.socket.path</name>
<value>/var/run/hadoop-hdfs/dn._PORT</value>
</property>
</configuration>
答案 0 :(得分:5)
我找到了解决方案 - 添加
spark.files file:///opt/spark/conf/hdfs-site.xml,file:///opt/spark/conf/core-site.xml
每个奴隶的到conf/spark-defaults.conf
解决了这个问题。
执行程序成功后将core-site.xml
和hdfs-site.xml
从驱动程序下载到执行程序。
答案 1 :(得分:2)
Spark内部将使用 fs.defaultFS 的默认配置,这是您的本地file://
。
为了尊重HDFS HA,您需要通过CLASSPATH将core-site.xml
和hdfs-site.xml
传递给SparkContext
,或者如下所示(确保这些文件在本地可用)同一位置的从节点,例如:/config/core-site.xml
例如,Spark 1.x
val sc = new SparkContext(sparkConf)
Spark 2.x
SparkSession sparkSession = SparkSession.builder().config(sparkConf).getOrCreate();
val sc = sparkSession.sparkContext()
在任何一种情况下,
sc.hadoopConfiguration().addResource(new org.apache.hadoop.fs.Path("/config/core-site.xml"));
sc.hadoopConfiguration().addResource(new org.apache.hadoop.fs.Path("/config/hdfs-site.xml"));
答案 2 :(得分:1)
必须使用以下内容调用spark-submit:
...
module: {
loaders: [
{
test: /\.jsx?$/,
include: path.join(__dirname, 'src'),
loader: 'babel',
},
{
test: /\.js$/,
exclude: /node_modules/,
loaders: ['babel-loader', 'eslint-loader' ]
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
}
]
},
output: {
path: path.join(__dirname, "src"),
filename: "client.min.js"
},
eslint: {
configFile: './.eslintrc',
outputReport: {
filePath: 'eslint_checkstyle_[hash].xml',
formatter: require('eslint/lib/formatters/checkstyle'),
}
},
...
这可以正确配置火花。
答案 3 :(得分:0)
从一个非常基本的IntelliJ项目(不使用spark-submit
),我验证了这些是您的应用程序的CLASSPATH所需的唯一设置。
<强>芯-site.xml中强>
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://hdfscluster</value>
</property>
</configuration>
<强> HDFS-site.xml中强>
<configuration>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.hdfscluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<property>
<name>dfs.nameservices</name>
<value>hdfscluster</value>
</property>
<property>
<name>dfs.ha.namenodes.hdfscluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.hdfscluster.nn1</name>
<value>namenode1.fqdn:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.hdfscluster.nn2</name>
<value>namenode2.fqdn:8020</value>
</property>
</configuration>
<强> Main.java 强>
public static void main( String[] args ) {
SparkSession spark = SparkSession.builder()
.master("local[*]") // "yarn-client"
.getOrCreate();
spark.read().text("hdfs:///tmp/sample.txt");
}
如果您想通过YARN提交,您还需要yarn-site.xml
,但我看到您的问题提及Mesos
答案 4 :(得分:-3)
java.net.UnknownHostException
表示在这种情况下,提供名称为hdfs
的主机无法解析为IP地址。
What causes the error - java.net.UnknownHostException
您可以尝试检查是否解析为IP地址ping hdfs
。