Spark介紹與安裝(包含IDEA編寫spark程序)

一、Spark概述

1.1、Spark官方介紹

Spark是什麼
Apache Spark是用於大規模數據處理的統一分析引擎
Spark基於內存計算,提高了在大數據環境下數據處理的實時性,同時保證了高容錯性和高可伸縮性,允許用戶將Spark部署在大量硬件之上,形成集羣。

●官網
http://spark.apache.org
http://spark.apachecn.org

在這裏插入圖片描述

1.2. Spark特點


與Hadoop的MapReduce相比,Spark基於內存的運算要快100倍以上,基於硬盤的運算也要快10倍以上。Spark實現了高效的DAG執行引擎,可以通過基於內存來高效處理數據流。

易用
Spark支持Java、Python、R和Scala的API,還支持超過80種高級算法,使用戶可以快速構建不同的應用。而且Spark支持交互式的Python和Scala的shell,可以非常方便地在這些shell中使用Spark集羣來驗證解決問題的方法。

通用
Spark提供了統一的解決方案。Spark可以用於批處理、交互式查詢(Spark SQL)、實時流處理(Spark Streaming)、機器學習(Spark MLlib)和圖計算(GraphX)。這些不同類型的處理都可以在同一個應用中無縫使用。Spark統一的解決方案非常具有吸引力,畢竟任何公司都想用統一的平臺去處理遇到的問題,減少開發和維護的人力成本和部署平臺的物力成本。

兼容性
Spark可以非常方便地與其他的開源產品進行融合。比如,Spark可以使用Hadoop的YARN和Apache Mesos作爲它的資源管理和調度器,並且可以處理所有Hadoop支持的數據,包括HDFS、HBase和Cassandra等。這對於已經部署Hadoop集羣的用戶特別重要,因爲不需要做任何數據遷移就可以使用Spark的強大處理能力。Spark也可以不依賴於第三方的資源管理和調度器,它實現了Standalone作爲其內置的資源管理和調度框架,這樣進一步降低了Spark的使用門檻,使得所有人都可以非常容易地部署和使用Spark。此外,Spark還提供了在EC2上部署Standalone的Spark集羣的工具。

1.3、激動人心的Spark發展史

大數據、人工智能( Artificial Intelligence )像當年的石油、電力一樣, 正以前所未有的廣度和深度影響所有的行業, 現在及未來公司的核心壁壘是數據, 核心競爭力來自基於大數據的人工智能的競爭。
Spark是當今大數據領域最活躍、最熱門、最高效的大數據通用計算平臺,
2009年誕生於美國加州大學伯克利分校AMP 實驗室,
2010年通過BSD許可協議開源發佈,
2013年捐贈給Apache軟件基金會並切換開源協議到切換許可協議至 Apache2.0,
2014年2月,Spark 成爲 Apache 的頂級項目
2014年11月, Spark的母公司Databricks團隊使用Spark刷新數據排序世界記錄

Spark 成功構建起了一體化、多元化的大數據處理體系。在任何規模的數據計算中, Spark 在性能和擴展性上都更具優勢。
(1) Hadoop 之父Doug Cutting 指出:Use of MapReduce engine for Big Data projects will decline, replaced by Apache Spark (大數據項目的MapReduce 引擎的使用將下降,由Apache Spark 取代)
(2)Hadoop 商業發行版本的市場領導者Cloudera 、HortonWorks 、MapR 紛紛轉投Spark,並把Spark 作爲大數據解決方案的首選和核心計算引擎。

2014 年的如此Benchmark 測試中, Spark 秒殺Hadoop ,在使用十分之一計算資源的情況下,相同數據的排序上, Spark 比Map Reduce 快3 倍! 在沒有官方PB 排序對比的情況下,首次將S park 推到了IPB 數據(十萬億條記錄) 的排序,在使用190 個節點的情況下,工作負載在4 小時內完成, 同樣遠超雅虎之前使用3800 臺主機耗時16 個小時的記錄。

2015年6月, Spark 最大的集羣來自騰訊–8000 個節點, 單個Job 最大分別是阿里巴巴和Databricks–1PB ,震撼人心!同時,Spark的Contributor 比2014 年漲了3 倍,達到730 人:總代碼行數也比2014 年漲了2 倍多,達到40 萬行。

IBM 於2015 年6 月承諾大力推進Apache Spark 項目, 並稱該項目爲:以數據爲主導的,未來十年最重要的新的開源項目。這-承諾的核心是將Spark 嵌入IBM 業內領先的分析和商務平臺,並將Spark 作爲一項服務,在IBMB平臺上提供給客戶。IBM 還將投入超過3500 名研究和開發人員在全球10餘個實驗室開展與Spark 相關的項目,並將爲Spark 開源生態系統無償提供突破性的機器學習技術–IBM SystemML。同時,IBM 還將培養超過100 萬名Spark 數據科學家和數據工程師。

2016 年,在有“計算界奧運會”之稱的國際著名Sort Benchmark全球數據排序大賽中,由南京大學計算機科學與技術系PASA 大數據實驗室、阿里巴巴和Databricks 公司組成的參賽因隊NADSort,以144美元的成本完成lOOTB 標準數據集的排序處理,創下了每TB 數據排序1.44美元成本的最新世界紀錄,比2014 年奪得冠軍的加州大學聖地亞哥分校TritonSort團隊每TB 數據4.51美元的成本降低了近70%,而這次比賽依舊使用Apache Spark 大數據計算平臺,在大規模並行排序算法以及Spark 系統底層進行了大量的優化,以儘可能提高排序計算性能並降低存儲資源開銷,確保最終贏得比賽。

在FullStack 理想的指引下,Spark 中的Spark SQL 、SparkStreaming 、MLLib 、GraphX 、R 五大子框架和庫之間可以無縫地共享數據和操作, 這不僅打造了Spark 在當今大數據計算領域其他計算框架都無可匹敵的優勢, 而且使得Spark 正在加速成爲大數據處理中心首選通用計算平臺

1.4、Spark爲什麼會流行

1.4.1. 原因1:優秀的數據模型和計算抽象

Spark 產生之前,已經有MapReduce這類非常成熟的計算系統存在了,並提供了高層次的API(map/reduce),把計算運行在集羣中並提供容錯能力,從而實現分佈式計算。
雖然MapReduce提供了對數據訪問和計算的抽象,但是對於數據的複用就是簡單的將中間數據寫到一個穩定的文件系統中(例如HDFS),所以會產生數據的複製備份,磁盤的I/O以及數據的序列化,所以在遇到需要在多個計算之間複用中間結果的操作時效率就會非常的低。而這類操作是非常常見的,例如迭代式計算,交互式數據挖掘,圖計算等。
認識到這個問題後,學術界的 AMPLab 提出了一個新的模型,叫做 RDD。RDD 是一個可以容錯且並行的數據結構(其實可以理解成分佈式的集合,操作起來和操作本地集合一樣簡單),它可以讓用戶顯式的將中間結果數據集保存在內存中,並且通過控制數據集的分區來達到數據存放處理最優化.同時 RDD也提供了豐富的 API (map、reduce、foreach、redeceByKey…)來操作數據集。後來 RDD被 AMPLab 在一個叫做 Spark 的框架中提供並開源.
簡而言之,Spark 借鑑了 MapReduce 思想發展而來,保留了其分佈式並行計算的優點並改進了其明顯的缺陷。讓中間數據存儲在內存中提高了運行速度、並提供豐富的操作數據的API提高了開發速度。
在這裏插入圖片描述
在這裏插入圖片描述

1.4.2. 原因2:完善的生態圈

在這裏插入圖片描述
目前,Spark已經發展成爲一個包含多個子項目的集合,其中包含SparkSQL、Spark Streaming、GraphX、MLlib等子項目

Spark Core:實現了 Spark 的基本功能,包含RDD、任務調度、內存管理、錯誤恢復、與存儲系統交互等模塊。

Spark SQL:用來操作結構化數據的程序包。通過 Spark SQL,我們可以使用 SQL操作數據。

Spark Streaming:Spark提供的對實時數據進行流式計算的組件。提供了用來操作數據流的API.

Spark MLlib:提供了常見的機器學習(ML)功能的程序庫。

GraphX(圖計算):Spark中用於圖計算的API,性能良好,擁有豐富的功能和運算符,能在海量數據上自如地運行復雜的圖算法。

集羣管理器:Spark 設計爲可以高效地在一個計算節點到數千個計算節點之間伸縮計算。

1.4.3. 擴展閱讀:Spark VS Hadoop
hadoop spark
類型 基礎平臺,包含計算,存儲,調度 分佈式計算工具
場景 大規模數據集上的批處理 迭代計算,交互式計算,流計算
價格 對機器要求較低,便宜 對內存有要求,相對於較貴
編程範式 Map+Reduce,API較爲底層,算法適應性差 RDD組成的DAG有向無環圖,API較爲頂層,方便使用
數據存儲結構 MapReduce中間計算結果存在HDFS 磁盤上,延遲大 RDD中間結果存在內存中,延遲小
運行方式 Task以進程方式維護,任務啓動慢 Task以線程的方式維護,任務啓動快

★注意:
儘管Spark相對於Hadoop而言具有較大優勢,但Spark並不能完全替代Hadoop,Spark主要用於替代Hadoop中的MapReduce計算模型。存儲依然可以使用HDFS,但是中間結果可以存放在內存中;調度可以使用Spark內置的,也可以使用更成熟的調度系統YARN等
實際上,Spark已經很好地融入了Hadoop生態圈,併成爲其中的重要一員,它可以藉助於YARN實現資源調度管理,藉助於HDFS實現分佈式存儲。
此外,Hadoop可以使用廉價的、異構的機器來做分佈式存儲與計算,但是,Spark對硬件的要求稍高一些,對內存與CPU有一定的要求

1.5、Spark運行模式

1.local本地模式(單機)–開發測試使用,分爲local單線程和local-cluster多線程

2.standalone獨立集羣模式–開發測試使用,典型的Mater/slave模式‘’

3.standalone-HA高可用模式–生產環境使用,基於standalone模式,使用zk搭建高可用,避免Master是有單點故障的
4.on yarn集羣模式–生產環境使用
運行在 yarn 集羣之上,由 yarn 負責資源管理,Spark 負責任務調度和計算,
好處:計算資源按需伸縮,集羣利用率高,共享底層存儲,避免數據跨集羣遷移。
FIFO
Fair
Capacity
5.on mesos集羣模式–國內使用較少
運行在 mesos 資源管理器框架之上,由 mesos 負責資源管理,Spark 負責任務調度和計算
6.on cloud集羣模式–中小公司未來會更多的使用雲服務
比如 AWS 的 EC2,使用這個模式能很方便的訪問 Amazon的 S3

第二章 Spark環境搭建

■我們選擇目前企業中使用最多的穩定版Spark2.2.0
■使用Apache版還是CDH版?
1.Apache版直接下載官方編譯好的基於Apache Hadoop的Spark即可
2.自己下載Spark源碼基於CDH Hadoop重新編譯
因爲CDH5.14版 Spark基於Spark1.6版本較低,且爲了推廣自家的Impala對Spark SQL進行了閹割,所以要重新編譯
課程資料中已經給大家提供了編譯好的CHD Spark,當然也可以根據資料自己編譯
(如果自己編譯要求網絡環境較好,使用提供的軟件、倉庫,細心耐心操作,耗時1個半小時左右)

2.1. local本地模式-Spark初體驗

2.1.1. 安裝

●下載Spark安裝包
下載地址:http://spark.apache.org/downloads.html

●解壓重命名=
cd /export/servers
tar spark-2.2.0-bin-2.6.0-cdh5.14.0.tgz
mv spark-2.2.0-bin-2.6.0-cdh5.14.0 spark

●注意:
如果有權限問題,可以修改爲root,方便學習時操作,實際中使用運維分配的用戶和權限即可
chown -R root /export/servers/spark
chgrp -R root /export/servers/spark

●解壓目錄說明:
bin 可執行腳本
conf 配置文件
data 示例程序使用數據
examples 示例程序
jars 依賴 jar 包
python pythonAPI
R R 語言 API
sbin 集羣管理命令
yarn 整合yarn需要的東東

2.1.2. 啓動spark-shell

●開箱即用
直接啓動bin目錄下的spark-shell:
./spark-shell

●spark-shell說明
1.直接使用./spark-shell
表示使用local 模式啓動,在本機啓動一個SparkSubmit進程
2.還可指定參數 --master,如:
spark-shell --master local[N] 表示在本地模擬N個線程來運行當前任務
spark-shell --master local[] 表示使用當前機器上所有可用的資源
3.不攜帶參數默認就是
spark-shell --master local[
]
4.後續還可以使用–master指定集羣地址,表示把任務提交到集羣上運行,如
./spark-shell --master spark://node01:7077
5.退出spark-shell
使用 :quit

2.1.3. 初體驗-讀取本地文件

●準備數據
vim /root/words.txt

hello me you her 
hello you her
hello her 
hello 
val textFile = sc.textFile("file:///root/words.txt")
val counts = textFile.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _)
counts.collect//收集結果
// Array[(String, Int)] = Array((you,2), (hello,4), (me,1), (her,3))
2.1.4. 初體驗-讀取HDFS文件

●準備數據
上傳文件到hdfs
hadoop fs -put /root/words.txt /wordcount/input/words.txt
目錄如果不存在可以創建
hadoop fs -mkdir -p /wordcount/input
結束後可以刪除測試文件夾
hadoop fs -rm -r /wordcount

val textFile = sc.textFile("hdfs://node01:8020/wordcount/input/words.txt")
val counts = textFile.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _)
counts.saveAsTextFile("hdfs://node01:8020/wordcount/output")

2.2. standalone集羣模式

2.2.1. 集羣角色介紹

Spark是基於內存計算的大數據並行計算框架,實際中運行計算任務肯定是使用集羣模式,那麼我們先來學習Spark自帶的standalone集羣模式瞭解一下它的架構及運行機制。

Standalone集羣使用了分佈式計算中的master-slave模型,
master是集羣中含有master進程的節點
slave是集羣中的worker節點含有Executor進程

●Spark架構圖如下(先了解):
在這裏插入圖片描述

2.2.2. 集羣規劃

node01:master
node02:slave/worker
node03:slave/worker

2.2.3. 修改配置並分發

●修改Spark配置文件
cd /export/servers/spark/conf
mv spark-env.sh.template spark-env.sh
vim spark-env.sh

#配置java環境變量
export JAVA_HOME=/export/servers/jdk1.8
#指定spark Master的IP
export SPARK_MASTER_HOST=node01
#指定spark Master的端口
export SPARK_MASTER_PORT=7077

mv slaves.template slaves
vim slaves

node02
node03

●通過scp 命令將配置文件分發到其他機器上
scp -r /export/servers/spark node02:/export/servers
scp -r /export/servers/spark node03:/export/servers

2.2.4. 啓動和停止

●集羣啓動和停止
在主節點上啓動spark集羣
/export/servers/spark/sbin/start-all.sh

在主節點上停止spark集羣
/export/servers/spark/sbin/stop-all.sh

●單獨啓動和停止
在 master 安裝節點上啓動和停止 master:
start-master.sh
stop-master.sh
在 Master 所在節點上啓動和停止worker(work指的是slaves 配置文件中的主機名)
start-slaves.sh
stop-slaves.sh

2.2.5. 查看web界面

正常啓動spark集羣后,查看spark的web界面,查看相關信息。
http://node01:8080/

2.2.6. 測試

●需求
使用集羣模式運行Spark程序讀取HDFS上的文件並執行WordCount

●集羣模式啓動spark-shell
/export/servers/spark/bin/spark-shell --master spark://node01:7077

●運行程序

sc.textFile("hdfs://node01:8020/wordcount/input/words.txt")
.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _)
.saveAsTextFile("hdfs://node01:8020/wordcount/output2")

●注意
集羣模式下程序是在集羣上運行的,不要直接讀取本地文件,應該讀取hdfs上的
因爲程序運行在集羣上,具體在哪個節點上我們運行並不知道,其他節點可能並沒有那個數據文件

2.3. standalone-HA高可用模式

2.3.1. 原理

Spark Standalone集羣是Master-Slaves架構的集羣模式,和大部分的Master-Slaves結構集羣一樣,存在着Master單點故障的問題。
如何解決這個單點故障的問題,Spark提供了兩種方案:
1.基於文件系統的單點恢復(Single-Node Recovery with Local File System)–只能用於開發或測試環境。
2.基於zookeeper的Standby Masters(Standby Masters with ZooKeeper)–可以用於生產環境。
在這裏插入圖片描述

2.3.2. 配置HA

該HA方案使用起來很簡單,首先啓動一個ZooKeeper集羣,然後在不同節點上啓動Master,注意這些節點需要具有相同的zookeeper配置。
●先停止Sprak集羣
/export/servers/spark/sbin/stop-all.sh

●在node01上配置:
vim /export/servers/spark/conf/spark-env.sh

●註釋掉Master配置
#export SPARK_MASTER_HOST=node01
●在spark-env.sh添加SPARK_DAEMON_JAVA_OPTS,內容如下:

export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER  -Dspark.deploy.zookeeper.url=node01:2181,node02:2181,node03:2181  -Dspark.deploy.zookeeper.dir=/spark"

參數說明
spark.deploy.recoveryMode:恢復模式
spark.deploy.zookeeper.url:ZooKeeper的Server地址
spark.deploy.zookeeper.dir:保存集羣元數據信息的文件、目錄。包括Worker、Driver、Application信息。

●scp到其他節點
scp /export/servers/spark/conf/spark-env.sh node02:/export/servers/spark/conf/
scp /export/servers/spark/conf/spark-env.sh node03:/export/servers/spark/conf/

2.3.3. 啓動zk集羣

zkServer.sh status
zkServer.sh stop
zkServer.sh start

2.3.4. 啓動Spark集羣

●node01上啓動Spark集羣執行
/export/servers/spark/sbin/start-all.sh

●在node02上再單獨只起個master:
/export/servers/spark/sbin/start-master.sh

●注意:
在普通模式下啓動spark集羣
只需要在主節點上執行start-all.sh 就可以了
在高可用模式下啓動spark集羣
先需要在任意一臺主節點上執行start-all.sh
然後在另外一臺主節點上單獨執行start-master.sh

●查看node01和node02
http://node01:8080/
http://node02:8080/
可以觀察到有一臺狀態爲StandBy

2.3.5. 測試HA

●測試主備切換
1.在node01上使用jps查看master進程id
2.使用kill -9 id號強制結束該進程
3.稍等片刻後刷新node02的web界面發現node02爲Alive
在這裏插入圖片描述
●測試集羣模式提交任務
1.集羣模式啓動spark-shell
/export/servers/spark/bin/spark-shell --master spark://node01:7077,node02:7077

2.運行程序

sc.textFile("hdfs://node01:8020/wordcount/input/words.txt")
.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _)
.saveAsTextFile("hdfs://node01:8020/wordcount/output3")

2.4. on yarn集羣模式

2.4.1. 準備工作
1.安裝啓動Hadoop(需要使用HDFS和YARN,已經ok)

2.安裝單機版Spark(已經ok)
注意:不需要集羣,因爲把Spark程序提交給YARN運行本質上是把字節碼給YARN集羣上的JVM運行,但是得有一個東西幫我去把任務提交上個YARN,所以需要一個單機版的Spark,裏面的有spark-shell命令,spark-submit命令

3.修改配置:
在spark-env.sh ,添加HADOOP_CONF_DIR配置,指明瞭hadoop的配置文件的位置
vim /export/servers/spark/conf/spark-env.sh

export HADOOP_CONF_DIR=/export/servers/hadoop/etc/hadoop
2.4.2. cluster模式

●說明
在企業生產環境中大部分都是cluster部署模式運行Spark應用
Spark On YARN的Cluster模式 指的是Driver程序運行在YARN集羣上

●補充Driver是什麼:
運行應用程序的main()函數並創建SparkContext的進程

●圖解
在這裏插入圖片描述
●運行示例程序
spark-shell是一個簡單的用來測試的交互式窗口
spark-submit用來提交打成jar包的任務

/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
--driver-memory 1g \
--executor-memory 1g \
--executor-cores 2 \
--queue default \
/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/jars/spark-examples_2.11-2.2.0.jar \
10

●查看界面
http://node01:8088/cluster
在這裏插入圖片描述

2.4.3. client模式[瞭解]

●說明
學習測試時使用,開發不用,瞭解即可
Spark On YARN的Client模式 指的是Driver程序運行在提交任務的客戶端

●圖解
在這裏插入圖片描述

●運行示例程序

/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \
--driver-memory 1g \
--executor-memory 1g \
--executor-cores 2 \
--queue default \
/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/jars/spark-examples_2.11-2.2.0.jar \
10
2.4.4. 兩種模式的區別

Cluster和Client模式最本質的區別是:Driver程序運行在哪裏!
運行在YARN集羣中就是Cluster模式,
運行在客戶端就是Client模式
當然還有由本質區別延伸出來的區別,面試的時候能簡單說出幾點就行
●cluster模式:生產環境中使用該模式
1.Driver程序在YARN集羣中
2.應用的運行結果不能在客戶端顯示
3.該模式下Driver運行ApplicattionMaster這個進程中,如果出現問題,yarn會重啓ApplicattionMaster(Driver)

●client模式:
1.Driver運行在Client上的SparkSubmit進程中
2.應用程序運行結果會在客戶端顯示

2.5. 兩種模式的區別

2.5.1. spark-shell

spark-shell是Spark自帶的交互式Shell程序,方便用戶進行交互式編程,用戶可以在該命令行下可以用scala編寫spark程序,適合學習測試時使用!

●示例
spark-shell可以攜帶參數
spark-shell --master local[N] 數字N表示在本地模擬N個線程來運行當前任務

spark-shell --master local[*] 表示使用當前機器上所有可用的資源
默認不攜帶參數就是–master local[
]

spark-shell --master spark://node01:7077,node02:7077 表示運行在集羣上

2.5.2. spark-submit

spark-submit命令用來提交jar包給spark集羣/YARN
spark-shell交互式編程確實很方便我們進行學習測試,但是在實際中我們一般是使用IDEA開發Spark應用程序打成jar包交給Spark集羣/YARN去執行。
spark-submit命令是我們開發時常用的!!!

示例:計算π
cd /export/servers/spark

/export/servers/spark/bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://node01:7077  \
--executor-memory 1g \
--total-executor-cores 2 \
/export/servers/spark/examples/jars/spark-examples_2.11-2.2.0.jar \
10
2.5.3. 參數總結

●Master參數形式

Master形式 解釋
local 本地以一個worker線程運行(例如非並行的情況).
local[N] 本地以K worker 線程 (理想情況下, N設置爲你機器的CPU核數).
local[*] 本地以本機同樣核數的線程運行.
spark://HOST:PORT 連接到指定的Spark standalone cluster master. 端口是你的master集羣配置的端口,缺省值爲7077.
mesos://HOST:PORT 連接到指定的Mesos 集羣. Port是你配置的mesos端口, 默認5050. 或者使用ZK,格式爲 mesos://zk://…
yarn-client 以client模式連接到YARN cluster. 集羣的位置基於HADOOP_CONF_DIR 變量找到.
yarn-cluster 以cluster模式連接到YARN cluster. 集羣的位置基於HADOOP_CONF_DIR 變量找到.

其他參數示例

–master spark://node01:7077 指定 Master 的地址
–name “appName” 指定程序運行的名稱
–class 程序的main方法所在的類
–jars xx.jar 程序額外使用的 jar 包
–driver-memory 512m Driver運行所需要的內存, 默認1g
–executor-memory 2g 指定每個 executor 可用內存爲 2g, 默認1g
–executor-cores 1 指定每一個 executor 可用的核數
–total-executor-cores 2 指定整個集羣運行任務使用的 cup 核數爲 2 個
–queue default 指定任務的對列
–deploy-mode 指定運行模式(client/cluster)

●注意:
如果 worker 節點的內存不足,那麼在啓動 spark-submit的時候,就不能爲 executor分配超出 worker 可用的內存容量。
如果–executor-cores超過了每個 worker 可用的 cores,任務處於等待狀態。
如果–total-executor-cores即使超過可用的 cores,默認使用所有的。以後當集羣其他的資源釋放之後,就會被該程序所使用。
如果內存或單個 executor 的 cores 不足,啓動 spark-submit 就會報錯,任務處於等待狀態,不能正常執行。

第三章 IDEA編寫Spark程序

3.1. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>cn.itcast</groupId>
    <artifactId>SparkDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <!-- 指定倉庫位置,依次爲aliyun、cloudera和jboss倉庫 -->
    <repositories>
        <repository>
            <id>aliyun</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </repository>
        <repository>
            <id>cloudera</id>
            <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
        </repository>
        <repository>
            <id>jboss</id>
            <url>http://repository.jboss.com/nexus/content/groups/public</url>
        </repository>
    </repositories>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <scala.version>2.11.8</scala.version>
        <scala.compat.version>2.11</scala.compat.version>
        <hadoop.version>2.7.4</hadoop.version>
        <spark.version>2.2.0</spark.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-hive_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-hive-thriftserver_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <!-- <dependency>
             <groupId>org.apache.spark</groupId>
             <artifactId>spark-streaming-kafka-0-8_2.11</artifactId>
             <version>${spark.version}</version>
         </dependency>-->
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming-kafka-0-10_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql-kafka-0-10_2.11</artifactId>
            <version>${spark.version}</version>
        </dependency>
 
        <!--<dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.6.0-mr1-cdh5.14.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>1.2.0-cdh5.14.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>1.2.0-cdh5.14.0</version>
        </dependency>-->
 
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.typesafe</groupId>
            <artifactId>config</artifactId>
            <version>1.3.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
    </dependencies>
 
    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
        <testSourceDirectory>src/test/scala</testSourceDirectory>
        <plugins>
            <!-- 指定編譯java的插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
            </plugin>
            <!-- 指定編譯scala的插件 -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.2.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                        <configuration>
                            <args>
                                <arg>-dependencyfile</arg>
                                <arg>${project.build.directory}/.scala_dependencies</arg>
                            </args>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.18.1</version>
                <configuration>
                    <useFile>false</useFile>
                    <disableXmlReport>true</disableXmlReport>
                    <includes>
                        <include>**/*Test.*</include>
                        <include>**/*Suite.*</include>
                    </includes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass></mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

3.2. 本地運行(統計單詞數量)

package cn.itcast.sparkhello

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}


object WordCount {
  def main(args: Array[String]): Unit = {
    //1.創建SparkContext
    val config = new SparkConf().setAppName("wc").setMaster("local[*]")
    val sc = new SparkContext(config)
sc.setLogLevel("WARN")
    //2.讀取文件
    //A Resilient Distributed Dataset (RDD)彈性分佈式數據集
    //可以簡單理解爲分佈式的集合,但是spark對它做了很多的封裝,
    //讓程序員使用起來就像操作本地集合一樣簡單,這樣大家就很happy了
    val fileRDD: RDD[String] = sc.textFile("D:\\授課\\190429\\資料\\data\\words.txt")
    //3.處理數據
    //3.1對每一行按空切分並壓平形成一個新的集合中裝的一個個的單詞
    //flatMap是對集合中的每一個元素進行操作,再進行壓平
    val wordRDD: RDD[String] = fileRDD.flatMap(_.split(" "))
    //3.2每個單詞記爲1
    val wordAndOneRDD: RDD[(String, Int)] = wordRDD.map((_,1))
    //3.3根據key進行聚合,統計每個單詞的數量
    //wordAndOneRDD.reduceByKey((a,b)=>a+b)
    //第一個_:之前累加的結果
    //第二個_:當前進來的數據
    val wordAndCount: RDD[(String, Int)] = wordAndOneRDD.reduceByKey(_+_)
    //4.收集結果
    val result: Array[(String, Int)] = wordAndCount.collect()
    result.foreach(println)
  }
}

3.3. 集羣運行(統計單詞數量)

●修改代碼

package cn.itcast.sparkhello

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}


object WordCount {
  def main(args: Array[String]): Unit = {
    //1.創建SparkContext
    val config = new SparkConf().setAppName("wc")//.setMaster("local[*]") 
    val sc = new SparkContext(config)
    sc.setLogLevel("WARN")
    //2.讀取文件
    //A Resilient Distributed Dataset (RDD)彈性分佈式數據集
    //可以簡單理解爲分佈式的集合,但是spark對它做了很多的封裝,
    //讓程序員使用起來就像操作本地集合一樣簡單,這樣大家就很happy了
    val fileRDD: RDD[String] = sc.textFile(args(0)) //文件輸入路徑
    //3.處理數據
    //3.1對每一行按空切分並壓平形成一個新的集合中裝的一個個的單詞
    //flatMap是對集合中的每一個元素進行操作,再進行壓平
    val wordRDD: RDD[String] = fileRDD.flatMap(_.split(" "))
    //3.2每個單詞記爲1
    val wordAndOneRDD: RDD[(String, Int)] = wordRDD.map((_,1))
    //3.3根據key進行聚合,統計每個單詞的數量
    //wordAndOneRDD.reduceByKey((a,b)=>a+b)
    //第一個_:之前累加的結果
    //第二個_:當前進來的數據
    val wordAndCount: RDD[(String, Int)] = wordAndOneRDD.reduceByKey(_+_)
    wordAndCount.saveAsTextFile(args(1))//文件輸出路徑
   //4.收集結果
   //val result: Array[(String, Int)] = wordAndCount.collect()
   //result.foreach(println)
  }
}

●打包
在這裏插入圖片描述

●上傳
在這裏插入圖片描述

●執行命令提交到Spark-HA集羣

/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/bin/spark-submit \
--class cn.itcast.sparkhello.WordCount \
--master spark://node01:7077,node02:7077 \
--executor-memory 1g \
--total-executor-cores 2 \
/root/wc.jar \
hdfs://node01:8020/aa.txt \
hdfs://node01:8020/cc

●執行命令提交到YARN集羣

/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/bin/spark-submit \
--class cn.itcast.sparkhello.WordCount \
--master yarn \
--deploy-mode cluster \
--driver-memory 1g \
--executor-memory 1g \
--executor-cores 2 \
--queue default \
/root/wc.jar \
hdfs://node01:8020/wordcount/input/words.txt \
hdfs://node01:8020/wordcount/output5

好了,以上內容就到這裏了。不知道小編本篇內容有沒有幫助到你呢。歡迎路過的朋友關注小編哦。各位朋友關注點贊是小編堅持下去的動力。小編會繼續爲大家分享更多的知識哦~~~。

我是小哪吒,目前是傳智的一名學子。我是一名互聯網行業的工具人,小編的座右銘:“我不生產代碼,我只做代碼的搬運工”…哈哈哈,我們下期見哦,Bye~

當你的才華還撐不起你的野心時,你就該努力。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章