1. 程式人生 > >Spark 叢集配置(standalone)

Spark 叢集配置(standalone)

此為純乾貨
喊話橙子精:我放棄那篇論文總結了。。。寒假前在離開實驗室的那天系統抽風了,來學校這兩天基本花在重新裝系統配環境上了

鋪墊一下

在Spark中除了在單機上執行的local模式以外,共有三種分散式部署方法:

  • local
    執行在單機上,一般用於測試和開發

  • standalone
    需要構建由Master+Slave構成的Spark叢集。因此為獨立模式,自帶完整的服務,可單獨部署到一個叢集中,無需依賴任何其他資源管理系統

  • Spark on Mesos
    Spark客戶端直接連線Mesos,不需要額外構建Spark叢集。這是很多公司採用的模式,官方推薦這種模式,比執行在Yarn上更加靈活。有兩種排程模式供使用者選擇使用:
    須知: 每個應用程式的執行環境由一個Dirver和若干個Executor組成,其中,每個Executor佔用若干資源,內部可執行多個Task(與“slot”數對應)(各個節點上的資源被抽象成粗粒度的slot)


    1) 粗粒度模式(Coarse-grained Mode):“獨佔式”,應用程式的各個Task正式執行之前,需要將執行環境中的資源全部申請好,且執行過程中要一直佔用這些資源,即使不用,最後程式執行結束後,才可回收這些資源。一定程度上可以認為,每個應用程式利用mesos搭建了一個虛擬叢集自己使用。 缺點很明顯,會造成資源浪費
    2) 細粒度模式(Fine-grained Mode):“共享式”,按需分配。也需要在程式啟動時先啟動Executor,但是每個Executor佔用的資源僅供自己執行,不需要考慮即將要執行的Task。之後,mesos會為每個executor動態分配資源,每分配一些,便可以執行一個新任務,單個Task執行完之後可以馬上釋放對應的資源。每個Task完全獨立,優點是便於資源控制和隔離,但缺點也很明顯,短作業執行延遲大。

  • Spark on Yarn
    Spark客戶端直接連線Yarn,不需要額外構建Spark叢集。目前僅支援粗粒度模式(Coarse-grained Mode)1,支援兩種模式:
    1) yarn-cluster:適用於生產環境
    2) yarn-client:適用於互動、除錯,立即看到app的輸出

進入正題–Standalone部署

本人使用兩臺機器做配置,這兩臺裝置連在同一個區域網中,均為Linux,部署Standalone的前提是已經安裝好JDK/Hadoop/Spark,如未安裝請參考Spark安裝(僅需在Master上安裝Hadoop和Spark即可,可以直接scp -r 將配置好的hadoop和Spark傳過去)


所有機器統一建立一個非root使用者測試比較好,本人目前使用的還是root,若選擇建立新使用者不要忘記為其新增管理員許可權

1.修改主機名(每臺)

1)將/etc/hostsname內容修改為Master或Slaver-n,使用gedit編輯文件命令如下(若使用的是root使用者,則無需加上sudo)(需reboot系統才可生效)

sudo gedit /etc/hostname

2)在/etc/hosts中修改各個節點的IP與主機名的對應:

sudo gedit /etc/hosts

修改如下:
172.31.72.111 Master
172.31.72.115 Slave1

2.安裝SSH(每臺)

原理:在Master上生成一個金鑰對,包括一個公鑰和一個私鑰,而後將公鑰複製到所有的Slave上。當Master通過SSH連線Salve時,Salve就會生成一個隨機數並用Master的公鑰對隨機數進行加密,併發送給Master。Master收到加密數之後再用私鑰解密,並將解密數回傳給Slave,Slave確認解密數無誤之後就允許Master進行連線了。這就是一個公鑰認證過程,其間不需要使用者手工輸入密碼,保證了叢集中的資料傳輸。

先切換至root,直接su回車輸入密碼即可

1)安裝:

sudo apt-get install ssh

*解除安裝:

apt-get purge openssh-server

2)檢視SSH程序:

ps -e|grep ssh

3)生成金鑰對:

ssh-keygen -t rsa -P ""  //-t 指定生成RSA型別的金鑰以及管理金鑰

一直回車,會在/root/.ssh/資料夾下生成id_rsa id_rsa.pub
id_rsa – 私有金鑰
id_rsa.pub — 公有金鑰

4)把id_rsa.pub追加到authorized_key裡面去,因為authorized_keys可以用來儲存所有允許當前使用者登入到SSH客戶端使用者的公鑰內容,從而實現無金鑰通訊:

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

5)使用gedit修改/etc/ssh/sshd_config 檔案,使得本機允許遠端連線,做如下修改:

RSAAuthentication yes 
PubkeyAuthentication yes 
AuthorizedKeysFile %h/.ssh/authorized_keys
PermitRootLogin yes

6)重啟ssh服務

service ssh restart

5)給許可權:
chmod 600 authorized_keys
chmod 700 ~/.ssh

7) 把master裡的pub複製到slave1(若有多臺機器不要遺漏):

scp /root/.ssh/id_rsa.pub root@slave1:/root/.ssh/id_rsa.pub_sl 

8)切換到slave1,把傳輸過來的公鑰追加到authorized_keys裡面(若有多臺機器不要遺漏):

cat id_rsa.pub_sl >> authorized_keys

9)驗證,在Master上輸入:

ssh slave1

!!!!!!!!!!!!!!!!
很重要:每臺機器上都要配置SSH
!!!!!!!!!!!!!!!!

3.Hadoop配置

1)修改 /etc/profile(每臺!)新增如下內容,使得hadoop命令在當前終端立即生效:

export HADOOP_HOME=/usr/hadoop/hadoop-2.7.5
export PATH=$PATH:$HADOOP_HOME/bin 
export HADOOP_HOME_WARN_SUPPRESS=1 

2)修改~/.bashrc(Master即可),把Hadoop 安裝目錄加入 PATH 變數中,這樣就可以在任意目錄中直接使用 hadoo、hdfs 等命令:

export JAVA_HOME=/usr/java/jdk1.8.0_151
export PATH=$PATH:/usr/hadoop/hadoop-2.7.5/bin:/usr/hadoop/hadoop-2.7.5/sbin

使配置檔案立即生效:

Source ~/.bashrc

以下是在Haoop/ 檔案下的做的配置,可以在Master上統一配置完成後傳送給各個salve

3) 在本地檔案系統建立以下資料夾:./hadoop/tmp、./dfs/data、./dfs/name (mkdir)

4) 在hadoop-env.sh配置檔案中指定JDK環境

gedit  /usr/hadoop/hadoop-2.7.5/etc/hadoop/hadoop-env.sh

新增:

export JAVA_HOME=/usr/java/jdk1.8.0_151

export HADOOP_CONF_DIR=usr/hadoop/hadoop-2.7.5/etc/hadoop

使得配置生效:

source hadoop-env.sh

測試是否配置成功:

hadoop version

sour
5) 配置yarn-env.sh
新增:

export JAVA_HOME=/usr/java/jdk1.8.0_151

使得配置生效:

source  yarn-env.sh

6)修改Hadoop核心配置檔案etc/hadoop/core-site.xml,通過fs.default.name指定 NameNode 的 IP 地址和埠號,通過hadoop.tmp.dir指定hadoop資料儲存的臨時資料夾:
特別注意:如沒有配置hadoop.tmp.dir引數,會指向系統預設的臨時目錄,而這個目錄在每次重啟後都會被刪除,必須重新執行format才行,否則會出錯

<configuration>
 <property>
  <name>fs.defaultFS</name>
  <value>hdfs://Master:9000</value> 埠是否開啟,因為所有的DataNode都要通過這個埠連線NameNode
 <configuration>
 <property>
  <name>fs.defaultFS</name>
  <value>hdfs://Master:9000</value>  <!--埠是否開啟,因為所有的DataNode都要通過這個埠連線NameNode-->
 </property>
 <property>
  <name>io.file.buffer.size</name>
  <value>131072</value>
 </property>
 <property>
  <name>hadoop.tmp.dir</name>
  <value>file:/usr/hadoop/hadoop-2.7.5/tmp</value>
  <description>Abasefor other temporary directories.</description>
 </property>
 <property>
  <name>hadoop.proxyuser.spark.hosts</name>
  <value>*</value>
 </property>
<property>
  <name>hadoop.proxyuser.spark.groups</name>
  <value>*</value>
 </property>
</configuration>

7)修改HDFS核心配置檔案etc/hdfs-site.xml,通過dfs.replication指定HDFS的備份因子(節點個數),通過dfs.name.dir指定namenode節點的檔案儲存目錄,通過dfs.data.dir指定datanode節點的檔案儲存目錄:

<configuration>
   <!-- 設定namenode的http通訊地址 -->
   <property>
      <name>dfs.namenode.http-address</name>
      <value>master:50070</value>
   </property>

   <!-- 設定secondarynamenode的http通訊地址 -->
   <property>
      <name>dfs.namenode.secondary.http-address</name>
      <value>slave1:50090</value>
  </property>
  <property>
   <name>dfs.namenode.name.dir</name>
   <value>file:/usr/hadoop/hadoop-2.7.5/dfs/name</value>
  </property>
  <property>
   <name>dfs.datanode.data.dir</name>
   <value>file:/usr/hadoop/hadoop-2.7.5/dfs/data</value>
  </property>
  <property>
   <name>dfs.replication</name>
   <value>3</value>
  </property>
  <property>
   <name>dfs.webhdfs.enabled</name>
   <value>true</value>
  </property>
  <property>
   <name>dfs.block.size</name>
   <value>268435456</value>
  </property>
  <property>
   <name>dfs.client.block.write.replace-datanode-on-failure.enable</name>
   <value>true</value>
 </property>
 <property>
  <name>dfs.client.block.write.replace-datanode-on-failure.policy</name>
  <value>NEVER</value>
 </property>


</configuration>

8)配置mapred-site.xml,一般情況下,只有一個mapred-site.xml.template ,cp mapred-site.xml.template mapred-site.xml複製出來一份即可:

<configuration>
  <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>
</configuration>

9)Yarn-site.xml

<configuration>
        <property>
                <name>yarn.resourcemanager.hostname</name>
                <value>Master</value>
        </property>
        <property>
                <name>yarn.nodemanager.aux-services</name>
                <value>mapreduce_shuffle</value>
        </property>
</configuration>

10)配置slaves檔案(指明哪幾個節點作為Datanode)
有各種說法,用IP好/用主機名好
本人使用的是主機名:
Master
Slave1

Slaven

11)將配置好的hadoop檔案copy到另一臺slave機器上

scp -r /usr/hadoop/hadoop-2.7.5 root@slave1:/usr/hadoop/hadoop-2.7.5

(-r 因為是資料夾)

12)驗證(only Master)
先格式化namenode

   hadoop namenode -format

13)啟動hdfs (在spark中只要啟動hdfs和yarn就好) (only Master)

./sbin/start-dfs.sh   

注意!!!!啟動前取保防火牆關閉:ufw disable
不然datanode會開啟後又自動關閉(!deepin下本就沒有開啟防火牆,無論iptables還是ufw都沒啟用)

14)jps 檢視啟動程序(每臺)
如果遇上jps找不到,就Source /etc/profile

15)啟動yarn

cd /app/hadoop/hadoop-2.6.0/sbin
./start-yarn.sh

4.配置Spark

(每臺配好環境變數先,在/etc/profile檔案中)
如下:

export JAVA_HOME=/usr/java/jdk1.8.0_151
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export IDEA_JDK=/usr/java/jdk1.8.0_151
export PATH="$PATH:/usr/scala/scala-2.11.11/bin"
export SPARK_HOME=/usr/spark/spark-2.1.1-bin-hadoop2.7
export PATH=$PATH:${SPARK_HOME}/bin
export HADOOP_HOME=/usr/hadoop/hadoop-2.7.5
export PATH=$PATH:$HADOOP_HOME/bin 
export HADOOP_HOME_WARN_SUPPRESS=1

說明:本人搭建的測試叢集中只有兩個節點
節點cpu資訊:slave1雙核,master4核

1)配置conf/spark-env.sh

cp  spark-env.sh.template  spark-env.sh

gedit spark-env.sh

新增如下:

export JAVA_HOME=/usr/java/jdk1.8.0_151
export HADOOP_HOME=/usr/hadoop/hadoop-2.7.5

export SPARK_MASTER_IP=Master
export SPARK_MASTER_PORT=7077
export SPARK_WORKER_CORES=2   //Spark應用程式可以使用的核數
export SPARK_WORDER_INSTANCES=1
export SPARK_WORKER_MEMORY=2g  //Spark應用程式可以使用的總記憶體數
export SPARK_MASTER_WEBUI_PORT=8080
export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=18080 -Dspark.history.retainedApplications=3 -Dspark.history.fs.logDirectory=hdfs://Master:9000/directory "
export SPARK_CONF_DIR=/usr/spark/spark-2.1.1-bin-hadoop2.7/conf

2)修改Spark-default.conf檔案

spark.master                     spark://Master:7077
spark.eventLog.enabled           true
spark.eventLog.dir               hdfs://Master:9000/directory  
spark.eventLog.compress          true
spark.executor.memory            2g    
引數說明:每個executor可使用的記憶體,預設為1G(對應於在spark-submit 時提交的引數 --executor-memory)
spark.executor.cores             2     
引數說明:每個executor的核數,預設為2(對應於在spark-submit 時提交的引數 --executor-cores)
spark.cores.max                  4     
引數說明:所有executor總共核數(對應於在spark-submit 時提交的引數 --total-executor-cores)

4)配置slaves(指定那些節點作為worker)
Master
slave1

5)把spark分發到各個節點:

scp -r /usr/spark/spark-2.1.1-bin-hadoop2.7 root@slave1:/usr/spark/spark-2.1.1-bin-hadoop2.7

6)啟動spark:

./sbin/start-all.sh

7)啟動history服務,檢視程式的詳細情況:

./start-history-server.sh

8)檢視
在瀏覽器輸入 locahost:8080

這裡寫圖片描述

9)驗證客戶端連線

進入slave1節點,進入spark的bin目錄,使用spark-shell連線叢集

cd /app/hadoop/spark-1.1.0/bin
spark-shell --master spark://spark1:7077 --executor-memory 500m

在命令中只指定了記憶體大小並沒有指定核數,所以該客戶端將佔用該叢集所有核並在每個節點分配500M記憶體

關閉Master節點:

sbin/stop-master.sh

關閉Spark:

sbin/stop-all.sh

關閉hdfs叢集:

sbin/stop-dfs.sh

10)總結提供檢視詳細情況的web:
-HDFS:Master:50070 (檢視datanode的information)
                  Slave1:50090 (檢視secondarynamenode的information)
-history:localhost:18080
-Spark:localhost:8080
-關於4040埠
可以通過localhost:4040訪問,但必須先啟動SparkContext。比如命令:./bin/spark-shell,4040頁面只有在有spark 任務執行時才能訪問,提交job後Spark-UI才會啟動。當任務執行完了,立馬埠就釋放了。spark-history 頁面,可以檢視已經finished的job

後記/遇到的問題(不定期更新中)

1.spark上使用HDFS上的資料:
val lines = sc.textFile(“hdfs://master:9000/library/README.txt”)
2. 必須的HDFS操作

hdfs dfs -mkdir -p /directory   //建立directory資料夾(一定)
hdfs dfs -put README.txt /test/README.txt

3.用Spark自帶求PI的例子,測試叢集是否成功(提交自帶的jar包):

./bin/spark-submit --master spark://172.31.72.182:7077 --class org.apache.spark.examples.SparkPi --executor-memory 1g  /usr/spark/spark-2.0.2-bin-hadoop2.6/examples/jars/spark-examples_2.11-2.0.2.jar

5.叢集中有4個節點,HDFS的備份數設定為3,測試資料集為HIGGS(7.48GB),異常中止:
18/03/21 04:14:02 ERROR DFSClient: Failed to close inode 39566
java.io.IOException: Failed to replace a bad datanode on the existing pipeline due to no more good datanodes being available to try.

嘗試:( 參考:hadoop常見錯誤及解決方法)
修改hadoop下的hdfs-site.xml

<property>
  <name>dfs.client.block.write.replace-datanode-on-failure.enable</name>
  <value>true</value>
</property>
<property>
  <name>dfs.client.block.write.replace-datanode-on-failure.policy</name>
  <value>NEVER</value>
</property>

6.自動負載均衡hadoop檔案:hadoop balancer

檢視各節點的磁碟佔用情況 hadoop dfsadmin -report

檢視檔案的備份係數:hadoop dfs -ls [filename]

檢視hadoop叢集的備份冗餘情況:hadoop fsck /

修改hdfs檔案備份係數:hadoop dfs -setrep [-R] path 如果有-R將修改子目錄檔案的性質。hadoop dfs -setrep -w 3 -R /user/hadoop/dir1 就是把目錄下所有檔案備份係數設定為3.
參考:設定hdfs副本數

7.設定哪些選項來自動清除已經停止執行的application的資料夾呢?
spark-env.sh中加入如下內容

SPARK_WORKER_OPTS=”-Dspark.worker.cleanup.enabled=true”

Spark 的Job任務在執行過程中產生大量的臨時目錄位置,導致某個分割槽磁碟寫滿,主要原因spark執行產生臨時目錄的預設路徑/tmp/spark*, 建議優化應用程式或更改日誌路徑到/home/ 子目錄下
spark-env.sh下增加

export SPARK_LOCAL_DIRS=/usr/spark/tmp/

/spark/work/目錄下存放提交的任務程式定時刪除,否則佔用磁碟空間