單純看書(shū)翻源碼非常枯燥狈谊,為了單步debug追Hadoop源碼,最好先在部署環(huán)境編譯一份源碼竞惋,以避免各種環(huán)境問(wèn)題试溯。
本文記錄了猴子在自己的Mac上編譯Hadoop源碼的過(guò)程蔑滓,結(jié)合之前的一次編譯經(jīng)驗(yàn)郊酒,基本覆蓋了編譯Hadoop源碼時(shí)可能遇到的主要問(wèn)題遇绞。
隨著debug的進(jìn)一步深入,后期可能涉及到對(duì)源碼的修改燎窘,需要多次重新編譯摹闽。因此,這一關(guān)是繞不過(guò)的褐健。
版本聲明
- 源碼:
Apache Hadoop 2.6.0
- 系統(tǒng):
macOS 10.12.4
- 依賴(lài):
oracle jdk 1.7.0_79
Apache Maven 3.5.0
libprotoc 2.5.0
編譯
核心命令
mvn install -DskipTests -Pdist,native -Dtar
坑
時(shí)間長(zhǎng)
Hadoop源碼量巨大付鹿、依賴(lài)眾多,編譯時(shí)間比較長(zhǎng)蚜迅。
下載jar包和編譯protoc是兩個(gè)大頭舵匾。編譯protoc用了1小時(shí)左右,下載jar包+編譯Hadoop用了2個(gè)多小時(shí)谁不。除去這些時(shí)間坐梯,也需要1小時(shí)左右才能編譯成功。
還好上半年為了看Yarn的狀態(tài)機(jī)編譯過(guò)一回刹帕,雖然是不完全編譯吵血,但也下載了大部分依賴(lài)的jar包,并編譯安裝了protoc(強(qiáng)烈建議編譯安裝偷溺,忘記當(dāng)時(shí)有什么坑來(lái)著)蹋辅。這次只需要繼續(xù)踩上次剩下的坑了。
不過(guò)挫掏,鑒于第一次編譯時(shí)侦另,大部分人都會(huì)重復(fù)多次才能編譯成功,單次編譯的時(shí)間也沒(méi)什么意義了。喝杯茶褒傅,慢慢來(lái)吧硫麻。
JDK版本
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile (default-compile) on project hadoop-annotations: Compilation failure: Compilation failure:
[ERROR] /Volumes/Extended/Users/msh/IdealProjects/Git-Study/hadoop/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsJDiffDoclet.java:[20,22] 錯(cuò)誤: 程序包c(diǎn)om.sun.javadoc不存在
不明白為啥這個(gè)包會(huì)不存在,可能是JDK版本問(wèn)題樊卓。google一番拿愧,參考解決Mac OS 下編譯Hadoop Annotations 程序包c(diǎn)om.sun.javadoc找不到問(wèn)題解決。
驗(yàn)證
在所有的pom.xml里面找設(shè)置1.7 jdk的地方:
find . -name pom.xml > tmp/tmp.txt
while read file
do
cnt=0
grep '1.7' $file -C2 | while read line; do
if [ -n "$line" ]; then
if [ $cnt -eq 0 ]; then
echo "+++file: $file"
fi
cnt=$((cnt+1))
echo $line
fi
done
cnt=0
done < tmp/tmp.txt
輸出:
+++file: ./hadoop-common-project/hadoop-annotations/pom.xml
</profile>
<profile>
<id>jdk1.7</id>
<activation>
--
<activation>
<jdk>1.7</jdk>
</activation>
<dependencies>
--
--
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<version>1.7</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
+++file: ./hadoop-project/pom.xml
...(略)
確實(shí)./hadoop-common-project/hadoop-annotations/pom.xml
中限制了jdk版本碌尔。
解決
猴子Mac上的默認(rèn)JDK是oracle jdk1.8.0_102
的浇辜,翻了下jdk源碼也有這個(gè)包。說(shuō)明不是因?yàn)樵摪鼘?shí)際不存在唾戚。
可以嘗試修改pom里限制的jdk版本柳洋;不過(guò),為了防止使用了deprecated方法等麻煩叹坦,這里直接切jdk 1.7熊镣,不改pom。
openssl環(huán)境變量
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.7:run (make) on project hadoop-pipes: An Ant BuildException has occured: exec returned: 1
[ERROR] around Ant part ...<exec dir="/Volumes/Extended/Users/msh/IdealProjects/Git-Study/hadoop/hadoop-tools/hadoop-pipes/target/native" executable="cmake" failonerror="true">... @ 5:153 in /Volumes/Extended/Users/msh/IdealProjects/Git-Study/hadoop/hadoop-tools/hadoop-pipes/target/antrun/build-main.xml
猜測(cè)是ant版本問(wèn)題募书,重裝了jdk1.7適配的ant绪囱。
Ant BuildException
也是夠迷惑的。而且之前猴子電腦配置的jdk1.8莹捡,切到1.7之后ant就不能用了(brew安裝的ant用1.8jdk編譯的鬼吵,1.7無(wú)法解析class文件),重裝了適配1.7的ant版本后篮赢,ant可以正常使用了齿椅,卻還是報(bào)這個(gè)錯(cuò)。启泣。涣脚。
結(jié)果還是報(bào)這個(gè)錯(cuò),打開(kāi)build-main.xml看寥茫,發(fā)現(xiàn)是一個(gè)cmake命令的配置遣蚀,copy到終端執(zhí)行:
cmake /Volumes/Extended/Users/msh/IdealProjects/Git-Study/hadoop/hadoop-tools/hadoop-pipes/src/ -DJVM_ARCH_DATA_MODEL=64
輸出:
...(略)
CommandLineTools/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at /usr/local/Cellar/cmake/3.6.2/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
system variable OPENSSL_ROOT_DIR (missing: OPENSSL_INCLUDE_DIR)
Call Stack (most recent call first):
/usr/local/Cellar/cmake/3.6.2/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
/usr/local/Cellar/cmake/3.6.2/share/cmake/Modules/FindOpenSSL.cmake:380 (find_package_handle_standard_args)
CMakeLists.txt:20 (find_package)
...(略)
OPENSSL_ROOT_DIR
、OPENSSL_INCLUDE_DIR
沒(méi)有設(shè)置坠敷。echo一下確實(shí)沒(méi)有設(shè)置妙同。
解決
Mac自帶OpenSSL,然而猴子并不知道哪里算是root膝迎,哪里算是include粥帚;另外,據(jù)說(shuō)mac計(jì)劃移除默認(rèn)的openssl限次。干脆自己重新安裝:
brew install openssl
然后配置環(huán)境變量:
export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2n
export OPENSSL_INCLUDE_DIR=$OPENSSL_ROOT_DIR/include
maven倉(cāng)庫(kù)不穩(wěn)定
[ERROR] Failed to execute goal on project hadoop-aws: Could not resolve dependencies for project org.apache.hadoop:hadoop-aws:jar:2.6.0: Could not transfer artifact com.amazonaws:aws-java-sdk:jar:1.7.4 from/to central (https://repo.maven.apache.org/maven2): GET request of: com/amazonaws/aws-java-sdk/1.7.4/aws-java-sdk-1.7.4.jar from central failed: SSL peer shut down incorrectly -> [Help 1]
出現(xiàn)類(lèi)似“Could not resolve dependencies”芒涡、“SSL peer shut down incorrectly”等語(yǔ)句柴灯,一般是maven不穩(wěn)定,換個(gè)穩(wěn)定的maven源费尽,或者重新編譯多試幾次赠群。
其他
歷史遺留坑
上次編譯有個(gè)小坑,是Hadoop源碼里的歷史遺留問(wèn)題旱幼。
編譯過(guò)程中會(huì)在$JAVA_HOME/Classes
下找一個(gè)并不存在的jar包classes.jar
查描,實(shí)際上需要的是$JAVA_HOME/lib/tools.jar
,加個(gè)軟鏈就好(注意mac加軟鏈時(shí)與linux的區(qū)別)柏卤。
因此上次編譯猴子已經(jīng)修復(fù)了這個(gè)問(wèn)題冬三,這里就不復(fù)現(xiàn)了。具體可以看這篇mac下編譯Hadoop
沒(méi)有skipTests
沒(méi)有skipTests的話缘缚,至少會(huì)在測(cè)試過(guò)程中以下錯(cuò)誤:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.16:test (default-test) on project hadoop-auth: There are test failures.
[ERROR]
[ERROR] Please refer to /Volumes/Extended/Users/msh/IdealProjects/Git-Study/hadoop/hadoop-common-project/hadoop-auth/target/surefire-reports for the individual test results.
Results :
Tests in error:
TestKerberosAuthenticator.testAuthenticationHttpClientPost:157 ? ClientProtocol
TestKerberosAuthenticator.testAuthenticationHttpClientPost:157 ? ClientProtocol
Tests run: 92, Failures: 0, Errors: 2, Skipped: 0
可以暫時(shí)忽略這些相關(guān)錯(cuò)誤勾笆,skipTests跳過(guò)測(cè)試,能追蹤源碼了解主要過(guò)程即可桥滨。
啟動(dòng)偽分布式“集群”
編譯成功后窝爪,在hadoop-dist
模塊的target
目錄下,生成了各種發(fā)行版齐媒。選擇hadoop-2.6.0.tar.gz
蒲每,找個(gè)地方解壓。
配置
參考官網(wǎng)配置etc/hadoop
目錄下的core-site.xml
里初、hdfs-site.xml
啃勉、yarn-site.xml
忽舟、mapred-site.xml
等双妨。
啟動(dòng)
- 格式化(只有第一次需要格式化):
bin/hdfs namenode -format
- 啟動(dòng)(啟動(dòng)dfs時(shí)需要輸出幾次用戶(hù)密碼)
# 啟動(dòng) Namenode、SecondaryNamenode(偽分布式無(wú)法開(kāi)啟HA)叮阅、Datanode
sbin/start-dfs.sh
# 啟動(dòng) ResourceManager刁品、NodeManager
sbin/start-yarn.sh
# 啟動(dòng) TimelineServer(ApplicationHistoryServer)
sbin/yarn-daemon.sh start timelineserver
啟動(dòng)后,訪問(wèn)NameNode浩姥、ResourceManager的Web UI挑随,Timeline的RESTful接口,創(chuàng)建目錄勒叠、上傳文件兜挨,跑示例MapReduce,以驗(yàn)證是否成功部署眯分。
參考:
本文鏈接:Mac編譯Hadoop源碼
作者:猴子007
出處:https://monkeysayhi.github.io
本文基于 知識(shí)共享署名-相同方式共享 4.0 國(guó)際許可協(xié)議發(fā)布拌汇,歡迎轉(zhuǎn)載,演繹或用于商業(yè)目的弊决,但是必須保留本文的署名及鏈接噪舀。