前言
本章將介紹如何通過IDEA構建Spark應用,並最終部署。
構建應用
Java應用
1、新建一個maven項目,並在POM中添加如下依賴:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency> <!-- Spark dependency -->
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
2、基於java8編寫一個main類,讀取spark的README.md文件,統計包含a、b分別有多少行:
public class SimpleJavaApp {
public static void main(String[] args) {
String logFile = "D:/spark-2.3.0-bin-hadoop2.7/README.md";
SparkConf conf = new SparkConf().setMaster("local[8]");
SparkSession spark = SparkSession.builder().config(conf).appName("Simple Application").getOrCreate();
Dataset<String> logData = spark.read().textFile(logFile).cache();
long numAs = logData.filter((FilterFunction<String>) str -> str.contains("a")).count();
long numBs = logData.filter((FilterFunction<String>) str -> str.contains("b")).count();
System.out.println("Lines with a: " + numAs + ", lines with b: " + numBs);
spark.stop();
}
}
Note:
- 通過SparkConf設定master參數,即可設定運行計算模式,先主要介紹Local模式:
Local模式就是運行在一臺計算機上的模式,通常就是用於在本機上練手和測試,有如下幾個方式:
- local: 所有計算都運行在一個線程當中,沒有任何並行計算,通常我們在本機執行一些測試代碼,或者練手,就用這種模式;
- local[K]: 指定使用幾個線程來運行計算,比如local[4]就是運行4個worker線程。通常我們的cpu有幾個core,就指定幾個線程,最大化利用cpu的計算能力;
- local[*]: 這種模式直接幫你按照cpu最多cores來設置線程數了;
實際的大規模計算還是需要cluster模式。
3、控制檯打印:
Scala應用
Scala 源代碼被編譯成Java字節碼,所以它可以運行於JVM之上,並可以調用現有的Java類庫。而Spark正是由Scala開發的,所以天然通過Scala構建的應用將是最佳方案,本小節將直接在當前項目中採用scala實現相同功能。
1、在idea中添加scala類庫配置:
2、編寫main方法如下:
object SimpleApp {
def main(args: Array[String]) {
val logFile = "D:/spark-2.3.0-bin-hadoop2.7/README.md"
val conf = new SparkConf().setMaster("local[8]")
val spark = SparkSession.builder.config(conf).appName("Simple Application").getOrCreate()
val logData = spark.read.textFile(logFile).cache()
val numAs = logData.filter(line => line.contains("a")).count()
val numBs = logData.filter(line => line.contains("b")).count()
println(s"Lines with a: $numAs, Lines with b: $numBs")
spark.stop()
}
}
3、控制檯打印:
Local模式部署
>spark-submit --class com.shf.spark.SimpleJavaApp --master local[4] --name demo D:\learnworkspace\spark-demo\target\spark-demo-1.0-SNAPSHOT.jar
查看到如下打印信息表明部署成功:
擴展
上述的開發環境調試和部署均採用local模式,實際生產者中必須採用cluster模式,先簡單介紹下概念:
cluster模式
cluster模式肯定就是運行很多機器上了,但是它又分爲以下三種模式,區別在於誰去管理資源調度。
這種模式下,Spark會自己負責資源的管理調度。它將cluster中的機器分爲master機器和worker機器,master通常就一個,可以簡單的理解爲那個後勤管家,worker就是負責幹計算任務活的苦勞力。具體怎麼配置可以參考
Spark Standalone Mode使用standalone模式示例:
/bin/spark-submit --cluster cluster_name --master spark://host:port ...
--master就是指定master那臺機器的地址和端口,我想這也正是--master參數名稱的由來吧。
mesos模式
這裏就很好理解了,如果使用mesos來管理資源調度,自然就應該用mesos模式了,示例如下:
/bin/spark-submit --cluster cluster_name --master mesos://host:port ...
yarn模式
同樣,如果採用yarn來管理資源調度,就應該用yarn模式,由於很多時候我們需要和mapreduce使用同一個集羣,所以都採用Yarn來管理資源調度,這也是生產環境大多采用yarn模式的原因。yarn模式又分爲yarn cluster模式和yarn client模式:
- yarn cluster: 這個就是生產環境常用的模式,所有的資源調度和計算都在集羣環境上運行。
- yarn client: 這個是說Spark Driver和ApplicationMaster進程均在本機運行,而計算任務在cluster上。