IDEA開發(fā)Spark應(yīng)用并提交本地Spark 2.1.0 standalone集群運行

本文主要參考了如下兩篇博文:

Windows下IntelliJ IDEA中調(diào)試Spark Standalone

怎么解決java.lang.NoClassDefFoundError錯誤

一、通過IDEA連接遠(yuǎn)程集群運行應(yīng)用就是個大坑。。

寫在2017年10月3日凌晨0點57分:

最初這篇博文的名字是“IDEA開發(fā)Spark應(yīng)用并提交遠(yuǎn)程Spark 2.1.0 standalone集群運行”,當(dāng)時以不能SSH免密碼登錄遠(yuǎn)程主機為由,直接連接本地集群運行應(yīng)用,后來又嘗試了一下通過IDEA連接部署在實驗室服務(wù)器上的Spark集群來運行應(yīng)用,然后就發(fā)現(xiàn)這里實在是坑太多。如果部署模式是“client”,則會在本地主機起一個driver進程,而從本地主機序列化分發(fā)jar包到集群各從節(jié)點要求本地主機能夠SSH免密碼登錄各從節(jié)點?。。ó?dāng)然運行時只需要網(wǎng)絡(luò)互通即可)如果部署模式是“cluster”,然后IDEA運行項里配置“VM options”為-Dspark.submit.deployMode=cluster,結(jié)果很不幸,driver依然在本機運行,然后執(zhí)行器和驅(qū)動器無法互相通信。

通過spark-submit腳本,設(shè)置部署模式為cluster,這樣driver會在某一個worker上啟動,然而我們的jar包依然在本機,還是需要序列化分發(fā)到各節(jié)點,然而這樣就需要本地主機可以免密碼SSH登錄所有集群節(jié)點!!

當(dāng)然本地開發(fā)測試還是可以通過IDEA連接本地集群運行應(yīng)用,畢竟借助IDEA,我們只需點一下“運行”即可,還是方便很多。所以啊,本文決定把題目和內(nèi)容改一下,把遠(yuǎn)程改成本地!

二、前言

雖然之前也有許多博文講如何基于IDEA來開發(fā)運行Spark應(yīng)用,但是他們大多數(shù)都以本地模式運行(例如:conf.setMaster("local[*]")),而本地模式只是在本機以多線程方式運行Spark應(yīng)用,這與standalone模式運行有很大差別。

此外,雖然也有一些博文介紹了如何使用IDEA將開發(fā)的Spark應(yīng)用提交到本地Spark集群執(zhí)行,但是這些博文涉及的Spark版本都比較老,較新版本的Spark(例如2.1.0及以后)取消了lib目錄,也就是說新版本沒有assembly jar包(例如:spark-assembly-1.5.2-hadoop2.6.0.jar),取而代之的是jars目錄,這就使得在新版本里,依賴包的添加發(fā)生了一些變化。

綜上所述,還是很有必要重新寫一篇關(guān)于IDEA提交Spark應(yīng)用到本地集群的博文,這篇博文關(guān)注點在于如何讓IDEA連接Spark 2.1.0 standalone集群

這篇博文首先介紹了幾種Spark應(yīng)用開發(fā)和運行的方式,然后介紹了如何通過IDEA連接Spark standalone集群來開發(fā)運行Spark應(yīng)用,最后對可能發(fā)生的錯誤給出了解決方法。

注意:由于大部分情況下,我們不能隨意訪問遠(yuǎn)程主機,例如不能直接ssh免密碼登錄遠(yuǎn)程主機,所以本文只是將IDEA連接到了本機的Spark 2.1.0 standalone集群,也就是將Spark應(yīng)用提交到本地集群運行。

三、開發(fā)環(huán)境

操作系統(tǒng):CentOS 7

Spark:2.1.0

IDEA:社區(qū)版2016.3.1

Scala:2.11.8

JDK:1.8.0_111

四、Spark應(yīng)用開發(fā)運行綜述

1、開發(fā)

用Scala開發(fā)Spark應(yīng)用,官方推薦使用SBT項目構(gòu)建工具,當(dāng)然由于Scala基于JVM,所以使用Maven也是可以的。有時我們想在項目中混合使用Java和Scala,這時Maven就成了最佳選擇,當(dāng)然這個時候就需要在pom.xml中配置Java和Scala的編譯工具。

可以純粹使用項目構(gòu)建工具SBT或者Maven來完成Spark開發(fā)(不借助IDE),包括按照模板創(chuàng)建項目、編譯、構(gòu)建項目、打包和發(fā)布等等。當(dāng)然也可以借助IDEA集成的SBT和Maven插件來高效完成上述工作(IDE+項目構(gòu)建工具)。

當(dāng)然這篇博文只使用IDEA來完成上述工作,沒有使用項目構(gòu)建工具。

2、運行

開發(fā)完項目后當(dāng)然就要運行我們的Spark應(yīng)用了,運行也有好幾種方式。

(1)第一種方式主要用于開發(fā)測試完畢,準(zhǔn)備線上運行。借助IDEA或者使用項目構(gòu)建工具將Spark應(yīng)用打成Jar包,接著上傳到服務(wù)器(windows使用FileZilla,Linux使用scp命令),然后通過spark-submit腳本連接集群(通過master的URL可以連接到不同集群)并運行Spark應(yīng)用。

(2)第二種方式是本地測試。打包后直接提交本地Spark standalone集群(偽分布式,本機運行master和worker)。

(3)開發(fā)時會頻繁地運行Spark應(yīng)用,前面兩種方式就顯得比較麻煩(需要打包、上傳、提交),第三種方式用于開發(fā)過程中。通過IDEA連接Spark standalone集群,只需點擊IDEA的“運行”按鈕即可運行Spark應(yīng)用(不需要手動打包,不需要上傳到服務(wù)器,不需要手動運行spark-submit腳本)。當(dāng)然也可以以local模式運行(可以在應(yīng)用程序中使用conf.setMaster("local[*]")或者在IDEA運行項中配置“VM options”為-Dspark.master=local[*],然后點擊IDEA的“運行”按鈕),此時在本地以多線程方式運行Spark應(yīng)用,local模式不需要開啟Spark集群。

下面介紹如何通過IDEA連接Spark standalone集群,來快速開發(fā)調(diào)試Spark應(yīng)用。

五、通過IDEA將開發(fā)的Spark應(yīng)用提交到本地Spark 2.1.0 standalone集群運行

1、前提要求(版本信息見“開發(fā)環(huán)境”)

(1)需要有一個Spark standalone集群,不需要hdfs,能啟動運行即可。

(2)IntelliJ IDEA、Scala插件、Java JDK、Scala SDK都已安裝配置完畢。

2、創(chuàng)建項目

新建一個Scala項目。啟動IntelliJ IDEA,選擇New Project,然后選擇Scala,點擊下一步,接著配置項目名稱、SDK版本和項目位置等。注意:IDEA中項目的概念類似于Eclipse中的工作區(qū)(workspace),而IDEA中模塊(module)的概念類似于Eclipse中的項目。

圖1 新建一個Scala項目
圖2 配置項目(名稱、SDK和位置等)

3、添加依賴的Jar包

如前文所述,較新版本的Spark(例如2.1.0及以后)取消了lib目錄,取而代之的是jars目錄,所以這里依賴包的添加相比于舊版本發(fā)生了一些變化。

首先按如下步驟(圖3、圖4和圖5)為我們開發(fā)的Spark應(yīng)用添加依賴,把Spark 2.1.0中的jars目錄整個添加進來(這樣jars目錄里所有的jar包都會被添加到classpath中),并調(diào)整它的scope為“編譯”(這樣我們后面打的包會包括jars目錄里所有的jar包)。

看到這里,讀者可能會心生疑惑,我們開發(fā)的應(yīng)用事實上用不著這么多的jar包,例如關(guān)于機器學(xué)習(xí)或者流計算的jar包我們肯定用不上,另外,這些jar包Spark集群中都有,為什么還要把scope設(shè)為“編譯”呢?

如果是手動打包然后通過spark-submit腳本運行應(yīng)用的話,確實只需添加幾個jar包即可,而且scope還應(yīng)該設(shè)為“provided”,這樣可以減少最終生成jar包的大小。然而通過IDEA提交Spark應(yīng)用到本地集群,還就必須按前述步驟做,否則會報java.lang.NoClassDefFoundError的錯誤(不把整個jars目錄添加到classpath中會報錯,不把它的scope設(shè)為“編譯”也會報錯)。

java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError這兩種錯誤看起來有點像,但它們是完全不同的。NoClassDefFoundError是指JVM運行時無法在classpath中找到對應(yīng)的類進行加載;而ClassNotFoundException是指編譯的時候classpath中找不到對應(yīng)的類。

圖3 為Spark應(yīng)用添加依賴
圖4 把Spark 2.1.0中的jars目錄整個添加進來
圖5 調(diào)整scope為“編譯”

4、完成代碼

在src目錄下新建一個名為WordCount的object,這是我們的main class。接著在源文件中輸入Spark的HelloWorld程序——WordCount。因為這里連接的是本地Spark 2.1.0 standalone集群,所以直接從本地讀取文件。

有兩點需要注意:

(1)因為要提交Spark應(yīng)用到本地集群運行,所以需要配置master的URL,可以在應(yīng)用程序中使用conf.setMaster("spark://host:port")或者在IDEA運行項中配置“VM options”為-Dspark.master=spark://host:port,“host”就是master所在的主機名,如果沒有在/etc/hosts中建立主機名和IP的映射關(guān)系,則直接使用IP。

(2)通過conf.setJars(List("/path/to/xxx.jar")),告訴Spark集群我們要提交的包含作業(yè)代碼的jar包在哪里,記住路徑中千萬別包含中文,不然會出錯。

圖6 在src目錄下新建WordCount.scala
圖7 輸入WordCount代碼

5、配置打包

即便是通過IDEA提交Spark應(yīng)用到本地集群執(zhí)行,我們還是需要配置打包。Spark應(yīng)用之所以能夠分布式運行,正是因為jar包被分發(fā)到了各個worker之中。

我們將應(yīng)用程序打成可執(zhí)行jar包,并為它設(shè)置main class,然后再把“構(gòu)建項目自動打包”的選項勾上,這樣才能做到點擊“運行”就提交到本地集群運行。

圖8 將Spark應(yīng)用打包
圖9 可執(zhí)行jar包,配置main class
圖10 構(gòu)建項目時自動打包

6、配置IDEA運行項

這里結(jié)合spark-submit腳本,說明一下IDEA是怎么做到一鍵提交Spark應(yīng)用到本地集群執(zhí)行。當(dāng)我們點擊“運行”按鈕,IDEA會自動構(gòu)建項目,并重新打包;然后根據(jù)應(yīng)用程序中的conf.setJars(List("/path/to/xxx.jar")),可以找到需要提交到集群的jar包;根據(jù)conf.setMaster("spark://host:port")或者IDEA運行項中“VM options”的-Dspark.master=spark://host:port連接到Spark standalone集群,這相當(dāng)于配置spark-submit腳本的--master;然后IDEA運行項中的“Main class”指定了Spark應(yīng)用的main class,這相當(dāng)于配置spark-submit腳本的--class;如果還想為Spark應(yīng)用做一些其他配置,可以通過conf.set("xxx", "XXX")或者“VM options”添加一些其他配置(形如-Dxxx.yyy=zzz);傳給Spark應(yīng)用main方法的參數(shù)在“Program arguments”中輸入。

所以使用IDEA連接集群,通過IDEA將Spark應(yīng)用提交本地集群執(zhí)行,其實就是IDEA替我們完成了打包和執(zhí)行spark-submit腳本的工作。

圖11 配置IDEA運行項

7、啟動Spark集群

在點擊“運行”按鈕之前,需要確保目標(biāo)本地Spark standalone集群已經(jīng)啟動。

注意:我們開發(fā)時使用的Spark版本要和本地集群一致。

8、運行,觀察IDEA控制臺結(jié)果,觀察Spark Web UI。

終于到了最后一步,點擊“運行”按鈕,見證奇跡吧(2333333......)。

可以看到,控制臺成功輸出了詞頻統(tǒng)計。也可以打開Spark Web UI,詳細(xì)看一下應(yīng)用執(zhí)行情況。

圖12 控制臺輸出結(jié)果
圖13 Spark Web UI查看應(yīng)用詳細(xì)執(zhí)行情況

六、可能出現(xiàn)的錯誤

1、可能會出現(xiàn)如下錯誤:創(chuàng)建SparkContext時出現(xiàn)異常

java.net.BindException: Cannot assign requested address: Service 'sparkDriver' failed after 16 retries (starting from 0)! Consider explicitly setting the appropriate port for the service 'sparkDriver '(for example spark.ui.port for SparkUI) to an available port or increasing spark.port.maxRetries.

解決方法:在IDEA運行項“VM options”中加入“-Dspark.driver.host=127.0.0.1”和“-Dspark.driver.port=7077” 這兩項, 配置driver進程在本機的7077端口運行。

2、還可能出現(xiàn)這個錯誤:Hadoop權(quán)限錯誤

org.apache.hadoop.security.AccessControlException: Permission denied: user=yourUsername, access=WRITE, inode="/user/otherUsername/":otherUsername:supergroup:drwxr-xr-x

這是因為,HDFS中每個用戶都有自己的home目錄(與Linux系統(tǒng)一致),用戶自己的目錄只有該用戶擁有寫權(quán)限,遠(yuǎn)程連接Spark集群運行應(yīng)用時,若使用本機用戶嘗試對其他用戶在HDFS中的home目錄進行寫操作,會出現(xiàn)這個問題。

解決辦法:

(1)修改Hadoop 配置文件hdfs-site.xml,設(shè)置dfs.permissions.enabled為false即可,這樣不會再有權(quán)限限制,具體如圖14所示。當(dāng)然,開發(fā)測試完了最好還是把這個權(quán)限限制機制打開。

圖14 修改Hadoop配置文件hdfs-site.xml

(2)使用和遠(yuǎn)程集群一致的用戶,或者在同名用戶home目錄下進行寫操作。


轉(zhuǎn)載請注明如下內(nèi)容:

文章來自簡書,作者:就是楊宗

原文鏈接:http://www.lxweimin.com/p/b4e4658c459c

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內(nèi)容