配置的修改
pom文件
hdfs代碼在hadoop-hdfs-project/hadoop-hdfs中五嫂,pom中關(guān)于依賴的其他hadoop模塊的scope都設(shè)置為了provided统抬,但我們需要在IDEA里啟動(dòng)hdfs,所以扰才,要把這些provided都注釋掉雄右。
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-annotations</artifactId>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-auth</artifactId>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<!--<scope>provided</scope>-->
</dependency>
hdfs配置文件
core-site.xml
在hadoop-common工程里的src/main/conf/目錄下找到 core-site.xml
配置內(nèi)容如下
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
然后把這個(gè)文件復(fù)制一份剃诅,放到該工程的target/classes/目錄里巷送。
hdfs-site.xml
在hadoop-hdfs-project工程里的hadoop-hdfs模塊下的src/main/conf目錄里找到hdfs-site.xml,配置內(nèi)容如下
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/opt/xxxxxxxx/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/opt/xxxxxxxx/hadoop-2.7.3-src/dfs/data</value>
</property>
</configuration>
然后把這個(gè)文件復(fù)制一份综苔,放到該工程的target/classes目錄下
關(guān)于webapps
hadoop內(nèi)部有web應(yīng)用對(duì)外提供服務(wù),比如我們常用的50070之類的端口位岔。這部分web應(yīng)用在namenode和datanode啟動(dòng)的時(shí)候都需要加載如筛,編譯完畢的hadoop中,hdfs的web程序放在了 hadoop-hdfs-project/hadoop-hdfs/target/webapps目錄下抒抬。在IDEA里杨刨,classpath被指定到了hadoop-hdfs/target/classes目錄下,代碼里啟動(dòng)的時(shí)候是到classpath里加載webapps的資源的擦剑,找不到就會(huì)報(bào)錯(cuò)妖胀。我的解決辦法是:把hadoop-hdfs-project/hadoop-hdfs/target/webapps目錄完整復(fù)制到hadoop-hdfs-project/hadoop-hdfs/target/classes下。
如果有人知道如何在IDEA里給classpath添加目錄惠勒,可以在評(píng)論里留言赚抡,多謝各位。
嘗試啟動(dòng)
namenode和datanode是兩個(gè)獨(dú)立的進(jìn)程纠屋,說(shuō)明他們有獨(dú)立的main函數(shù)啟動(dòng)涂臣。namenode的main函數(shù)在hadoop-hdfs模塊下的org.apache.hadoop.hdfs.server.namenode.NameNode類里。datanode的main函數(shù)在org.apache.hadoop.hdfs.server.datanode.DataNode類里售担。 分別右鍵debug一下赁遗。datanode啟動(dòng)沒(méi)有報(bào)錯(cuò),namenode報(bào)了一個(gè)我們非常熟悉的錯(cuò)誤,告訴我們沒(méi)有給NameNode做格式化族铆。
java.io.IOException: NameNode is not formatted.
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:225)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFSImage(FSNamesystem.java:976)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFromDisk(FSNamesystem.java:681)
at org.apache.hadoop.hdfs.server.namenode.NameNode.loadNamesystem(NameNode.java:585)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:645)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:812)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:796)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1493)
at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1559)
hdfs在啟動(dòng)的時(shí)候岩四,需要從磁盤(pán)上讀取fsimage和editlog,然后把他們加載到內(nèi)存里來(lái)哥攘,如果磁盤(pán)上沒(méi)有這些信息剖煌,hdfs啟動(dòng)就會(huì)報(bào)這個(gè)錯(cuò)誤,提示我們hdfs沒(méi)有format逝淹。那我們要做的事情就是末捣,去看下namenode 的format動(dòng)作是如何被調(diào)起執(zhí)行的。這個(gè)操作是hdfs的指令创橄,所以箩做,這個(gè)操作應(yīng)該在hdfs的shell腳本里。在hadoop-hdfs-project/hadoop-hdfs/src /main/bin目錄中找到hdfs腳本妥畏,我們看到當(dāng)我們運(yùn)行 hdfs namenode -format命令的時(shí)候邦邦,實(shí)際上安吁,執(zhí)行的主類就是NameNode主類,然后把-format參數(shù)傳了進(jìn)去燃辖。
hdfs文件第134行鬼店,解析到傳入的command是namenode的時(shí)候,指定要執(zhí)行的class名為org.apache.hadoop.hdfs.server.namenode.NameNode
if [ "$COMMAND" = "namenode" ] ; then
CLASS='org.apache.hadoop.hdfs.server.namenode.NameNode'
HADOOP_OPTS="$HADOOP_OPTS $HADOOP_NAMENODE_OPTS"
elif [ "$COMMAND" = "zkfc" ] ; then
CLASS='org.apache.hadoop.hdfs.tools.DFSZKFailoverController'
HADOOP_OPTS="$HADOOP_OPTS $HADOOP_ZKFC_OPTS"
......
文件末尾黔龟,執(zhí)行的時(shí)候的命令如下
else
# run it
exec "$JAVA" -Dproc_$COMMAND $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
fi
所以妇智,我們想在IDEA里執(zhí)行hdfs namenode -format,只需要啟動(dòng)NameNode的main方法的時(shí)候氏身,設(shè)置好參數(shù)就可以了巍棱。
當(dāng)程序執(zhí)行完畢后,我們從控制臺(tái)看到的輸出如下
Connected to the target VM, address: '127.0.0.1:49792', transport: 'socket'
log4j:WARN No appenders could be found for logger (org.apache.hadoop.util.Shell).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Formatting using clusterid: CID-fd99778b-85d1-4b0e-bbbd-4fd9e93a96ac
Disconnected from the target VM, address: '127.0.0.1:49792', transport: 'socket'
Process finished with exit code 0
到我們配置的hdfs的磁盤(pán)目錄上去看下內(nèi)容蛋欣,發(fā)現(xiàn)數(shù)據(jù)都o(jì)k了航徙。
看到網(wǎng)上有人寫(xiě)了hdfs namenode -format整體的執(zhí)行流程,地址在這里陷虎。后續(xù)的文章里HDFS的所有常用執(zhí)行操作我也盡量都去做一下分析到踏。
啟動(dòng)HDFS
查看啟動(dòng)腳本后發(fā)現(xiàn),腳本里是先啟動(dòng)namenode尚猿,然后啟動(dòng)datanode的窝稿。我們要做的事情就是,在IDEA里分別啟動(dòng)兩個(gè)進(jìn)程凿掂。namenode和datanode的main函數(shù)所在的類前面已經(jīng)寫(xiě)了讹躯,不再重復(fù)。啟動(dòng)完畢后缠劝,在瀏覽器里訪問(wèn)50070潮梯,就可以看到hdfs已經(jīng)啟動(dòng)成功了。
最后惨恭,如果你在虛擬機(jī)上啟動(dòng)了HDFS秉馏,想從其他機(jī)器上訪問(wèn),別忘了設(shè)置防火墻策略脱羡,放行HDFS需要的端口,或者干脆關(guān)掉防火墻萝究。