Reprint: snail Long Acts -Spark study notes [four] Spark cluster using spark-submit submit jar task package of practical experience 

First, the problems encountered

Because you can easily and quickly run a Scala program under IDEA, it has not previously submitted package packaged jar task in the habit of using the terminal Spark-submit, but it can only be performed in local mode, in a lot of posts online search settings VM parameters spark cluster can not start, because the experimental task under IDEA emergency only temporarily give up job submission, and then submitted to change the use of the terminal by the spark-submit-packaged jar task.

Two, spark-shell Features

$ SPARK_HOME enter the directory, enter bin / spark-submit --help can use to get help for the command.



--master  MASTER_URL                          spark://host:port, mesos://host:port, yarn, or local.

Operation of the driver --deploy-mode DEPLOY_MODE, client running the machine, cluster running on a cluster

To run the application package --class CLASS_NAME class

--name NAME Application Name

--jars jar JARS local driver package list separated by commas and executor classpath

--py-files PY_FILES separated by commas placed on the Python application PYTHONPATH .zip, .egg, .py Files

--files FILES separated by commas to be placed in each executor working directory list of files

--properties-file FILE file attribute setting application placement, the default is conf / spark-defaults.conf

--driver-memory MEM driver memory size, default 512M

--driver-java-options driver of java options

--driver-library-path                                    driver的库路径Extra library path entries to pass to the driver

Classpath --driver-class-path driver and a jar package --jars added automatically included in the classpath

--executor-memory MEM executor memory size, default 1G

Spark standalone with cluster deploy mode only:

--driver-cores NUM driver uses the kernel number, the default is 1

--supervise If you set this parameter, driver failure will restart

Spark standalone and Mesos only:

--total-executor-cores NUM executor used the total number of nuclear

YARN-only:

--executor-cores NUM number of cores per executor used, default 1

--queue QUEUE_NAME 提交应用程序给哪个YARN的队列,默认是default队列

--num-executors NUM 启动的executor数量,默认是2个

--archives ARCHIVES 被每个executor提取到工作目录的档案列表,用逗号隔开

关于以上spark-submit的help信息,有几点需要强调一下:

关于--master  --deploy-mode,正常情况下,可以不需要配置--deploy-mode,使用下面的值配置--master就可以了,使用类似 --master spark://host:port --deploy-mode cluster会将driver提交给cluster,然后就将worker给kill的现象。

Master URL 含义

local 使用1个worker线程在本地运行Spark应用程序

local[K] 使用K个worker线程在本地运行Spark应用程序

local[*] 使用所有剩余worker线程在本地运行Spark应用程序

spark://HOST:PORT 连接到Spark Standalone集群,以便在该集群上运行Spark应用程序

mesos://HOST:PORT 连接到Mesos集群,以便在该集群上运行Spark应用程序

yarn-client 以client方式连接到YARN集群,集群的定位由环境变量HADOOP_CONF_DIR定义,该方式driver在client运行。

yarn-cluster 以cluster方式连接到YARN集群,集群的定位由环境变量HADOOP_CONF_DIR定义,该方式driver也在集群中运行。

如果要使用--properties-file的话,在--properties-file中定义的属性就不必要在spark-sumbit中再定义了,比如在conf/spark-defaults.conf 定义了spark.master,就可以不使用--master了。关于Spark属性的优先权为:SparkConf方式 > 命令行参数方式 >文件配置方式,具体参见Spark1.0.0属性配置。

和之前的版本不同,Spark1.0.0会将自身的jar包和--jars选项中的jar包自动传给集群。

Spark使用下面几种URI来处理文件的传播:file:// 使用file://和绝对路径,是由driver的HTTP server来提供文件服务,各个executor从driver上拉回文件。

hdfs:, http:, https:, ftp: executor直接从URL拉回文件

local: executor本地本身存在的文件,不需要拉回;也可以是通过NFS网络共享的文件。

如果需要查看配置选项是从哪里来的,可以用打开--verbose选项来生成更详细的运行信息以做参考。

三、如何将scala程序在IDEA中打包为JAR可执行包A:建立新项目(new project)

创建名为KMeansTest的project:启动IDEA -> Welcome to IntelliJ IDEA -> Create New Project -> Scala -> Non-SBT -> 创建一个名为KMeansTest的project(注意这里选择自己安装的JDK和scala编译器) -> Finish。

设置KMeansTest的project structure

增加源码目录:File -> Project Structure -> Medules -> KMeansTest,给KMeansTest创建源代码目录和资源目录,注意用上面的按钮标注新增加的目录的用途。

增加开发包:File -> Project Structure -> Libraries -> + -> java ->  选择

/usr/local/spark/spark-1.0.2-bin-hadoop2/lib/spark-assembly-1.0.2-hadoop2.2.0.jar

/root/.sbt/boot/scala-2.10.4/lib/scala-library.jar可能会提示错误,可以根据fix提示进行处

(这里也可以选择SBT选项来初始化工程,这样就会自动生成以上所需的目录及库包)B:编写代码

在源代码Scala目录下创建1个名为KMeansTest的package,并增加3个object(SparkPi、WordCoun、SparkKMeans):

[plain] view plain copy

//SparkPi代码

package <span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">KMeansTest</span></span></span>

import scala.math.random

import org.apache.spark._

/** Computes an approximation to pi */

object SparkPi {

def main(args: Array[String]) {

val conf = new SparkConf().setAppName("Spark Pi")

val spark = new SparkContext(conf)

val slices = if (args.length > 0) args(0).toInt else 2

val n = 100000 * slices

val count = spark.parallelize(1 to n, slices).map { i =>

val x = random * 2 - 1

val y = random * 2 - 1

if (x*x + y*y < 1) 1 else 0

}.reduce(_ + _)

println("Pi is roughly " + 4.0 * count / n)

spark.stop()

}

}

[plain] view plain copy

// WordCount1代码

package <span style="font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">KMeansTest</span></span></span>

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

import org.apache.spark.SparkContext._

object WordCount1 {

def main(args: Array[String]) {

if (args.length == 0) {

System.err.println("Usage: WordCount1 <file1>")

System.exit(1)

}

val conf = new SparkConf().setAppName("WordCount1")

val sc = new SparkContext(conf)

sc.textFile(args(0)).flatMap(_.split(" ")).map(x => (x, 1)).reduceByKey(_ + _).take(10).foreach(println)

sc.stop()

}

}

[plain] view plain copy

//SparkKMeans代码

package KMeansTest

import java.util.Random

import breeze.linalg.{Vector, DenseVector, squaredDistance}

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

import org.apache.spark.SparkContext._

object SparkKMeans {

val R = 1000     // Scaling factor

val rand = new Random(42)

def parseVector(line: String): Vector[Double] = {

DenseVector(line.split(" ").map(_.toDouble))

}

def closestPoint(p: Vector[Double], centers: Array[Vector[Double]]): Int = {

var index = 0

var bestIndex = 0

var closest = Double.PositiveInfinity

for (i <- 0 until centers.length) {

val tempDist = squaredDistance(p, centers(i))

if (tempDist < closest) {

closest = tempDist

bestIndex = i

}

}

bestIndex

}

def main(args: Array[String]) {

if (args.length < 3) {

System.err.println("Usage: SparkKMeans <file> <k> <convergeDist>")

System.exit(1)

}

val sparkConf = new SparkConf().setAppName("SparkKMeans").setMaster(args(0))

val sc = new SparkContext(sparkConf)

val lines = sc.textFile(args(1))

val data = lines.map(parseVector _).cache()

val K = args(2).toInt

val convergeDist = args(3).toDouble

val kPoints = data.takeSample(withReplacement = false, K, 42).toArray

var tempDist = 1.0

while(tempDist > convergeDist) {

val closest = data.map (p => (closestPoint(p, kPoints), (p, 1)))

val pointStats = closest.reduceByKey{case ((x1, y1), (x2, y2)) => (x1 + x2, y1 + y2)}

val newPoints = pointStats.map {pair =>

(pair._1, pair._2._1 * (1.0 / pair._2._2))}.collectAsMap()

tempDist = 0.0

for (i <- 0 until K) {

tempDist += squaredDistance(kPoints(i), newPoints(i))

}

for (newP <- newPoints) {

kPoints(newP._1) = newP._2

}

println("Finished iteration (delta = " + tempDist + ")")

}

println("Final centers:")

kPoints.foreach(println)

sc.stop()

}

}

C:生成jar程序包

生成jar程序包之前要先建立一个artifacts,File -> Project Structure -> Artifacts  -> + -> Jars -> From moudles with dependencies,然后随便选一个class作为主class。


按OK后, Build -> Build Artifacts -> KMeansTest -> rebuild进行打包,经过编译后,程序包放置在out/artifacts/KMeansTest目录下,文件名为KMeansTest.jar。

D:Spark应用程序部署

将生成的程序包KMeansTest.jar复制到spark安装目录下,切换到用户Hadoop/bin目录下进行程序的部署。

四、spark-shell下进行jar程序包提交运行实验

下面给出了几种实验CASE的命令:



在使用spark-submit提交spark应用程序的时候,需要注意以下几点:

集群外的客户机向Spark Standalone部署Spark应用程序时,要注意事先实现该客户机和Spark Standalone之间的SSH无密码登录。

向YARN部署spark应用程序的时候,注意executor-memory的大小,其内存加上container要使用的内存(默认值是1G)不要超过NM可用内存,不然分配不到container来运行executor。

参考资料:Spark1.0.0 应用程序部署工具spark-submit 

品略图书馆 http://www.pinlue.com/