2015-10-16 3 views
4

У меня есть кластер Apache Mesos 0.22.1 (3 мастера & 5 подчиненных), работающий с Cloudera HDFS (2.5.0-cdh5.3.1) в конфигурации HA и инфраструктура Spark 1.5.1 ,Доступ к HDFS HA ​​из искрового задания (ошибка UnknownHostException)

Когда я пытаюсь исправить отправку скомпилированного примера примера HdfsTest.scala (из источников Spark 1.5.1) - с ошибкой java.lang.IllegalArgumentException: java.net.UnknownHostException: hdfs в журналах исполнителя. Эта ошибка наблюдается только при передаче HDFS HA ​​Path в качестве аргумента hdfs://hdfs/<file>, когда я прохожу hdfs://namenode1.hdfs.mesos:50071/tesfile - все работает нормально.

То, что я нашел после включения журнала TRACE, заключается в том, что драйвер Spark фактически правильно считывает hdfs://hdfs URL, но Spark executor - нет.

Мой 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() 
    } 
    } 

Я скомпилировать этот код и отправить файл банку Спарк в режиме кластера:

/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 

Мой искровым defaults.conf файл:

spark.master      spark://1.2.3.4:7077 
spark.eventLog.enabled   true 
spark.driver.memory    1g 

My spark-env.sh файл:

export HADOOP_HOME=/opt/spark 
export HADOOP_CONF_DIR=/opt/spark/conf 

У меня есть искра, развернутая на каждом ведомом в каталоге/opt/spark.

Я могу получить доступ к HDFS с помощью команды «hdfs dfs -ls hdfs: // hdfs /» в консоли, без необходимости указывать активный адрес и порт наменования.

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> 

ответ

-2

java.net.UnknownHostException указывает на то, что хост с именем обеспечить hdfs в этом случае не может быть разрешено в IP-адрес.

What causes the error - java.net.UnknownHostException

Вы можете попробовать, чтобы проверить, действительно разрешаться в IP-адрес ping hdfs.

+1

На самом деле, «hdfs» здесь имя службы имен HA, а не имя хоста. https://hadoop.apache.org/docs/r2.4.1/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html. – kyarovoy

+0

В конце концов, 'hdfs' не является именем хоста. Таким образом, он не должен доходить до базового API Java. Что-то не так с вашей конфигурацией HA - попробуйте это http://stackoverflow.com/questions/25062788/namenode-ha-unknownhostexception-nameservice1 – tuxdna

+1

Этот ответ полностью игнорирует контекст вопроса и ничего не затрагивает. –

4

Я нашел решение - добавление

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 из программы-драйвера в программу-исполнителя.

+0

Удивительный! Не могли бы вы принять это как правильный ответ? –

+0

Более правильным решением является распространение 'spark-env.sh' и'/opt/spark/conf' на подчиненные –

0

Необходимо вызвать искру подать, используя следующие:

HADOOP_CONF_DIR=/etc/hadoop/conf spark-submit 

Это настраивает искру правильно.

1

Spark внутренне использует conf conf по умолчанию для fs.defaultFS, который является вашим местным file://.

в-чтобы его честь HDFS HA ​​вам необходимо пройти как core-site.xml и hdfs-site.xml к SparkContext через CLASSPATH, или, как показано ниже (убедитесь, что эти файлы доступны в локальных узлах ведомых в том же месте, например: /config/core-site.xml

Например, Спарк 1.x

val sc = new SparkContext(sparkConf) 

Спарк 2.х

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")); 
+0

Эти файлы уже выбраны из 'src/main/resources'. Каково свойство, которое позволяет разрешить конфигурацию HA? –

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"); 
} 

Вам также нужно a yarn-site.xml, если вы хотите представить через YARN, но я вижу ваш вопрос упоминает Mesos