Hadoop2.7.5 +Spark2.3.0+Anaconda2-5.1.0分散式叢集搭建
這幾天因為學習需要搭建了一個由3個節點組成的hadoop和spark分散式叢集,做記錄如下(已生成目錄,可按需檢視)。
叢集搭建環境及安裝軟體版本
- centos6
- jdk1.8.0_161
- hadoop2.7.5
- Spark2.3.0
- Scala-2.11.8
- Anaconda2-5.1.0
- IDEA-2018.1
搭建分散式叢集的幾個主要步驟:
- 下載好搭建分散式叢集的軟體
- 修改叢集各個虛機名稱
- 網路配置:修改叢集各個虛機hosts檔案
- 配置SSH:使得節點間可以互相免密登入
- 安裝jdk:在叢集的各個虛機上安裝jdk並配置相應jdk環境變數
- 安裝hadoop:先在主節點上安裝hadoop,修改完配置檔案後再將主節點的hadoop檔案對映至從節點並配置好各節點相應環境變數
- 安裝spark:先在主節點上安裝spark,修改完配置檔案conf後再將主節點的spark檔案對映至從節點並配置好各節點相應環境變數
- 安裝scala:在叢集的各個虛機上安裝scala並配置相應scala環境變數
- 安裝Anaconda2:在叢集的各個虛機上安裝Anaconda2並配置相應Anaconda2環境變數
- 安裝IDEA-2018.1.1.tar.gz:在主節點上安裝IDEA
- 因為是初次安裝,所以採取了在各個節點安裝jdk、hadoop、spark、scala、Anaconda2和配置相應環境變數的較繁瑣安裝方式,但實際上步驟5-9完全可以只在主機上進行然後再將安裝好的jdk、hadoop、spark、scala、Anaconda2打包對映到各個從節點,並用主節點的環境變數檔案profile.txt替換其他節點的方式安裝。
一、修改叢集各個虛機的名稱
因為拿到手的虛機虛機名不符合自己的開發需求需要更改,加之虛擬機器名會影響分散式叢集環境變數的配置,所以把修改叢集虛機名放在搭建分散式平臺的第一步。期望修改後的虛機名為:主節點:Master,從節點1:slave1, 從節點2:slave2。修改的步驟如下(以主節點為例):
- 開啟在虛機根路徑下的/etc/sysconfig的network 檔案,開啟方式可為在指令行輸入
vim /etc/sysconfig/network - 其他節點的虛機名按照步驟1修改。
- 將個節點的虛機的network檔案修改後,用指令重啟叢集,重啟指令為 shutdown -r now ,重啟後新的虛機名開始起效。(這一步的重啟也可以等到第二步的網路配置完成後)
注:如果你的虛機叢集是遠端登入的也可以直接用指令重啟,不需要叢集物理機管理者授權,重啟後過一段時間便可以重新連線到叢集。 - 重啟虛機後登陸centos系統,開啟終端進入shell命令提示符狀態,顯示如下內容表示修改成功:
[[email protected] ~]#
二、網路配置
修改叢集中個節點的hosts檔案,使得節點間可以相互ping通,為配置SSH做準備。修改步驟和內容如下:
- 開啟Master節點的hosts檔案,指令如下:
[[email protected] ~]# vim /etc/hosts - 在Master節點的hosts檔案中增加slave1、slave2的IP和主機對映關係,修改後如下所示:
- 參照Master節將slave1、slave2的hosts檔案修改成Master節點的hosts檔案一樣。
- 重啟虛擬機器群
- 在Master節點測試是否能ping 通slave1、slave2,測試指令如下:
ping slave1 -c 3
ping slave2 -c 3
ping通slave2後如下示: - 其他節點的ping測試參考Master節點
三、配置SSH
3.1 SSH簡介:SSH是Secure Shell的簡稱,是建立在應用層和傳輸層基礎上的安全協議。SSH是目前比較比較可靠、專為遠端登入會話和其他網路服務提供安全性的協議。SSH由服務端程式和客戶端程式組成,服務端是一個守護程序它在後臺執行並響應來自客戶端的連線請求,而客戶端則包括ssh程式及像scp(遠端複製)、slogin(遠端登入)、sftp(安全檔案傳輸)等其他的應用程式。 3.2 配置SSH的目的:
使得叢集間可以實現免密登入,從而使得叢集中的Hadoop名稱節點(Namenode)可以啟動叢集中所有機器的Hadoop守護程序。
3.3 SSH的免密配置:
- centos預設安裝了SSH的服務端,在進行SSH的免密配置之前先需要在叢集的各個虛機上先安裝好SSH的客戶端。SSH客戶端的安裝指令為:
# yum install openssh-server - 生成私鑰和公鑰:在三個節點中使用如下命令生成私鑰和公鑰
# ssh-keygen -t ras #執行該命令後,遇到提示資訊,一直按Enter鍵就可以
命令執行完畢後,可以在~/.ssh路徑下看到兩個檔案:id-rsa和id_rsa.pub,其中,以.pub結尾的是公鑰。把公鑰命名為authorized_keys_master.pub,使用的命令如下:
# cd ~/.ssh # mv id_rsa.pub authorized_keys_master.pub - 合併公鑰資訊:把兩個節點(slave1和slave2)的公鑰使用scp指令對映Master節點的~/.ssh目錄。
# scp authorized_keys_slave1.pub [email protected]:~./ssh #在節點slave1上執行# scp authorized_keys_slave2.pub [email protected]:~/.ssh #在節點slave2上執行
$ cat authorized_keys_master.pub >>authorized_keys $ cat authorized_keys_slave1.pub >>authorized_keys $ cat authorized_keys_slave2.pub >>authorized_keys
完成合並後再使用scp命令把authorized_keys 密碼檔案傳送到slave1和slave2節點,命令如下:
# scp authorized_keys [email protected]:~./ssh # scp authorized_keys [email protected]:~/.ssh
傳輸完畢後,需要在3臺節點使用如下設定authorized_keys 的讀寫許可權:
# cd ~/.ssh # chmod 400 authorized_keys 4. 驗證免密登入:在各節點中使用ssh命名,驗證他們之間是否可以免密登入:
$ssh Master $ssh slave1 $ssh slave2 配置成功免密登入效果如下:
四、安裝jdk
hadoop和scala都是基於jvm虛擬機器執行,因此我們需要給各個節點的虛機安裝上jdk併為其配置好相應環境變數,此處以主節點安裝為例,其他節點與主節點安裝及配置方式一致。
- 在/opt路徑下新建一個資料夾app並將叢集軟體(包括hadoop、spark等)全部在/opt/app路徑下,指令如下:
# mkdir /opt/app - 將jdk解壓到app路徑
# cd /opt/app tar -zxvf ./jdk-8u161-linux-x64.tar.gz 開啟profile檔案,新增jdk環境變數
# vim /etc/profile
export JAVA_HOME=/opt/app/jdk1.8.0_161 export PATH=$JAVA_HOME/bin:$PATH 用指令使得jdk的環境變數生效
# suorce /etc/proflle
五、安裝hadoop
- 在主節點中的/opt/app路徑下將hadoop安裝包解壓,並將解壓後的資料夾重新命名為hadoop
# cd /opt/app
# tar -zxvf ./hadoop-2.7.5.tar.gz
# mv hadoop2.7.5 hadoop - 修改hadoop路徑下的/etc/hadoop下的core-site.xml、hdfs-site.xml、mapreduce-site.xml、yarn-site.xml、slaves五個檔案
1)修改core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://Master:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/app/hadoop/tmp</value> #臨時檔案路徑
</property>
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
</configuration>
2)修改hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>2</value> #備份數為2
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///opt/app/hadoop/tmp/dfs/namenode</value> #名稱節點路徑
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file://opt/app/hadoop/tmp/dfs/datanode</value> #數字節點路徑
</property>
<property>
<name>dfs.http.address</name>
<value>Master:50070</value> #設為主節點主機名:Master
</property>
</configuration>
3)修改mapreduce-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>Master:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>Master:19888</value>
</property>
</configuration>
4)yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>Master</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>86400</value>
</property>
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>6144</value>
</property>
<property>
<name>yarn.nodemanager.local-dirs</name>
<value>/opt/app/hadoop/tmp/localdir</value>
</property>
<property>
<name>yarn.nodemanager.log-dirs</name>
<value>/opt/app/hadoop/tmp/logdir</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>10</value>
</property>
<property>
<name>yarn.log.server.url</name>
<value>http://Master:19888/jobhistory/logs</value>
</property>
</configuration>
5)修改slaves
Master
slave1
slave2
- 配置環境變數
export HADOOP_HOME=/opt/app/hadoop export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH - 用指令使得環境變數生效
# source /etc/profile - 將主節點上的/opt/app/hadoop資料夾對映到各個節點上。
# cd /opt/app # tar -zcf ./hadoop.master.tar.gz ./hadoop 將/opt/app/hadoop 資料夾壓縮並命名為hadoop.master.tar.gz # scp ./hadoop.master.tar.gz slave1:/opt/app # scp ./hadoop.master.tar.gz slave2:/opt/app - 在各個節點上的/opt/app路徑的hadoop.master.tar.gz 解壓所在路徑(以slave1為例)
# cd /opt/app # tar -zxvf ./hadoop/master.tar.gz # chown -R root /opt/app/hadoop #給解壓後的hadoop資料夾以可讀寫許可權 - hadoop成功安裝測試
在各節點上輸入下面的指令若出現hadoop版本資訊則安裝hadoop成功
# hadoop version - 啟動hadoop叢集
在主節點上執行下列指令
# hdfs dfs namenode -format #首次啟動需要格式化主節點上的名稱節點 # start-dfs.sh # start-yarn.sh
Master節點:
slave1節點:
slave2節點: - hadoop叢集安裝後啟動遇到的異常
異常1:啟動hadoop叢集失敗,如下圖示
異常原因:主節點的hosts檔案裡的從節點2 IP地址輸入錯誤
因為當時顯示是slave2節點異常,結果一直在slave2節點上查詢錯誤,找了許久沒有找到,近乎絕望之際才發現是主節點上的hosts檔案配置錯誤。在這裡謹記,叢集配置牽一髮而動全身,出現錯誤時記得把各個節點的上的可能相關異常源都審查一遍。異常2:訪問hdfs失敗,異常如下所示
異常原因:未關閉叢集防火牆(不知為何看師兄的叢集未關閉叢集也能正常訪問hdfs,這裡表示困惑)
解決方案:修改/叢集etc/selinux/config檔案如下
重啟集群后,在各節點指令終端輸入如下指令,如果顯示"iptables: Firewall is not running"則表示關閉防火牆成功
service iptables status |
六、安裝scala
scala是spark的底層語言,用scala開發spark應用是最為高效的。雖然spark自帶scala,但是卻不便於我們在IDA工具上進行開發應用,所以這裡為spark叢集需要安裝好scala。- 將scala解壓到app路徑
-
# cd /opt/app
# tar -zxvf ./scala-2.11.8.tgz
開啟profile檔案,新增scala環境變數
# vim /etc/profile
- 在檔案中新增環境變數如下:
-
export SCALA_HOME=/opt/app/scala-2.11.8 export PATH=$SCALA_HOME/bin:$PATH 用指令使得scala的環境變數生效
# suorce /etc/proflle
- 其他節點scala安裝參照主節點
七、安裝Spark
- 在主節點中的/opt/app路徑下將spark安裝包解壓,並將解壓資料夾重新命名為spark,解壓及重新命名指令如下
# cd /opt/app # tar -zxvf ./spark-2.3.0-bin-hadoop2.7.tgz # mv spark-2.3.0-bin-hadoop2.7.tgz spark |
- 修改解壓後spark/conf路徑下的slaves、spark-env.sh及spark-deflauts.conf檔案
- 配置conf/slaves
該配置檔案用於設定叢集中執行Worker節點資訊,需要注意的是Master節點不僅執行master程序,也執行worker程序。slaves檔案配置如下:Master #主節點名 slave1 #從節點1名 slave2 #從節點2名
- 配置conf/spark-env.sh
該配置檔案用於設定spark執行環境,預設的spark/conf目錄中沒有spark-env.sh檔案,需要通過複製或者修改spark-env.sh.template進行建立。使用的命令如下:
然後在開啟的spark-env.sh檔案中加入如下內容,設定Master為主節點,# cd /app/opt/spark/conf # cp spark-env.sh.template spark-env.sh # vim spark-env.sh
export JAVA_HOME=/opt/app/jdk1.8.0_161 export SCALA_HOME=/opt/app/scala-2.11.8 export SPARK_MASTER_IP=Master export HADOOP_CONF_DIR=/opt/app/hadoop/etc/hadoop
- 配置conf/spark-deflauts.conf檔案
spark.yarn.historyServer.address=Master:18080 spark.history.ui.port=18080 #HistoryServer的web埠 spark.eventLog.enabled=true #是否記錄Spark事件,用於應用程式在完成後重構webUI spark.eventLog.dir=hdfs://Master:9000/tmp/spark/events #保存日誌相關資訊的路徑,可以是hdfs://開頭的HDFS路徑, #也可以是file://開頭的本地路徑,都需要提前建立 spark.history.fs.logDirectory=hdfs://Master:9000/tmp/spark/event
- 配置/etv/profile
開啟環境變數配置檔案
加入spark環境變數配置如下# vim /etv/profile
export SPARK_HOME=/opt/app/spark export PATH=$SPARK_HOME/bin:SPARK_HOME/sbin:PATH
執行環境變數生效指令
# source /etc/profile
分發Spark目錄至分節點上
# cd /opt/app # scp ./spark [email protected]:/opt/app/spark # scp ./spark [email protected]:/opt/app/spark
- 啟動Spark
在主節點輸入如下指令:
啟動成功後jps後可看到# start-master.sh # start-slaves.sh
Master節點:
slave1節點:
slave1節點: - 使用spark-shell執行一個spark程式例項
首先啟動spark-shell,在任意路徑輸入如下指令
在spark-shell上執行一個簡單的wordcount程式# spark-shell
結果如下:scals-> val rdd=sc.textFile("file:///opt/app/spark/README.md") scala-> val wordcount = rdd.flatMap(_.split("\\s+")).map(x=>(x,1)).reduceByKey(_+_) scala-> val wordsort = wordcount.map{x=>(x._2,x._1)}.sortByKey(false).map(x=>(x._2,x._1)) scala-> wordsort.take(10)
啟動異常
啟動spark-shell出現"ERROR SparkContext :Error initializing SparkContext."
報出:"java.io.FileNotFoundExceptio:File does not exist :hdfs:Master:9000/tmp/spark/events"異常說明沒有在hdfs上建立tmp/spark/events路徑,建立後重新啟動spark-shell再執行上面程式時則可正常執行。
異常警示如下:
八、安裝Anaconda
在每個節點進行下列操作- 執行安裝指令,指令如下:
安裝時,第一個詢問回覆yes,第二個詢問為Anaconda路徑,這裡我們不選擇預設路徑改為[root/anaconda2]>>/opt/app/anaconda,第三個詢問為是否將Anaconda路徑配置在本地環境變數./root/.bashrc,由於我們是把環境變數統一配置在/etc/profile中,所有也選擇nocd /opt/app bash ./Anaconda2-5.1.0-Linux-x86-64.sh
具體安裝流程如下:
- 配置環境變數
開啟環境變數檔案
新增如下語句vim /etc/profile
export ANACONDA2_HOME=/opt/app/anaconda2 export PATH=$ANACONDA2_HOME/bin:$PATH
執行環境變數生效指令
source /etc/profile
九、安裝IDEA
- 程式碼除錯基本在主節點進行,故只需在主節點安裝IDEA即可,安裝指令如下
cd /opt/app
basd ./IDEA-2018.1.1.tar.gz
- 配置環境變數
開啟環境變數檔案
在環境變數檔案中加入如下語句:# vim /etc/profile
export IDEA_HOME=/opt/app/IDEA export PATH=$IDEA_HOME/bin:$PATH
- 開啟idea指令
任意環境輸入:# idea.sh
至此,一個可應用於實際開發的hadoop,spark分散式平臺搭建成功。