spark代碼 spark-submit提交yarn-cluster模式

worldcount yarn-cluster集羣作業運行

之前寫的是一個windows本地的worldcount的代碼,當然這種功能簡單 代碼量少的 也可以直接在spark-shell中直接輸scala指令。

但是在項目開發 企業運用中,因爲本地的資源有限 使得無法發揮出spark的真正優勢。因此 在這裏 我就spark代碼在集羣中運行 做一些補充講述。

我使用的環境是: idea編譯器 jdk1.7 scala 2.10 spark 1.6.0(因爲公司服務器普遍搭建的還是cdh5.15集羣,上面的spark版本是舊時的1.6.0版本 2.x上面的一些功能不能使用 例如SparkSession Spark.ml包 這裏還需要注意一點的是在maven打包時 如果編譯打包的環境是jdk1.8有可能會出現打包不成功 這是因爲jdk與scala二者版本不兼容導致 建議讀者將jdk換成1.7 或者提高scala版本)

1. 首先搭建idea maven環境 添加相應依賴

關於idea中配置maven環境之類的,還有什麼jdk之類的搭建,南國在這裏就不做篇幅說明了。 這些屬於基本操作,不熟悉操作的網上有許多資料,比較簡單。

這裏我主要給出項目所需要的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>Huawei</groupId>
    <artifactId>Spark</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <spark.version>1.6.0-cdh5.15.0</spark.version>
        <scala.version>2.10</scala.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_${scala.version}</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming_${scala.version}</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_${scala.version}</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-hive_${scala.version}</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-mllib_${scala.version}</artifactId>
            <version>${spark.version}</version>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <!--  scala-maven-plugin:編譯scala程序的Maven插件 -->
                <plugin>
                    <groupId>net.alchim31.maven</groupId>
                    <artifactId>scala-maven-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <!--  maven-compiler-plugin:編譯java程序的Maven插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <!--  編譯scala程序的Maven插件的一些配置參數 -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>scala-compile-first</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>add-source</goal>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>scala-test-compile</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!--  編譯java程序的Maven插件的一些配置參數 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!--  maven-shade-plugin:打jar包用的Mavne插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.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>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

這裏 我強調在pom.xml中比較重要的地方:
properities:重要的屬性 我們可以將所添加依賴所屬的版本添加進去
dependency: 依賴 也就是項目具體所要調用的庫文件 包等
plugins: 插件 這裏我主要配置的是打包scala java程序所需要的Maven插件

2. scala程序編寫並打包到集羣中運行

源代碼:

package com.huawei.xjh

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

/**
  * Created by x50005784 on 2019/7/15.
  */
object wc {
  def main(args: Array[String]): Unit = {
    val conf=new SparkConf().setAppName("wc")
    val sc=new SparkContext(conf)
    val wc=sc.textFile(args(0)).flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
//    wc.foreach(print)
    wc.saveAsTextFile(args(1))
    sc.stop() //釋放資源
  }
}

注意:寫提交到集羣中的程序代碼最好在放在指定的包中,idea和eclipse不同 程序默認編寫在Main下面,程序代碼前是沒有包名的,這種情況下 當你打包提交到spark-submit中運行時,程序難以正確都找到你想要運行代碼的類名,而且 當你項目中的代碼越寫越多時,就越難以分清。 所以,何不將你的代碼放在某個特定包名下了。

Maven打包:
如果你代碼所在的項目工程之前 已經打包過,首先進行clean
在這裏插入圖片描述
然後點擊package進行打包,網上對於在idea中打包的方法有幾種,但其他方法過程太過繁瑣 囉嗦,直接雙擊package進行打包
在這裏插入圖片描述
在console中顯示BUILD SUCCESS表示打包成功,我們在項目工程的路徑中target即可找到你剛纔打包成功的jar。 如果顯示的BUILDFAILURE則說明打包中出現了報錯,努力找原因去把他解決,你一定沒問題的!!
在這裏插入圖片描述
在這裏插入圖片描述
上傳到yarn集羣運行
一般而言,企業中 spark-shell 使用的yarn-client模式,例如下圖
在這裏插入圖片描述
我在上圖標紅的幾處 讀者細看,關於集羣中的配置 可借鑑。
yarn-client模式主要用於本地測試,client在本地 運行日誌可直接在本地看到;
yarn-cluster真正的集羣模式,這也是我們在日常應用中最常用的集羣模式。聰明的你可能說 spark不是還有standalone集羣模式,是的,但是standalone是spark自身的集羣模式,他和其他mapreduce hive zookeeper等常用的大數據服務是分開的。在應用中,我們一般使用yarn作爲珍格格大數據集羣的資源管理,畢竟yarn模式是現在最常用的。

具體的操作:

  1. 首先將jar傳輸到linux系統上,這個根據你自己所用的shell遠程登錄的工具相關搜索一下 就行。傳輸的原理 就是ftp協議。這裏我使用的MobaXterm, 他直接將所傳輸的文件 直接拖到linux中
    在這裏插入圖片描述
  2. 確保你的集羣正常啓動,提前設置好輸入 輸出路徑 在spark-submit中提交作業
    這裏 確保你的hadoop saprk服務正常啓動
    然後在spark-submit中提交作業
spark-submit --master yarn --deploy-mode cluster --driver-memory 500m --executor-memory 500m --executor-cores 1 --class com.huawei.xjh.wc /home/x50005784/Spark-1.0-SNAPSHOT.jar hdfs://cscloud-rs-hadoop293.huawei.com:8020/user/x50005784/test.txt hdfs://cscloud-rs-hadoop293.huawei.com:8020/user/x50005784/output

這裏簡要說明指令的含義:
–master 運行模式
–driver-memory 內存大小
–executor-memory –executor-cores 執行器設置
–class 代碼所在的類
後面兩個爲代碼中的兩個輸入路徑
在這裏插入圖片描述
系統運行直到提示SUCCEEDED
我們還可以在yarn管理資源的8088看到我們在運行的spark作業
在這裏插入圖片描述
3. 登錄HDFS查看結果文件
在這裏插入圖片描述

Java程序編寫並打包到集羣中運行

scala代碼在集羣中成功運行之後,實現Java代碼的集羣運行運行 就變得簡單多了。相比較於scala代碼而言,Java代碼看上去就顯得有些累贅 但是現在的企業運用中 前端 後臺使用Java的居多,在日常應用中 Java也是必須要掌握的。

我們在同一項目中新建Java類
在這裏插入圖片描述
編寫Java代碼:

package com.huawei.xjh;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;
import scala.Tuple2;

import java.util.Arrays;


/**
 * Created by x50005784 on 2019/7/15.
 */
public class JavaWC {
    public static void main(String[] args) {
        SparkConf conf=new SparkConf().setAppName("JavaWC");
        JavaSparkContext jsc=new JavaSparkContext(conf);
        final JavaRDD<String> lines=jsc.textFile(args[0]);

        JavaRDD<String> wc=lines.flatMap(new FlatMapFunction<String, String>() {
            @Override
            public Iterable<String> call(String line) throws Exception {
                return Arrays.asList(line.split(" "));
            }
        });
        JavaPairRDD<String,Integer> ones=wc.mapToPair(new PairFunction<String, String, Integer>() {
            @Override
            public Tuple2<String, Integer> call(String s) throws Exception {
                return new Tuple2<String, Integer>(s,1);
            }
        });
        JavaPairRDD<String,Integer> counts=ones.reduceByKey(new Function2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer v1, Integer v2) throws Exception {
                return v1+v2;
            }
        });
        counts.saveAsTextFile(args[1]);
        jsc.stop(); //釋放資源
    }
}

Java代碼的邏輯 和上述的scala意義一樣,只是代碼實現有些不同。所以 我在這裏沒有寫什麼註釋
後續的打包過程和上述scala一樣,只不過 在spark-submit中記得修改成爲Java所在的類和包名。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章