Spark基礎學習精髓——第一篇

老闆我這有皮卡丘發表於2020-08-17

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/

  然後就可以看目錄下的內容。