Spark+Hadoop環境搭建
一、工具下載:
1、spark下載
目前最新的是2.1.1,spark 2.0開始api和之前的還是有比較多的變化,因此如果選擇2.0以上版本,最好看一下api變化,下載地址:http://spark.apache.org/downloads.html
2、hadoop下載
3、jdk下載,這個就不多說了,基本很多都用到,不過建議下載1.8以上的,這樣避免出現相容問題
二、spark和hadoop基本介紹
1、Hadoop
Hadoop是一個開發和執行處理大規模資料的軟體平臺,是Appach的一個用java語言實現開源軟體框架,實現在大量計算機組成的叢集中對海量資料進行分散式計算
Hadoop的核心包括兩塊,一個是map/reduce操作,另一個是HDFS分散式檔案系統,這個檔案系統核心是NameNode和DataNode,前者負責記錄檔案樹形結構,簡單來說就是維護檔案目錄結構,以及每個檔案對應在DataNode中的檔案塊屬性。後者是用作資料儲存用的,舉個例子,如果你往HDFS裡面放入一個檔案,首先經過NameNode將檔案資訊記錄下來,然後將它存放到各個DataNode中
2、Spark
Spark是專為大規模資料處理而設計的快速通用的計算引擎,裡面封裝了很多方便的api呼叫,可以把它看做是Hadoop的補充,雖然hadoop也能進行一些分散式計算,但是spark擁有Hadoop MapReduce所具有的優點;但不同於MapReduce的是Job中間輸出結果可以儲存在記憶體中,從而不再需要讀寫HDFS
三、開始搭建環境
1. 選擇幾個ubuntu的虛擬機器,其中一個作為spark的master節點以及hadoop的 NameNode節點,其他的作為slave節點和DataNode節點
2. 解壓下載的spark和hadoop分別到目錄/home/spark
3. 配置ssh無祕鑰登入
a) Master節點生成公鑰
ssh-keygen -t rsa -P '' #一路回車直到生成公鑰
b) 將master生成的pub拷貝到worker(10.14.66.215)上
scp/home/master/.ssh/id_rsa.pub
10.14.66.215:/home/worker/.ssh/id_rsa.pub.master
c) 將自己生成的pub新增到授權列表裡
cat /home/master/.ssh/id_rsa.pub >> /home/master/.ssh/authorized_keys
d) worker節點中將master
cat /home/worker/.ssh/id_rsa.pub.master >> /home/worker/.ssh/authorized_keys
4. 配置etc/profile,相當於環境變數
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export SPARK_HOME=/home/spark/spark-2.1.0-bin-hadoop2.6
export HADOOP_HOME=/home/hadoop/hadoop-2.6.1
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export PYTHONPATH=$PYTHONPATH:$SPARK_HOME/python
export SPARK_SCALA_VERSION=2.11
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$SPARK_HOME/bin
最後執行source /etc/profile讓配置生效
注意:如果要使用python進行spark程式設計,那麼必須將spark的python路徑加到PYTHONPATH中才行,就像上面的
export PYTHONPATH=$PYTHONPATH:$SPARK_HOME/python
另外SPARK_SCALA_VERSION是2.0中需要加入的,因為每次分配任務給worker節點時都會檢查當前的scala編譯版本,沒有這個設定就會報錯找不到build directory,或者可以在SPARK_HOME目錄下建立\launcher\target\scala-2.11空目錄也能解決這個錯誤
5. 配置hadoop和spark的slaves檔案
a) 最好使用機器名作為節點名,下面會提到hadoop這方面的問題
b) 如果使用機器名的話,還需要配置/etc/hosts檔案將對應的機器名和ip繫結
6. 配置hadoop
a) 進入$HADOOP_HOME/etc/hadoop/hadoop-env.sh
export JAVA_HOME=/usr/java/jdk1.8.0_112/
b) $HADOOP_HOME/etc/hadoop/core-site.xml:
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/hadoop-2.7.3/tmp</value>
</property>
</configuration>
注意:fs.defaultFS配置了預設的檔案協議,後面程式碼中就預設加上hdfs://master:9000這個字首
c) $HADOOP_HOME/etc/hadoop/hdfs-site.xml:
<configuration>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>master:50090</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/opt/hadoop-2.7.3/hdfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/opt/hadoop-2.7.3/hdfs/data</value>
</property>
<property>
<name>dfs.namenode.datanode.registration.ip-hostname-check</name>
<!--在Hadoop 2中,不可以被NameNode解析的DataNode將會被拒絕通訊,如果沒配置這個必須在hadoop/etc/slaves裡面用機器名取代ip地址,然後在/etc/hosts裡面加上這個機器名對應的ip地址-->
<value>false</value>
</property>
</configuration>
d) $HADOOP_HOME/etc/hadoop/mapred-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.address</name>
<value>master:19888</value>
</property>
</configuration>
e) $HADOOP_HOME/etc/hadoop/yarn-site.xml
<!-- Site specific YARN configuration properties -->
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>master:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>master:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>master:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>master:8033</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>master:8088</value>
</property>
</configuration>
注意:yarn是作為資源管理器存在,每次提交一個任務時,spark會做兩件事,一個是將程式碼分成多個stage,每個stage相當於一個計算,然後再把stage分成多個task,每個task執行相同的操作,只不過操作的資料不同,這就和之前說的每個DataNode裡面都存放著同一個檔案的不同塊聯絡起來了。然後spark做的另一件事就是向yarn資源管理器請求分配資源,資源管理器通過NodeManager提供的每個節點所在機器的記憶體、CPU等資訊來分配一定的資源給這個任務
f) 最後格式化一下節點:
hdfs namenode -format -force
注意:如果格式化namenode的時候沒有強制格式化datanode,那麼datanode裡面關於namenode的資訊就還是之前的,這樣就找不到namenode了,所以要麼每次格式化namenode前刪除所有datanode,要麼進行強制的格式化同時格式化namenode和datanode
7. 配置spark-env.sh
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64
export HADOOP_HOME=/home/hadoop/hadoop-2.6.1
export SPARK_MASTER_HOST=10.64.66.215
export SPARK_MASTER_PORT=7077
export SPARK_WORKER_MERMORY=2G
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export SPARK_SCALA_VERSION=2.11
注意:配置這些屬性的時候最好根據原始檔裡面註釋裡提供的屬性作為依據,因為不同版本的spark有些屬性可能被廢棄了,如果你按照網上查的去配置的話就會出問題,比如SPARK_MASTER_HOST是2.0才加入的,之前用的是SPARK_MASTER_IP,在2.0已經被廢棄了
8. 拷貝相關檔案到worker節點:
先要修改worker節點的/home目錄為可寫許可權
scp -r /home/hadoop/hadoop-2.6.1 10.14.66.127:/home/hadoop
scp -r /home/spark/spark-2.1.0-bin-hadoop2.7 10.14.66.127:/home/spark
9. 建立hdfs檔案系統
hadoop fs -mkdir -p /Hadoop/Input
hadoop fs -put wordcount.txt /Hadoop/Input
注意:hdfs檔案系統是由namenode來維護目錄結構的,因此你在ubuntu上看不到具體的路徑存放,只能通過hadoop fs命令來檢視
10. 編輯測試程式碼
val file=sc.textFile("hdfs://master:9000/Hadoop/Input/wordcount.txt")
val rdd = file.flatMap(line => line.split(" ")).map(word => (word,1)).reduceByKey(_+_)
rdd.collect()
rdd.foreach(println)
注意:如果是在ubuntu上,hdfs://master:9000這個字首可以不用加,因為hadoop中配置了預設的字首就是它,但是在window上開發時需要加上
11. 搭建spark開發環境
Hadoop和spark比較適合搭建在ubuntu上,但是我們開發就不方便了,因此我們可以在window上搭建master節點,然後其他的像hadoop和slave節點仍然使用ubuntu上搭建好的就行,具體做法是在window上搭好開發環境後,可以檢視ubuntu上worker節點啟動的log檔案,第一行就是啟動的命令,然後將命令裡的master ip指定為window的ip,最後執行命令就能在那臺ubuntu上啟動一個worker節點了,hadoop完全不用變,因為window上仍然可以使用hdfs檔案指定