Spark基礎學習精髓
1 Spark與大資料
1.1 大資料基礎
1.1.1 大資料特點
- 儲存空間大
- 資料量大
- 計算量大
1.1.2 大資料開發通用步驟及其對應的技術
大資料採集->大資料預處理->大資料儲存->大資料處理->大資料視覺化
(1)大資料採集技術
分散式架構、多種採集技術混合使用
web資料採集:shell程式設計、爬蟲工具、爬蟲程式開發、HTTP協議、TCP/IP基本原理及Socket程式介面、程式語言、資料格式轉換、分散式儲存的命令和介面(HDFS、HBase等)、分散式應用開發
日誌資料採集:採集工具(Flume、Fluentd等)、接入工具(Kafka).日誌採集程式(Java、Python等)開發、Shell程式設計、TCP/IP基本原理以及網路程式設計介面、程式語言、資料格式轉換、分散式儲存系統的命令和介面(HDFS、HBase等)、分散式應用開發。
資料庫資料採集:Shell程式設計、採集工具(Flume、Fluentd等)、接入工具(Kafka)、資料庫採集程式(Java、Python等)開發、SQL查詢語言及程式設計介面、關係型資料、庫連線如JDBC等的使用、TCP/IP基本原理以及Socket程式設計介面、程式語言、資料格式轉換、分散式儲存系統的命令和介面(HDFS、HBase等)、分散式應用開發。
(2)大資料儲存技術
分散式海量檔案儲存:HDFS CEPH Moosefs GlusterFS。
NoSQL資料庫:Hbase Cassandra。
NewSQL資料庫:VoltDB、Spanner、TiDB等。
(3)大資料處理技術
Hadoop框架、Spark框架
1.2 認識Spark
Spark是一個統一的大規模資料處理分析引擎。
技術特點:高效能(基於記憶體)、支援多種語言、通用(提供SQL操作、流資料處理、圖資料處理、機器學習演算法庫)、多平臺執行、分散式開發更容易
1.3 Spark技術棧
1.4 Scala與Spark關係
Spark框架是用scala開發的。Scala語言特點有如下:
- 物件導向、函數語言程式設計
- 是強型別語言,不支援型別的隱式轉換
- 靜態型別語言
- 在JVM虛擬機器上執行,可以利用JAVA資源
- 支援互動式直譯器REPL
1.5 Spark快速學習路線
虛擬機器基礎:定製虛擬機器、能安裝centos7
Linux基礎:實現host和guest網路連線、完成基本檔案操作、會用vim
Scala程式設計:能編寫、編譯、打包、除錯、執行Scala程式,會用Scala編寫簡單的序列處理程式,能看懂簡單的Spark Scala API介面
Spark基礎:能說出Spark程式執行時架構、能提交Spark程式分散式執行、能解釋Spark相關概念:RDD、Application、Job、DAG、Stage、Task,能說出Spark程式的執行過程和程式碼執行過程
Spark核心程式設計:能使用IDEA來編寫、編譯、打包、除錯、執行Spark程式;能使用RDD、DataFrame/Dataset的基礎API編寫Spark程式
(具體學習資源請參見《Spark大資料程式設計實用教程》以及《艾叔》網易雲系列,能幫助初學者快速入門,少踩坑)
1.6 使用軟體和版本推薦
VMware workstation15、Centos7.2、jdk-8u162-linux-x64.tar.gz、hadoop-2.7.6.tar.gz、spark-2.3.0-bin-hadoop2.7.tgz、scala-2.11.12、ideaIC-2018.1.4.tar.gz
2 Spark執行環境的搭建
構建一個Spark執行環境,除Spark自身框架外,還要有叢集管理器和儲存系統用來儲存輸入和輸出資料。
2.1 Spark程式執行時架構
定義:Spark程式執行後程式的各個組成部分。
三種角色:
- Client(客戶端):負責提交Spark程式,提交的物件可以是叢集管理器、也可以沒有提交物件從而在本地執行;
- Driver(驅動程式):負責此次Spark程式執行的管理和狀態監控,從程式開始到程式結束都由Driver全程負責;
- Executor(執行器):負責執行具體任務,Executor可能有多個,所有executor合併共同完成整個任務。Executor中具體任務是Task,每個Task是一個執行緒(每個Task不一定只佔一個CPU,可以佔多個CPU),一個executor中可能有多個Task,一個Task的處理邏輯相同,處理資料不一樣;
Client向叢集管理器發出申請,叢集管理器接收請求,併為其分配合適的資源。具體選擇哪種管理器,可以在Client提交時通過引數指定。每種資源管理器執行Spark程式時機制可能不一樣,但不管怎樣,Spark程式執行時的架構是不變的。其他細節,如Excutor、Task的分配、資源排程、不同資源管理器上Spak執行機制等。
2.2 首先構建最簡Spark大資料執行環境
最簡單的Spark執行環境由HDFS、Yarn、Spark三個部分組成。
部署圖如下:
2.2.1 構建HDFS
1.什麼是hdfs
HDFS(Hadoop Distributed File System Hadoop分散式檔案系統),是一個分散式檔案系統。Spark處理資料時的資料來源和處理結果都儲存在HDFS上。
2.重要特徵
(1)HDFS中的檔案在物理上是分塊儲存(block),塊的大小可以通過配置引數( dfs.blocksize)來規定,預設大小在hadoop2.x版本中是128M,老版本中是64M
(2)HDFS檔案系統會給客戶端提供一個統一的抽象目錄樹,客戶端通過路徑來訪問檔案,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data
(3)目錄結構及檔案分塊資訊(後設資料)的管理由namenode節點承擔——namenode是HDFS叢集主節點,負責維護整個hdfs檔案系統的目錄樹,以及每一個路徑(檔案)所對應的block塊資訊(block的id,及所在的datanode伺服器)
(4)檔案的各個block的儲存管理由datanode節點承擔---- datanode是HDFS叢集從節點,每一個block都可以在多個datanode上儲存多個副本(副本數量也可以通過引數設定dfs.replication)
(5)HDFS是設計成適應一次寫入,多次讀出的場景,且不支援檔案的修改
3.hdfs命令列
(1)檢視幫助 hdfs dfs -help (2)檢視當前目錄資訊 hdfs dfs -ls / (3)上傳檔案 hdfs dfs -put /本地路徑 /hdfs路徑 (4)剪下檔案 hdfs dfs -moveFromLocal a.txt /aa.txt (5)下載檔案到本地 hdfs dfs -get /hdfs路徑 /本地路徑 (6)合併下載 hdfs dfs -getmerge /hdfs路徑資料夾 /合併後的檔案 (7)建立資料夾 hdfs dfs -mkdir /hello (8)建立多級資料夾 hdfs dfs -mkdir -p /hello/world (9)移動hdfs檔案 hdfs dfs -mv /hdfs路徑 /hdfs路徑 (10)複製hdfs檔案 hdfs dfs -cp /hdfs路徑 /hdfs路徑 (11)刪除hdfs檔案 hdfs dfs -rm /aa.txt (12)刪除hdfs資料夾 hdfs dfs -rm -r /hello (13)檢視hdfs中的檔案 hdfs dfs -cat /檔案 hdfs dfs -tail -f /檔案 (14)檢視資料夾中有多少個檔案 hdfs dfs -count /資料夾 (15)檢視hdfs的總空間 hdfs dfs -df / hdfs dfs -df -h / (16)修改副本數 hdfs dfs -setrep 1 /a.txt
4.hdfs工作機制
(1)概述
- HDFS叢集分為兩大角色:NameNode、DataNode
- NameNode負責管理整個檔案系統的後設資料
- DataNode 負責管理使用者的檔案資料塊
- 檔案會按照固定的大小(blocksize)切成若干塊後分布式儲存在若干臺datanode上
- 每一個檔案塊可以有多個副本,並存放在不同的datanode上
- Datanode會定期向Namenode彙報自身所儲存的檔案block資訊,而namenode則會負責保持檔案的副本數量
- HDFS的內部工作機制對客戶端保持透明,客戶端請求訪問HDFS都是通過向namenode申請來進
(2)HDFS寫工作原理
有一個檔案FileA,100M大小。Client將FileA寫入到HDFS上。
HDFS按預設配置。
HDFS分佈在三個機架上Rack1,Rack2,Rack3。
a. Client將FileA按64M分塊。分成兩塊,block1和Block2;
b. Client向nameNode傳送寫資料請求,如圖藍色虛線①------>。
c. NameNode節點,記錄block資訊。並返回可用的DataNode,如粉色虛線②--------->。
Block1: host2,host1,host3
Block2: host7,host8,host4
原理:
NameNode具有RackAware機架感知功能,這個可以配置。
若client為DataNode節點,那儲存block時,規則為:副本1,同client的節點上;副本2,不同機架節點上;副本3,同第二個副本機架的另一個節點上;其他副本隨機挑選。
若client不為DataNode節點,那儲存block時,規則為:副本1,隨機選擇一個節點上;副本2,不同副本1,機架上;副本3,同副本2相同的另一個節點上;其他副本隨機挑選。
d. client向DataNode傳送block1;傳送過程是以流式寫入。
流式寫入過程,//逐個傳輸 host2-->host1--host3>
1>將64M的block1按64k的package劃分;
2>然後將第一個package傳送給host2;
3>host2接收完後,將第一個package傳送給host1,同時client想host2傳送第二個package;
4>host1接收完第一個package後,傳送給host3,同時接收host2發來的第二個package。
5>以此類推,如圖紅線實線所示,直到將block1傳送完畢。
6>host2,host1,host3向NameNode,host2向Client傳送通知,說“訊息傳送完了”。如圖粉紅顏色實線所示。
7>client收到host2發來的訊息後,向namenode傳送訊息,說我寫完了。這樣就真完成了。如圖×××粗實線
8>傳送完block1後,再向host7,host8,host4傳送block2,如圖藍色實線所示。
9>傳送完block2後,host7,host8,host4向NameNode,host7向Client傳送通知,如圖淺綠色實線所示。
10>client向NameNode傳送訊息,說我寫完了,如圖×××粗實線。。。這樣就完畢了。
分析,通過寫過程,我們可以瞭解到:
①寫1T檔案,我們需要3T的儲存,3T的網路流量貸款。
②在執行讀或寫的過程中,NameNode和DataNode通過HeartBeat進行儲存通訊,確定DataNode活著。如果發現DataNode死掉了,就將死掉的DataNode上的資料,放到其他節點去。讀取時,要讀其他節點去。
③掛掉一個節點,沒關係,還有其他節點可以備份;甚至,掛掉某一個機架,也沒關係;其他機架上,也有備份。
(3)HDFS讀工作原理
讀操作就簡單一些了,如圖所示,client要從datanode上,讀取FileA。而FileA由block1和block2組成。
那麼,讀操作流程為:
a. client向namenode傳送讀請求。
b. namenode檢視Metadata資訊,返回fileA的block的位置。
block1:host2,host1,host3
block2:host7,host8,host4
c. block的位置是有先後順序的,先讀block1,再讀block2。而且block1去host2上讀取;然後block2,去host7上讀取;
上面例子中,client位於機架外,那麼如果client位於機架內某個DataNode上,例如,client是host6。那麼讀取的時候,遵循的規律是:
優選讀取本機架上的資料。
5.HDFS的構建
(1)定製虛擬機器(取名scala_dev)
在VMware 15.x上安裝centos7.x,在第一部分已經介紹過具體的安裝包版本,可以在對應的官網或者國內源下載,也可以聯絡我的郵箱zhangv_chian@163.com。
具體安裝步驟可參見:https://www.cnblogs.com/gebilaoqin/p/12817510.html
建議安裝圖形化介面,並且配置好網路,使得host和guest能夠相互Ping通。本人使用的是NAT模式,並且給網路卡配置固定的IP地址,防止重啟後IP有變化,影響後續的配置和ssh登入。
NAT配置可參見:https://blog.csdn.net/sdyb_yueding/article/details/78216135?utm_source=blogxgwz8
關閉防火牆可參見:https://www.cnblogs.com/yyxq/p/10551274.html
安裝vmtools設定共享資料夾,將windows下載的安裝包通過共享資料夾傳遞到centos中:https://www.cnblogs.com/Jankin-Wen/p/10157244.html
修改主機名:
a. 在root使用者下:vi /etc/hosts
b. 在root使用者下: vi /etc/hostname
修改完主機名就可以輸入:reboot 重啟centos
可以ping scaladev看看是否能解析出IP地址
(2)scala_dev無密碼登入自己
因為搭建的是最簡單的HDFS,NameNode 和 DataNode 都在 scala_dev 上,因此,需要做 scala_dev 無密碼登入自己,操作如下。:
解釋:上述命令會 1)自動建立~/.ssh 目錄; 2)在~/.ssh 下自動生成:id_dsa 和 id_dsa.pub 兩個檔案,其中,id_dsa 是私鑰,儲存在 NameNode 節點,id_dsa.pub 是公鑰,要放置在 DataNode 節點,id_dsa.pub 相當於 NameNode 的身份資訊,一旦在 DataNode 節點登記,就相當於 DataNode 節點已認可 NameNode,這樣, NameNode 就可以無密碼登入 DataNode 了; 3)-P 後面的 '' 是 2 個單引號,不是雙引號;
將公鑰 id_dsa.pub 加入到 scala_dev 的 authorized_keys 中,實現 scala_dev 對 scala_dev 自身的認證。
修改 authorized_keys 的許可權
驗證,如果不需要密碼就可以登入,則說明操作成功
(填自己的IP地址)查詢系統自帶的java檔案,根據不同的系統版本,輸入rpm -qa | grep jdk
或者rpm -qa | grep java
(3)配置JDK
1)檢視系統自帶的jdk
2)查詢系統自帶的java檔案,根據不同的系統版本,輸入rpm -qa | grep jdk
或者rpm -qa | grep java
3)刪除noarch檔案以外的其他檔案,輸入rpm -e --nodeps 需要解除安裝的安裝檔名
4)檢視是否已經刪除完畢
5)解壓jdk
在設定好共享目錄的前提下,共享目錄一般都在/mnt/hgfs/<共享檔名>/, 在windows上把安裝包都放在此目錄下
然後解壓到/home/user/ ,命令為:tar xf /mnt/hgfs/sharefile/jdk-8u162-linux-x64.tar.gz /home/user/
6)配置環境變數
切換到root, 然後vi /etc/profile,輸入以下內容(路徑根據自己實際路徑來,不要照搬)
然後切換的普通使用者:su user
配置完環境變數後都要source /etc/profile
驗證:java -version
(4) 配置HDFS
1)解壓hdfs
tar xf /mnt/hgfs/sharefile/hadoop-2.7.6.tar.gz /home/user/
2)配置環境變數
切換到root然後編輯/etc/profile(路徑根據自己實際路徑來,不要照搬)
配置完環境變數後都要source /etc/profile
驗證,退回到普通使用者,輸入 hd,看能否用 tab 鍵補全 hdfs,如果可以,說明 profile 設 置成功,如果不行,則要檢查,或者執行 source/etc/profile 再試。
3)設定hostname
此處scaladev不等加下劃線_,否則會出錯,然後重啟;
4)新增hosts資訊
驗證,如果 pingscaladev 能自動解析出 IP,則說明修改成功。
5)修改 hadoop-env.sh (在前面修改了環境變數/etc/profile是不夠的,必須在每臺節點上加入java的路徑)
6)修改slaves,它儲存的是所有DataNode的主機名
後續擴充套件DataNode,只需要在slaves裡面加主機名
7)修改 hdfs-site.xml,先複製模板檔案
編輯模板
8)修改core-site.xml 複製模板
配置了 defaultFS 和 fs.default.name 後,會自動在路徑前面加上 hdfs://scaladev:9001/字首,這樣,默 認路徑就是 hdfs 上的路徑,之前的 file:///字首,表示的是本地檔案系統。按照目前的配置,/表示 hdfs://scaladev:9001/,表示 HDFS 上的/目錄,而 file:///則表示本地檔案系統的/目錄。
9)格式化並啟動 HDFS
a.格式化
b.啟動HDFS
c.驗證
2.2.2 構建YARN
1.yarn簡介
Yarn是hadoop的叢集管理器,Spark和Mapreduce程式都可以執行在Yarn上。
2.Yarn配置步驟
(1)複製 yarn-site.xml 模板檔案
編輯 yarn-site.xml
(2)複製 mapred-site.xml 模板檔案
(3)啟動Yarn
(4)驗證:Yarn上執行MapReduce程式
MapReduce 和 Spark 一樣,也是一個分散式處理框架,MapReduce 程式和 Spark 一樣,可 以提交到 Yarn 上執行,在 Spark 出現之前,MapReduce 是主流的大資料處理平臺。Hadoop 中自帶了 MapReduce 的例子程式,如經典的 wordcount(單詞計數)程式,如果 MapReduce 執行成功,說明 Yarn 配置成功,後續,我們將學習如何將 Spark 程式提交到 Yarn 上執行。
提交 MapReduce 程式到 Yarn 上執行的步驟如下:
1)複製檔案到HDFS
file:///表示本地檔案系統,/表示 HDFS 的根目錄,這是因為在 core-site.xml 中配置了 defaultFS 為 hdfs://scaladev:9001/
2)驗證
3)在 HDFS 上準備輸入目錄 input,以及檔案 core-site.xml
4)執行wordcount的例子
5)驗證
(5)Yarn執行Mapreduce程式的過程
1)當執行下面的命令後, Client 向 ResourceManager 傳送執行 wordcount 程式(Application) 的請求;ResourceManager 響應請求,返回 Application ID 和一個 HDFS 地址;Client 將啟動 Application 所需資訊(要執行的 jar 包,資源要求等)上傳到指定的 HDFS 路徑下,並向 ResourceManager 發起啟動 MRApplicationMaster(簡稱 AM)請求; hadoopjarshare/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.6.jarwordcount/input/output
2)ResourceManager 根據當前資源使用情況和排程策略,確定一個可用節點(例如 NodeManager01),向該節點的 NodeManager 傳送命令,啟動一個 Container 來執行 AM;
AM 是此次 wordcount 程式執行的管理者,從 wordcount 的啟動到結束都由此 AM 來負責。 AM 啟動後,向 ResourceManager 註冊,計算 Task 數(map 數(Split 數量決定,一個 Split 對 應一個 map)+reduce 數(mapreduce.job.reduces)),以此確定 Container 數(map 數+reduce 數),然後準備好每個任務 Container 請求,傳送給 ResourceManager;ResourceManager 響應 請求,為其指定可用的節點 NodeManager02~NodeManagerXX;
3) AM 依次和這些節點的 NodeManager 通訊,在這些節點上啟動 Container,並在 Container 執行 wordcount 中的 Task,wordcount 的 Task 分為 map 和 reduce 兩種,先執行 mapTask,然 後執行 reduceTask(彙總操作),並向 AM 彙報任務狀態;在執行過程中,Client 會和 AM 通 信,查詢 Application 執行情況或者控制任務執行;
4)當某個 Container 上的任務執行完畢,可以退出時,AM 會和 ResourceManager 通訊, 申請釋放此 Container 及其資源。待總的 Application 結束,所有資源都釋放完畢,AM 會向 ResourceManager 申請登出自己,最後,Client 退出。
(6)Yarn日誌
Yarn的日誌分為兩大類: 1.Yarn架構自身相關日誌,包括ResourceManager和NodeManager 的日誌;2. 在 Yarn 上執行的程式(Application)日誌。
第一類日誌的 ResourceManager 日誌位於 ResoureManager 的$HADOOP_HOME 下的 log 目錄中,日誌檔名是 yarn-user-resourcemanager-scaladev.log。
第一類日誌的 NodeManager 日誌位於每個 NodeManager 的$HADOOP_HOME 下的 log 目 錄中,日誌檔名是 yarn-user-nodemanager-scaladev.log。
第二類日誌位於 ResoureManager 的$HADOOP_HOME 下的 log/userlogs 目錄下,每個 Application 都會根據其 ID 號建立一個目錄,例如:application_1533802263437_0005,在此目錄下,會儲存該 Application 所有 Container 的日誌,示例如下,可以看到 wordcount 這個 Application有3個Container,其中尾號為1的container是AM,其它的container用來執行Task, 可能是 MapTask,也可能ReduceTask。每個 container 日誌目錄下又有 3 個檔案:stdout、 stderr 和 syslog,其中 stdout 是 Task 執行過程中輸出,例如 printfln 就會輸出到 stdout 中, stderr 會儲存報錯資訊,syslog 則會儲存系統日誌輸出。
2.2.3 構建Spark叢集
(1)下載 Spark 軟體包
Spark 所選擇的版本是 2.3.0,軟體包名:spark-2.3.0-bin-hadoop2.7.tgz,下載地址為: http://archive.apache.org/dist/spark/spark-2.3.0/spark-2.3.0-bin-hadoop2.7.tgz
(2)解壓
(3)配置環境變數
(4)設定JAVA_HOME
2.3 執行Spark程式
本地執行、分散式執行
2.3.1本地執行方式
示例:SparkPi
Spark軟體包中有一個spark-examples_2.11-2.3.0.jar 它是Spark自帶示例的jar包,下面就以其中的SparkPi為例,介紹Spark程式的本地(local)執行方式
執行SparkPi具體命令如下:
在spark目錄下執行:spark-submit --class org.apache.spark.examples.SparkPi --master local examples/jars/spark-examples_2.11-2.3.0.jar 10
SparkPi的程式引數說明如下:
- --class org.apache.spark.examples.SparkPi , 指明此執行程式的Main Class
- --master local ,表示此Spark程式Local執行
- examples/jars/spark-examples_2.11-2.3.0.jar, 為Spark示例的jar包
- 10,表示迭代10次。
如果輸出結果,這說明成功。
程式執行時如果報了一個WARN提示:NativeCodeLoader:62-Unable to load native-hadoop library for your platform
解決辦法是在/etc/profile中新增下面的內容
export LD_LIBRARY_PATH=$HADOOP_HOME/lib/native
切換到普通使用者,執行下面的命令,使得配置生效。
source /etc/profile
2.4 執行Spark程式(分散式)
Spark程式分散式執行要依賴特定的叢集管理器,最常用的有Yarn和Standalone。Client和Driver是否在一個程式裡,可以分為client和cluster模式。
2.4.1 Spark on Yarn
1.client deploy mode
以DFSReadWriteTest為例,說明Spark on Yarn的client 的deploy mode。
DFSReadWriteTest是Spark-examples_2.11-2.3.0.jar自帶的一個示例,它會讀取本地檔案進行單詞計數,然後將本地檔案上傳到HDFS,從HDFS讀取該檔案,使用Spark進行計數,最後比較兩次計數的結果。
(1)提交Spark程式 到Yarn上 ,以client mode執行
spark-submit --class org.apache.spark.examples.DFSReadWriteTest --master yarn /home/user/spark-2.3.0-bin-hadoop2.7/examples/jars/spark-examples_2.11-2.3.0.jar /etc/profile /output
執行改程式要保證Yarn和HDFS同時啟動。
如果結果正確,會輸出:Success!
執行報錯:初次執行程式時,可能會有以下兩個報錯。
報錯1的報錯資訊如下所示:
Exception in thread "main"java.lang Exception: When unning with master yam' either HADOOP_CONF DIR or YARN_CONF _DIR must be set in the environment.
報錯原因:沒有設定環境變數:HADOOP_CONF_DIR或YARN_CONF_DR.
解決辦法:在/etc/profile中增加下面的內容。
HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HADOOP_CONF_DIR
切回到普通使用者,使剛才的配置失效。
報錯2的報錯資訊如下所示。
報錯原因:Container(容器)的記憶體超出了虛擬記憶體限制,Container的虛擬記憶體為2.1GB,但使用了2.3GB.comtainer fpd-+22containeriD-container.15373079299 0002_02 0000l1]is runing ba
mual ncnoy ias CGma uage I64 SMB ofI GB plysical memory uscd 23 GB of 2.1 GB virual meaused Killing container
解決辦法:
改變分配Container最小實體記憶體值,將yarn.scheduler.minimum-allocation-mb設定成2GB,重啟Yarn,每個Container向RM申請的虛擬記憶體為2GB*2.1=4.2GB
(2)Spark程式在Yarn上的執行過程
1)client模式下,Client和Driver在一個程式內,向Resource Manager發出請求;
2)Resource Manager指定一個節點啟動Container,用來執行AM;AM向resource manager申請container來執行程式,resource manager向AM返回可用節點;
3)AM同可用節點的NodeManager通訊,在每個節點上啟動Container,每個Container中執行 一個Spark的Excutor,Excutor再執行若干Tasks;
4)Driver與Executor通訊,向其分配Task並執行,並檢測其狀態,直到整個任務完成;
5)總任務完成後,Driver清理Executor,通知AM,AM想ResouceManager請求釋放Container,所有資源清理完畢後,AM登出並退出、client退出。
2. Spark on Yarn (cluster deploy mode)
(1)提交DFSReadWriteTest到Yarn執行(cluster deploy mode)
命令:spark-submit --deploy-mode cluster --class org.apache.spark.examples.DFSReadWriteTest --master yarn /home/user/spark-2.3.0-bin-hadoop2.7/examples/jars/spark-example_2.11-2.3.0.jar /etc/profile /outputSpark
(2)Spark程式在Yarn上執行過程
1)Client想ResourceManager提交Application請求;
2)ResourceManager指定一個節點,啟動Container來執行AM和Spark Driver;AM根據任務情況向ResourceManager申請Container;ResourceManager返回可以執行Container NodeManager;
3)AM與這些NodeManager通訊,啟動Container,在Container中執行Executor;
4)Spark Driver與Executor通訊,向它們分配Task,並監控Task執行狀態;
5)所有Task執行完畢後,清理Executor,清理完畢後,Driver通知AM,AM請求Resource Manager,釋放所有Container;Client收到Application FINISHED後退出。
2.4.2 Spark on Standalone
Standalone是Spark自帶的叢集管理器,主/從式架構,包括Master和Worker兩種角色,Master管理所有的Worker,Worker負責單個節點的管理。
優點:簡單、方便、快速部署。
缺點:不通用、只支援Spark,功能沒有Yarn強大
1.Spark on Standalone(client deployed mode)
(1)部署Standalone
1)配置slaves檔案,改檔案儲存了整個叢集中被管理節點的主機名。先複製模板檔案;
cp conf/slaves.template conf/slaves
2)編輯slaves檔案
vi conf/slaves
3)將localhost修改為scaladev
scala_dev
4)新增JAVA_HOME
cp conf/spark-env.sh.template conf/spark-env.sh
5)編輯spark-env.sh檔案
vi conf/spark-env.sh
6)在最後一行新增下面內容
export JAVA_HOME=/home/user/jdk1.8.0_162
7)啟動Standalone叢集
sbin/start-all.sh
8)驗證 jps,檢視是否有worker和master
9)檢視Standalone的Web監控介面
(2)提交Spark程式到Standalone上,以client deploy mode執行
提交前卻把HDFS已經啟動,HDFS上/output目錄下已經清空。具體命令如下:
spark-submit --class org.apache.spark.examples.DFSReadWriteTest --master spark://scaladev:7077 /home/user/spark-2.3.0-bin-hadoop2.7/examples/jars/spark-examples_2.11-2.3.0.jar /etc/profile /output
其中-master spark:// scaladev:7077 表示連線Standalone叢集, scaladev是Master所在的主機名,沒有指定--deploy-mode cluster,則部署模式預設為client
(3)Spark程式在Standalone上的執行過程(client deploy mode)
client部署模式下,Spark程式在Standalone的執行過程如圖所示。
1)Client初始化,內部啟動Client模組和Driver模組,並向Master傳送Application請求;
2)Master接收請求,為其分配Worker,並通知Worker啟動Executor;
3)Executor向Driver註冊,Driver向Executor傳送Task,Executor執行Task,並反饋執行狀態,Driver再根據Executor的當前情況,繼續傳送Task,直到整個Job完成。
2.Spark on Standalone(cluster deploy mode)
(1)提交Spark程式到Standalone,以cluster deploy mode執行
具體命令如下:
spark-submit --class org.apache.spark.examples.DFSReadWriteTest --master spark://scaladev:6066 --deploy-mode cluster /home/user/spark-2.3.0-bin-hadoop2.7/examples/jars/spark-examples_2.11-2.3.0.jar /etc/profile hdfs://scaladev:9001/output
有4點要特別注意:
1)採用cluster deploy mode時,Driver需要一個處理器,後續Executor還需要另外的處理器,如果虛擬機器scaladev只有1個處理器,就會出現資源不足的警告,導致程式執行失敗,如下所示:
WARN TaskSchedulerImpl:66 - Initial job has not accepted any resource
解決辦法:增加虛擬機器的處理器為2個。
2)命令引數中,--master spark://scaladev:6066 用來指定Master的URL,cluster deploy mode下,Client會向Master提交Rest URL, Spark://scaladev:6066就是Spark的Rest URL;如果還是使用原來的引數--master spark://scaladev:7077,則會報下的錯誤;
WARN RestSubmissionClient:66 -Unable to connect to server spark://7077
3)HDFS的路徑前面要加hdfs://,因為Cluster Mode下,core-site.xml中的defaultFS設定不起作用;
4)Client提交成功後就會退出,而不是等待Application結束後才退出。
(2)Spark程式在Standalone上的執行過程(cluster deploy mode)
cluster deploy mode下,Spark程式在Standalone的執行過程如圖所示。
1)Client初始化,內部啟動Client模組,並向Master註冊Driver模組,並等待Driver資訊,待後續Driver模組正常執行,Client退出;
2)Master接收請求,分配一個Worker,並通知這些Worker啟動Executor;
3)Master接受請求,分配Worker,並通知這些Worker啟動Executor;
4)Executor向Driver註冊,Driver向Executor傳送Task,Executor執行Task,並反饋執行狀態,Driver再根據Executor的當前情況,繼續傳送Task,直到整個Job完成
3. Spark on Standalone日誌
standalone的日誌分為兩類:框架日誌、應用日誌。
框架日誌:指Master和Worker日誌,Master日誌位於Master的Spark目錄下的logs目錄下,檔名:spark-user-org.apache.spark.deploy.master.Master-1-scaladev.out;Worker位於每個Worker節點的Spark目錄下的logs目錄下,檔名為:spark-user-org.apache.spark.deploy.worker.Worker-1-scaladev.out。
應用日誌:指每個Spark程式執行的日誌,因為一個Spark程式可能會啟動多個Executor,每個Executor都會有一個日誌檔案,位於Executor所在的Worker節點的Spark目錄的work目錄下,每個Spark執行會分配一個ID,執行時在控制檯會列印ID的值,如下所示:
Connected to Spark cluster with app ID app-2018081004758-0001
列出woker目錄下的內容,命令如下。
ls work/
然後就可以看目錄下的內容。