爲開發和調試SPark應用程序設置的完整的開發環境。這裏,咱們將使用Java,其實SPark還支持使用Scala, Python和R。咱們將使用IntelliJ做爲IDE,由於咱們對於eclipse再熟悉不過了,這裏就使用IntelliJ進行練練手,因此咱們也將使用Maven做爲構建的管理器。在本篇結束時,您將瞭解如何設置IntelliJ,如何使用Maven管理依賴項,如何將SPark應用程序打包並部署到集羣中,以及如何將活動程序鏈接到調試器。java
(注意:指令可能因操做系統而異。在本教程中,咱們將使用IntelliJ版本:2018.2.1上的MAC OSX High Sierra. )node
經過選擇File > New > Project: ,再選擇 Maven > 單擊Nextapache
將項目命名以下:api
Hortonworks
SparkTutorial
1.0-SNAPSHOT
而後單擊下一個繼續。eclipse
最後,選擇項目名稱和位置。這些字段應該是自動填充的,因此讓咱們保持默認值便可:ssh
IntelliJ應該建立一個具備默認目錄結構的新項目。生成全部文件夾可能須要一兩分鐘。socket
讓咱們分解一下項目結構。maven
在繼續以前,讓咱們驗證幾個IntelliJ設置:分佈式
1.覈實import Maven projects automatically是ON.ide
2.覈實Project SDK和Project language level設置爲Java版本:
3.覈實Language level 設置爲Java版本:
在開始編寫SPark應用程序以前,咱們須要將SPark庫和文檔導入IntelliJ。爲此,咱們將使用Maven。這是必要的,若是咱們想要IntelliJ識別Spark代碼。要導入SPark庫,咱們將使用依賴關係管理器Maven。將如下行添加到文件put.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>hortonworks</groupId> <artifactId>SparkTutorial</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_2.11</artifactId> <version>2.2.1</version> </dependency> </dependencies> </project>
保存文件後,IntelliJ將自動導入運行SPark所需的庫和文檔。
對於咱們的第一個應用程序,咱們將構建一個簡單的程序,進行單詞計數。Download the file,將文件保存爲shakespeare.txt.
稍後,咱們但願SPark從HDFS(HadoopDistributedFileSystem)檢索這個文件,因此如今讓咱們把它放在那裏。要上傳到HDFS,首先要確保咱們的Ambari 沙箱已經啓動並運行。
如今咱們已經準備好建立應用程序了。在IDE中打開文件夾src/main/resources,這應該是自動爲您生成的。
接下來,選擇文件夾SRC/Main/java:
將其複製到您的新文件中:
public class Main { public static void main(String[] args) { System.out.println("Hello World"); } }
如今轉到IDE頂部的「Run」下拉菜單,而後選擇Run。而後選擇Main。若是全部設置都正確,IDE應該打印「HelloWorld」。如今咱們已經知道環境已正確設置,請用如下代碼替換該文件:
package Hortonworks.SparkTutorial; import org.apache.spark.api.java.JavaPairRDD; import org.apache.spark.api.java.JavaSparkContext; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.SparkConf; import scala.Tuple2; import java.util.Arrays; public class Main { public static void main(String[] args){ //Create a SparkContext to initialize SparkConf conf = new SparkConf().setMaster("local").setAppName("Word Count"); // Create a Java version of the Spark Context JavaSparkContext sc = new JavaSparkContext(conf); // Load the text into a Spark RDD, which is a distributed representation of each line of text JavaRDD<String> textFile = sc.textFile("src/main/resources/shakespeare.txt"); JavaPairRDD<String, Integer> counts = textFile .flatMap(s -> Arrays.asList(s.split("[ ,]")).iterator()) .mapToPair(word -> new Tuple2<>(word, 1)) .reduceByKey((a, b) -> a + b); counts.foreach(p -> System.out.println(p)); System.out.println("Total words: " + counts.count()); counts.saveAsTextFile("/tmp/shakespeareWordCount"); } }
如前所述,單擊Run>Run以運行文件。這應該運行Spark進行做業,並打印在莎士比亞shakespeare.txt中出現的每一個單詞的頻率。
由您的程序建立的文件能夠在上面代碼中指定的目錄中找到,在咱們的例子中,咱們使用/tmp/shakspeareWordCount.
注意,咱們已經設置了這一行:
setMaster("local")
這告訴SPark使用此計算機在本地運行,而不是在分佈式模式下運行。要在多臺機器上運行Spark,咱們須要將此值更改成 YARN。咱們稍後再看看怎麼作。
如今咱們已經瞭解瞭如何在IDE中直接部署應用程序。這是一種快速構建和測試應用程序的好方法,但這有點不切實際,由於SPark只在一臺機器上運行。在生產中,SPark一般會處理存儲在分佈式文件系統(如HDFS)上的數據(若是運行在雲中,則多是S3或Azure博客存儲)。SPark也一般在集羣模式下運行(即,分佈在許多機器上)。
那麼,首先,咱們將學習如何在Hortonworks沙箱(這是一個單節點Hadoop環境)上部署SPark,而後咱們將學習如何在雲中部署SPark。
雖然咱們仍然在一臺機器上運行SPark,可是咱們將使用HDFS和SEAR(集羣資源管理器)。這將比咱們以前所作的更接近於運行一個完整的分佈式集羣。咱們要作的第一件事是更改這一行:
JavaRDD<String> textFile = sc.textFile("src/main/resources/shakespeare.txt");
更改成:
JavaRDD<String> textFile = sc.textFile("hdfs:///tmp/shakespeare.txt");
將:
counts.saveAsTextFile("/tmp/shakespeareWordCount");
更改成:
counts.saveAsTextFile("hdfs:///tmp/shakespeareWordCount");
這告訴 Spark 要讀取和寫入HDFS,而不是本地。確保保存文件。
接下來,咱們將把這些代碼打包到一個編譯好的JAR文件中,這個JAR文件能夠部署在 sandbox沙箱上。了簡化咱們的生活,咱們將建立一個程序集JAR:一個包含咱們的代碼和咱們的代碼所依賴的全部JAR的JAR文件。經過將咱們的代碼打包成一個程序集,咱們保證在代碼運行時,全部依賴的JAR(在pu.xml中定義的)都會出現。
打開終端和CD到包含 pom.xml. 運行mvn package. 這將在文件夾中建立一個名爲「SparkTutver-1.0-SNAPSHOT.jar」的編譯JAR。
(注:若是MVN命令不起做用-請確保已成功安裝maven。)
將程序集複製到沙箱:
scp -P 2222 ./target/SparkTutorial-1.0-SNAPSHOT.jar root@sandbox-hdp.hortonworks.com:/root
打開第二個終端窗口,將ssh放入沙箱:
ssh -p 2222 root@sandbox-hdp.hortonworks.com
使用spark-submit 運行咱們的代碼。咱們須要指定主類、要運行的JAR和運行模式(本地或集羣):
spark-submit --class "Hortonworks.SparkTutorial.Main" --master local ./SparkTutorial-1.0-SNAPSHOT.jar
您的控制檯應該能夠看到出現的每一個單詞的頻率,以下所示:
... (comutual,1) (ban-dogs,1) (rut-time,1) (ORLANDO],4) (Deceitful,1) (commits,3) (GENTLEWOMAN,4) (honors,10) (returnest,1) (topp'd?,1) (compass?,1) (toothache?,1) (miserably,1) (hen?,1) (luck?,2) (call'd,162) (lecherous,2) ...
此外,若是在Ambari中打開「文件視圖」,您應該會看到/tmp/shakspeareWordCount下的結果。這代表結果也存儲在HDFS中。
在設置集羣以後,部署代碼的過程相似於部署到沙箱。咱們須要對集羣的JAR進行SCP:
scp -P 2222 -i "key.pem" ./target/SparkTutorial-1.0-SNAPSHOT.jar root@[ip address of a master node]:root
而後打開第二個終端窗口並將ssh插入主節點:
ssh -p 2222 -i "key.pem" root@[ip address of a master node]
而後使用 spark-submit運行咱們的代碼:
spark-submit --class "Hortonworks.SparkTutorial.Main" --master yarn --deploy-mode client ./SparkTutorial-1.0-SNAPSHOT.jar
注意,咱們指定了參數--master yarn ,而不是--master local. 這意味着咱們但願SPark在分佈式模式下運行,而不是在一臺機器上運行,而且咱們但願依賴SEARY(集羣資源管理器)來獲取可用的機器來運行做業。若是您不熟悉YARN,那麼若是您想要在同一個集羣上同時運行多個做業,則這一點尤其重要。若是配置正確,YARN隊列將提供不一樣的用戶或處理容許使用的羣集資源配額。它還提供了容許做業在資源可用時充分利用集羣的機制,以及在其餘用戶或做業開始提交做業時縮小現有做業的範圍。
參數--deploy-mode client ,指示要將當前計算機用做Spark的驅動程序機器。驅動程序機器是一臺啓動Spark做業的機器,也是工做完成後收集彙總結果的地方。或者,咱們能夠指定 --deploy-mode cluster ,這將容許YARN選擇驅動機。
重要的是要注意的是,一個寫得很差的SPark程序可能會意外地試圖將許多兆字節的數據帶回到驅動程序機器中,從而致使其崩潰。所以,不該該使用集羣的主節點做爲驅動程序機器。許多組織從所謂的邊緣節點提交火花做業,這是一個單獨的機器,不用於存儲數據或執行計算。因爲邊緣節點與集羣是分開的,因此它能夠在不影響集羣其他部分的狀況降低。邊緣節點還用於從集羣中檢索的聚合數據的數據科學工做。
例如,數據科學家可能從邊緣節點提交一份SPark做業,將10 TB數據集轉換爲1GB聚合數據集,而後使用R和Python等工具對邊緣節點進行分析。若是計劃設置邊緣節點,請確保機器沒有安裝DataNode或HostManager組件,由於它們是集羣的數據存儲和計算組件。
將正在運行的SPark程序鏈接到調試器,這將容許咱們設置斷點並逐行遍歷代碼。在直接從IDE運行時,調試SPark就像其餘程序同樣,可是調試遠程集羣須要一些配置。
在計劃提交Spark做業的機器上,從終端運行這一行:
export SPARK_JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8086
這將使您能夠在端口8086上附加調試器。您須要確保端口8086可以接收入站鏈接。而後在IntelliJ中 Run > Edit Configurations:
而後單擊左上角的+按鈕並添加一個新的遠程配置。用主機IP地址填充主機,以及使用端口8086.
若是在提交SPark做業後當即從IDE運行此調試配置,則調試器將附加,SPark將在斷點處中止。
注意:要從新提交單詞計數代碼,咱們必須首先刪除前面建立的目錄。使用命令:
hdfs dfs -rm -r /tmp/shakespeareWordCount
在沙箱外殼上刪除舊目錄。再次在沙箱外殼上提交火花做業,並在執行spark-submit命令。請記住,爲了運行您的代碼,咱們使用瞭如下命令:
spark-submit --class "Hortonworks.SparkTutorial.Main" --master yarn --deploy-mode client ./SparkTutorial-1.0-SNAPSHOT.jar