前情提要:目前正在學(xué)習(xí)大數(shù)據(jù)方面的知識夜赵,于是在4臺VM上搭建環(huán)境溜族,使用的是Cloudera Parcels安裝法颠蕴,所以Hadoop,spark和Yarn是用CDH自動安裝的辈讶。
安裝環(huán)境的各個版本及對應(yīng)的官方Documentation
centos:6.8
Cloudera EnterPrise 5.9.x : http://www.cloudera.com/documentation/enterprise/latest.html
Spark(1.6.0) : http://spark.apache.org/docs/1.6.0/
Scala (2.10.4) : http://docs.scala-lang.org/zh-cn/overviews/
java version: 1.8.0_111(若是在parcells安裝時選擇了自動安裝jdk命浴,那就別自己再安裝jdk了)
jdk下載地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
hadoop 2.6.0-cdh5.9.0
jdk安裝方法:搜索 “centos6 安裝JDK”即可,也可以參考“https://shazi.info/centos-6-%E5%AE%89%E8%A3%9D-java-jdk-1-7-0/”
安裝JDK一定要注意設(shè)定 JAVA_HOME。
Intelligent Idea : https://www.jetbrains.com/help/idea/2016.3/meet-intellij-idea.html?utm_content=2016.3&utm_medium=help_link&utm_source=from_product&utm_campaign=IC
一 Cloudera 5.9.X安裝完成之后的設(shè)定
1. 增加Host 名稱
在每一臺電腦都增加所有 VM 的 IP 跟 Host名稱生闲,如下:
vi /etc/hosts
然后增加下面的內(nèi)容
<code>
140.138.77.22 cglab22
140.138.77.23 cglab23
140.138.77.24 cglab24
140.138.77.25 cglab25 </code>
2. 建立 SSH 免密碼登入媳溺,概念是 master VM 產(chǎn)生一個 public key 然后丟給所有slave vm認(rèn)證,讓master可以無密碼ssh登入其他臺 VM碍讯。步驟如下:
cglab22( master ):
ssh localhost //目的是建立 ~/.ssh文件夾
ssh-keygen -t rsa //建立public key
cat ./id_rsa.pub >> ./authorized_keys //概念上類似認(rèn)證悬蔽,做了就可以免密碼ssh登入
scp ~/.ssh/id_rsa.pub cglab25:~/.ssh //將master的public key傳給slave,過程中需要密碼
cglab23…( slave ):
ssh localhost //目的是建立 ~/.ssh文件夾
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys //概念上類似認(rèn)證捉兴,做了就可以免密碼ssh登入
rm ~/.ssh/id_rsa.pub //可以刪掉了
注意:這個一定要刪掉蝎困,因為上面這個過程只是完成了從master vm到slave vm的ssh免密登錄,而沒有完成從slave vm到master vm倍啥。對于其他的每個slave vm禾乘,都要重復(fù)上面的這些步驟,而如果沒有“ rm ~/.ssh/id_rsa.pub ”這一步虽缕,就會覆蓋掉之前的設(shè)定始藕。
對剩余的slave vm也做相同的步驟
全部完成cglab22、ssh cglab23…之間就可以直接用ssh互相連接氮趋,不需要密碼伍派。
參考:http://www.dashen100.com/question/1014
3.設(shè)置防火墻( iptables ),步驟如下:
sudo vi /etc/sysconfig/iptables
<code>-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -s 140.138.77.23 -j ACCEPT // 這邊是新增的IP凭峡,slave vm IP
-A INPUT -i eth0 -p tcp -s 140.138.77.24 -j ACCEPT // 這邊是新增的IP拙已,slave vm IP
-A INPUT -i eth0 -p tcp -s 140.138.77.25 -j ACCEPT // 這邊是新增的IP,slave vm IP
-A INPUT -i eth0 -p tcp -s 140.138.150.169 -j ACCEPT //允許查看remote vm 的本地電腦的IP(就是自己的電腦的IP)
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
</code>
sudo service iptables restart //再啟動防火墻
4. 關(guān)掉 SELinux
<code>sudo vi /etc/sysconfig/selinux
SELINUX=disabled</code>
5. reboot //重啟
二 Spark程序運(yùn)行時出現(xiàn)的問題
在cloudera環(huán)境配置好之后摧冀,第一次運(yùn)行spark程序出現(xiàn)了許多問題倍踪,以下是幾個困擾我最久的問題:
1. set master url的問題
我是用Intelligent Idea來寫spark程序,在本地端運(yùn)行時記得要在初始化spark的時候設(shè)置master url.
Example:
<code>
val conf = new SparkConf().setAppName("TensorTucker")
.setMaster("Local[*]")
val sc = new SparkContext( conf )
TensorTucker.setSparkContext( sc )
</code>
2.jackson.databind的問題
這個問題的名字很長索昂,由于是很久之前的錯誤建车,已經(jīng)沒有出錯信息了。如果有人碰到椒惨,仔細(xì)看出錯信息缤至,如果里面有關(guān)鍵字jackson.databind,也許我的回答會有幫助康谆。
我把錯誤信息放到stackflow上搜索领斥,得到的答案是這是jackson的版本問題。因為我的CDH是屬于比較新的版本沃暗,所以需要新的jackson jar包來支持運(yùn)行月洛。由于我采用的是parcels安裝,所以jackson的目錄是:
/opt/cloudera/parcels/CDH-5.9.0-1.cdh5.9.0.p0.23/jars
下面是此目錄中jackson jar包示例
可以發(fā)現(xiàn)里面有許多以jackson開頭的jar包孽锥,我下載完jackson-core-2.4.4.jar之后放到上面那個目錄嚼黔,然后由于jackson-core-2.4.4.jar對類似于jackson-annotations.jar等其他jar包的版本也有要求细层,所以我總共在上述目錄添加了一下這幾個jar包,后面是對應(yīng)的版本唬涧。
jackson-module-scala_2.10-2.4.4.jar
jackson-annotations-2.4.4.jar
jackson-core.jar 2.4.4
jackson-annotations 2.4.4
jackson-databind 2.4.4
paranamer 2.6
jsr305 2.0.1
還修改了 coudera/parcels/CDH/lib/spark/conf/classpath.txt 中與上述jar包對應(yīng)的版本
然后在程序中重新引入jackson的jar包疫赎。
Link:https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305/2.0.1
3.修改了intelligent idea Setting->Build,Execution..->Compiler->Build process heap size(從700改到1500),這可能會對解決java out of space的問題有幫助碎节。同時在程序運(yùn)行時進(jìn)行如下設(shè)定捧搞,也對解決java out of space的問題有幫助。
--driver-memory 8G
--num-executors 2
--executor-cores 3
--executor-memory 8G
4.關(guān)于從本地上傳文件到hdfs的問題钓株。
安裝CDH時會自動在hdfs中創(chuàng)建一個身份 hdfs实牡,路徑是/user/hdfs(這里的 user = root ),所以在hdfs中已經(jīng)有一個身份和對應(yīng)路徑了轴合。
然后我自己又在hdfs中創(chuàng)建了一個新的身份是 root ( 這個root其實是我的vm--cglab22的登錄身份 )创坞, 路徑是/user/root 。
所以如果在使用 hdfs dfs -ls的時候不指定具體的路徑受葛,使用 hdfs dfs -ls 這種類似的命令就會默認(rèn)查詢當(dāng)前vm身份下的路徑题涨,即默認(rèn)查詢/user/root 路徑。所以要查詢不同身份的文件总滩,應(yīng)該要指定具體的路徑纲堵。
總結(jié)起來就是,首先在hdfs中創(chuàng)建一個身份root(root就是我登錄VM的身份
hdfs dfs -mkdir /user/root
然后給這個hdfs 的root身份一個對應(yīng)的權(quán)限,如果是登錄vm 是root,則是root權(quán)限窗价,如果是user或xiaoming,則是user或xiaoming的權(quán)限茂附。
hdfs dfs -chown:hadoop /user/root
5.以yarn-cluster模式運(yùn)行程序時遇到的問題(注意要在Cloudera WebUI 中找到Y(jié)ARN,然后在YARN里找到Resource ManagerWeb UI 督弓,然后找對應(yīng)程序的log营曼,不僅要看master vm的log,也要看datanode的log)愚隧,如下圖:
1)SparkContext did not initialize after waiting for 100000 ms 問題
這個屬于spark initial的問題蒂阱,很簡單,是因為我在spark-submit的時候沒有加上--class Test(即在給程序打包時沒有指定main class 狂塘,所以在運(yùn)行時需要加录煤,若在打包時已經(jīng)指定了main class,則不需要加)荞胡。比如下面這個寫法妈踊,一定要加上主函數(shù)名那一項。
<code>
/opt/cloudera/parcels/CDH-5.9.0-1.cdh5.9.0.p0.23/lib/spark/bin/spark-submit
--class test \ //(主函數(shù)名)
--master yarn \ //(運(yùn)行模式)
--deploy-mode cluster
--driver-memory 8G \
--num-executors 2
--executor-cores 3
--executor-memory 8G
/usr/Code/Test/out/artifacts/Pi_jar/Pi.jar/ 10
</code>
2) ERROR yarn.ApplicationMaster: User class threw exception: java.lang.UnsupportedClassVersionError: MyFixedLengthInputFormat : Unsupported major.minor version 52.0
這個問題屬于程序編譯的jdk版本與程序運(yùn)行環(huán)境的版本不一致硝训,我的情況是程序編譯時jdk1.8.0-111,而運(yùn)行環(huán)境卻是1.7,運(yùn)行環(huán)境的配置可以在spark UI中找到窖梁,如下圖:
所以我把intelligent Idea的jdk改到了1.7赘风。改動的地方如下圖:
參考stackflow上的回答:http://stackoverflow.com/questions/10382929/how-to-fix-java-lang-unsupportedclassversionerror-unsupported-major-minor-versi
3)在cluster上運(yùn)行程序時,log上的錯誤信息:INFO yarn.ApplicationMaster: Unregistering ApplicationMaster with FAILED (diag message: User class threw exception: org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="/user/root/test1":hdfs:hadoop:drwxr-xr-x
又是hdfs 中文件的權(quán)限問題纵刘,我以hdfs身份創(chuàng)建的test1,test2邀窃,其所屬權(quán)限屬于hdfs,所以程序運(yùn)行時root沒有權(quán)限對這兩個文件進(jìn)行寫操作假哎,所以應(yīng)以root身份創(chuàng)建文件瞬捕。
6 關(guān)于add host 和delete host
(1)如果在一個cluster中,需要添加或刪除一個host舵抹,可以去cloudera官網(wǎng)找對應(yīng)教程肪虎,值得注意的是,若是要將一個host徹底從一個cluster中移除掉惧蛹,個人經(jīng)驗是按照 remove host的教程來做扇救,因為delete host 之后cluster中還是會出現(xiàn)一些跟這個刪除掉的host有關(guān)的錯誤信息。
(2)add new host 也是去看cloudera的官方文檔香嗓,記得一定要安裝與現(xiàn)有CDH一樣的版本迅腔。add new host的時候,驗證新host與舊host的關(guān)系時靠娱,可能出現(xiàn)swap與Transparent Hugepage Compaction的問題
解決方法如下
https://www.cloudera.com/documentation/enterprise/5-3-x/topics/cdh_admin_performance.html
版本問題的話沧烈,缺什么裝什么好了。
(3)若先delete了一個host 像云,比如cglab25锌雀,然后又add這個host,需要重新設(shè)置ssh免密登錄苫费,這個時候會出現(xiàn):warning:remote host identification has changed汤锨,是因為cglab22-23里的認(rèn)證信息是原來的cglab25,重新裝系統(tǒng)之后要刪掉其他VM原來的認(rèn)證資訊百框,然后才能ssh操作闲礼。
command line如下:
ssh-keygen -R <host>
(4)add new host的時候,驗證新host與舊host的關(guān)系時铐维,可能出現(xiàn)swap與Transparent Hugepage Compaction的問題
解決方法如下:
https://www.cloudera.com/documentation/enterprise/5-3-x/topics/cdh_admin_performance.html