Spark的Java開發環境構建

  爲開發和調試SPark應用程序設置的完整的開發環境。這裏,咱們將使用Java,其實SPark還支持使用Scala, Python和R。咱們將使用IntelliJ做爲IDE,由於咱們對於eclipse再熟悉不過了,這裏就使用IntelliJ進行練練手,因此咱們也將使用Maven做爲構建的管理器。在本篇結束時,您將瞭解如何設置IntelliJ,如何使用Maven管理依賴項,如何將SPark應用程序打包並部署到集羣中,以及如何將活動程序鏈接到調試器。java

1、建立一個新的IntelliJ項目

  (注意:指令可能因操做系統而異。在本教程中,咱們將使用IntelliJ版本:2018.2.1上的MAC OSX High Sierra. )node

  經過選擇File > New > Project:         ,再選擇 Maven > 單擊Nextapache

 

將項目命名以下:api

  • GroupId:Hortonworks
  • ArtifactId:SparkTutorial
  • 版本:1.0-SNAPSHOT

  而後單擊下一個繼續。eclipse

  最後,選擇項目名稱和位置。這些字段應該是自動填充的,因此讓咱們保持默認值便可:ssh

  IntelliJ應該建立一個具備默認目錄結構的新項目。生成全部文件夾可能須要一兩分鐘。socket

  讓咱們分解一下項目結構。maven

  • .IDEA:這些是IntelliJ配置文件。
  • SRC:源代碼。大部分代碼應該進入主目錄。應該爲測試腳本保留測試文件夾。
  • 目標:當您編譯您的項目時,它將位於這裏。
  • xml:Maven配置文件。咱們將向您展現如何使用該文件導入第三方庫和文檔。

  在繼續以前,讓咱們驗證幾個IntelliJ設置:分佈式

    1.覈實import Maven projects automatically是ON.ide

    •   Preferences > Build, Execution, Deployment > Build Tools > Maven > Importing

    2.覈實Project SDK和Project language level設置爲Java版本:

    •   File > Project Structure > Project

 

 

    3.覈實Language level 設置爲Java版本:

    •   File > Project Structure > Module

 

2、Maven配置

  在開始編寫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>
須要導入put.xml的代碼

  保存文件後,IntelliJ將自動導入運行SPark所需的庫和文檔。

 

3、建立SPark應用程序

  本地部署

  對於咱們的第一個應用程序,咱們將構建一個簡單的程序,進行單詞計數。Download the file,將文件保存爲shakespeare.txt.

  稍後,咱們但願SPark從HDFS(HadoopDistributedFileSystem)檢索這個文件,因此如今讓咱們把它放在那裏。要上傳到HDFS,首先要確保咱們的Ambari 沙箱已經啓動並運行。

  • 導航到sandbox-hdp.hortonworks.com:8080
  • 使用用戶名/密碼登陸
  • 一旦您登陸到Ambari Manager,鼠標在右上角的下拉菜單上並單擊文件視圖.
  • 打開TMP文件夾並單擊上傳按鈕在右上角上傳文件。確保它的名字shakespeare.txt.

 

  如今咱們已經準備好建立應用程序了。在IDE中打開文件夾src/main/resources,這應該是自動爲您生成的。

  接下來,選擇文件夾SRC/Main/java:

  • 右鍵單擊文件夾並選擇New > Java Class
  • 新建類文件: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。

   部署到Sandbox

  雖然咱們仍然在一臺機器上運行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中。

 

4、部署到雲端

  在設置集羣以後,部署代碼的過程相似於部署到沙箱。咱們須要對集羣的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組件,由於它們是集羣的數據存儲和計算組件。

 

5、現場調試

  將正在運行的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

相關文章
相關標籤/搜索