spark入门知识

来源:互联网 发布:南京java培训学校 编辑:程序博客网 时间:2024/06/08 20:07

1、Java下Spark开发环境搭建

1.1、jdk安装

安装oracle下的jdk,我安装的是jdk 1.7,安装完新建系统环境变量JAVA_HOME,变量值为“C:\ProgramFiles\Java\jdk1.7.0_79”,视自己安装路劲而定。

同时在系统变量Path下添加C:\Program Files\Java\jdk1.7.0_79\bin和C:\ProgramFiles\Java\jre7\bin。

1.2 spark环境变量配置

去http://spark.apache.org/downloads.html网站下载相应hadoop对应的版本,我下载的是spark-1.6.0-bin-hadoop2.6.tgz,spark版本是1.6,对应的hadoop版本是2.6

解压下载的文件,假设解压 目录为:D:\spark-1.6.0-bin-hadoop2.6。将D:\spark-1.6.0-bin-hadoop2.6\bin添加到系统Path变量,同时新建SPARK_HOME变量,变量值为:D:\spark-1.6.0-bin-hadoop2.6

1.3 hadoop工具包安装

spark是基于hadoop之上的,运行过程中会调用相关hadoop库,如果没配置相关hadoop运行环境,会提示相关出错信息,虽然也不影响运行,但是这里还是把hadoop相关库也配置好吧。

1.3.1 去下载hadoop 2.6,我下载的是hadoop-2.6.0.tar.gz

1.3.2 解压下载的文件夹,将相关库添加到系统Path变量中:D:\hadoop-2.6.0\bin;同时新建HADOOP_HOME变量,变量值为:D:\hadoop-2.6.0,下载winutils的windows版本,将winutils.exe加入你的hadoop-x.x.x/bin下,把hadoop.dll放入从C:/wondwos/system32下面。

1.4 eclipse环境

直接新建java工程,将D:\spark-1.6.0-bin-hadoop2.6\lib下的spark-assembly-1.6.0-hadoop2.6.0.jar添加到工程中就可以了。

 

注意点:

a.本机环境变量配置,配置后需要重启机器:hadoop_home(需要包含winutil.exe),spark_home

/* SimpleApp.java */

import org.apache.spark.api.java.*;

import org.apache.spark.SparkConf;

import org.apache.spark.api.java.function.Function;

 

public class SimpleApp {

    publicstatic void main(String[] args) {

        StringlogFile = "file:///spark-bin-0.9.1/README.md";

       SparkConf conf =new SparkConf().setAppName("Spark Application inJava");

       JavaSparkContext sc = new JavaSparkContext(conf);

       JavaRDD<String> logData = sc.textFile(logFile).cache();

 

        longnumAs = logData.filter(new Function<String, Boolean>() {

           public Boolean call(String s) { return s.contains("a"); }

       }).count();

 

        longnumBs = logData.filter(new Function<String, Boolean>() {

           public Boolean call(String s) { return s.contains("b"); }

       }).count();

 

        System.out.println("Lines with a:" + numAs +",lines with b: " + numBs);

    }

}

 

 

2, TDH上运行spark-demo、

touch 一个test.txt 然后put到hdfs的tmp下面,执行一下下面的命令

spark-submit \

--master yarn-cluster \

--num-executors 2 \

--driver-memory 1g \

--executor-memory 1g \

--executor-cores 1 \

--class org.apache.spark.examples.JavaWordCount \

"/usr/lib/discover/lib/spark-examples-1.5.1-hadoop2.5.2-transwarp.jar"\

"/tmp/test.txt"

 

3,client和cluster的区别和联系,

测试用指定sparkMaster为yarn时,could not parse MaserURL:'yarn'

这里跑在discover上,不能像取master的url,无法访问7077端口,如果在discover跑的代码中指定master为yarn-cluster,则会报sparkException,

当然如果是开源的,在集群测试代码的话,就取值master的url,代表在这个指定节点上跑,如果指定local,代表在本地跑,即standalone模式,yarn模式默认启动2个executor,无论你有多少的worker节点

standalone模式每个worker一个executor,无法修改executor的数量

partition是RDD中的一个dataset,一般默认都是2个

executor中的task数量由partition数(最后一个stage的partition数)决定

 

 从广义上讲,yarn-cluster适用于生产环境;而yarn-client适用于交互和调试,也就是希望快速地看到application的输出。

  在我们介绍yarn-cluster和yarn-client的深层次的区别之前,我们先明白一个概念:ApplicationMaster。在YARN中,每个Application实例都有一个Application Master进程,它是Application启动的第一个容器。它负责和ResourceManager打交道,并请求资源。获取资源之后告诉NodeManager为其启动container。

 

 从深层次的含义讲,Spark Application运行在YARN集群环境下

Spark:Driver+ Executors(Executors是JVMProcess)

YARN:AM+ Containers(Containers 是JVMProcess)

yarn-cluster和yarn-client模式的区别其实就是Application Master进程的区别,yarn-cluster模式下,driver运行在AM(Application Master)中,它负责向YARN申请资源,并监督作业的运行状况。当用户提交了作业之后,就可以关掉Client,作业会继续在YARN上运行。然而yarn-cluster模式不适合运行交互类型的作业。而yarn-client模式下,Application Master仅仅向YARN请求executor,client会和请求的container通信来调度他们工作,也就是说Client不能离开。看下下面的两幅图应该会明白(上图是yarn-cluster模式,下图是yarn-client模式):

 

 

 

4,spark-submit参数,

 

参数名称

含义

--master MASTER_URL

可以是spark://host:port, mesos://host:port, yarn, yarn-cluster,yarn-client, local

--deploy-mode DEPLOY_MODE

Driver程序运行的地方,client或者cluster

--class CLASS_NAME

主类名称,含包名

--name NAME

Application名称

--jars JARS

Driver依赖的第三方jar

--py-files PY_FILES

用逗号隔开的放置在Python应用程序PYTHONPATH上的.zip, .egg, .py文件列表

--files FILES

用逗号隔开的要放置在每个executor工作目录的文件列表

--properties-file FILE

设置应用程序属性的文件路径,默认是conf/spark-defaults.conf

--driver-memory MEM

Driver程序使用内存大小

--driver-java-options

--driver-library-path

Driver程序的库路径

--driver-class-path

Driver程序的类路径

--executor-memory MEM

executor内存大小,默认1G

--driver-cores NUM

Driver程序的使用CPU个数,仅限于Spark Alone模式

--supervise

失败后是否重启Driver,仅限于Spark Alone模式

--total-executor-cores NUM

executor使用的总核数,仅限于Spark AloneSpark on Mesos模式

--executor-cores NUM

每个executor使用的内核数,默认为1,仅限于Spark on Yarn模式

--queue QUEUE_NAME

提交应用程序给哪个YARN的队列,默认是default队列,仅限于Spark on Yarn模式

--num-executors NUM

启动的executor数量,默认是2个,仅限于Spark on Yarn模式

--archives ARCHIVES

仅限于Spark on Yarn模式

 

 

5,部分参数以及意义详解

 

启动参数

/bin/spark-submit \

--master yarn-cluster \

--num-executors 100 \

--executor-memory 6G \

--executor-cores 4 \

--driver-memory 1G \

--conf spark.default.parallelism=1000\

--confspark.storage.memoryFraction=0.5 \

--confspark.shuffle.memoryFraction=0.3 \

num-executors

参数说明:该参数用于设置Spark作业总共要用多少个Executor进程来执行。Driver在向YARN集群管理器申请资源时,YARN集群管理器会尽可能按照你的设置来在集群的各个工作节点上,启动相应数量的Executor进程。这个参数非常之重要,如果不设置的话,默认只会给你启动少量的Executor进程,此时你的Spark作业的运行速度是非常慢的。

参数调优建议:每个Spark作业的运行一般设置50~100个左右的Executor进程比较合适,设置太少或太多的Executor进程都不好。设置的太少,无法充分利用集群资源;设置的太多的话,大部分队列可能无法给予充分的资源。

executor-memory

参数说明:该参数用于设置每个Executor进程的内存。Executor内存的大小,很多时候直接决定了Spark作业的性能,而且跟常见的JVM OOM异常,也有直接的关联。

参数调优建议:每个Executor进程的内存设置4G~8G较为合适。但是这只是一个参考值,具体的设置还是得根据不同部门的资源队列来定。可以看看自己团队的资源队列的最大内存限制是多少,num-executors乘以executor-memory,就代表了你的Spark作业申请到的总内存量(也就是所有Executor进程的内存总和),这个量是不能超过队列的最大内存量的。此外,如果你是跟团队里其他人共享这个资源队列,那么申请的总内存量最好不要超过资源队列最大总内存的1/3~1/2,避免你自己的Spark作业占用了队列所有的资源,导致别的同学的作业无法运行。

executor-cores

参数说明:该参数用于设置每个Executor进程的CPU core数量。这个参数决定了每个Executor进程并行执行task线程的能力。因为每个CPU core同一时间只能执行一个task线程,因此每个Executor进程的CPU core数量越多,越能够快速地执行完分配给自己的所有task线程。

参数调优建议:ExecutorCPU core数量设置为2~4个较为合适。同样得根据不同部门的资源队列来定,可以看看自己的资源队列的最大CPU core限制是多少,再依据设置的Executor数量,来决定每个Executor进程可以分配到几个CPU core。同样建议,如果是跟他人共享这个队列,那么num-executors *executor-cores不要超过队列总CPU core1/3~1/2左右比较合适,也是避免影响其他同学的作业运行。

spark.default.parallelism

参数说明:该参数用于设置每个stage的默认task数量。这个参数极为重要,如果不设置可能会直接影响你的Spark作业性能。

参数调优建议:Spark作业的默认task数量为500~1000个较为合适。很多同学常犯的一个错误就是不去设置这个参数,那么此时就会导致Spark自己根据底层HDFSblock数量来设置task的数量,默认是一个HDFS block对应一个task。通常来说,Spark默认设置的数量是偏少的(比如就几十个task),如果task数量偏少的话,就会导致你前面设置好的Executor的参数都前功尽弃。试想一下,无论你的Executor进程有多少个,内存和CPU有多大,但是task只有1个或者10个,那么90%Executor进程可能根本就没有task执行,也就是白白浪费了资源!因此Spark官网建议的设置原则是,设置该参数为num-executors * executor-cores2~3倍较为合适,比如Executor的总CPU core数量为300个,那么设置1000task是可以的,此时可以充分地利用Spark集群的资源。

spark.storage.memoryFraction

参数说明:该参数用于设置RDD持久化数据在Executor内存中能占的比例,默认是0.6。也就是说,默认Executor 60%的内存,可以用来保存持久化的RDD数据。根据你选择的不同的持久化策略,如果内存不够时,可能数据就不会持久化,或者数据会写入磁盘。

参数调优建议:如果Spark作业中,有较多的RDD持久化操作,该参数的值可以适当提高一些,保证持久化的数据能够容纳在内存中。避免内存不够缓存所有的数据,导致数据只能写入磁盘中,降低了性能。但是如果Spark作业中的shuffle类操作比较多,而持久化操作比较少,那么这个参数的值适当降低一些比较合适。此外,如果发现作业由于频繁的gc导致运行缓慢(通过spark web ui可以观察到作业的gc耗时),意味着task执行用户代码的内存不够用,那么同样建议调低这个参数的值。

spark.shuffle.memoryFraction

参数说明:该参数用于设置shuffle过程中一个task拉取到上个stagetask的输出后,进行聚合操作时能够使用的Executor内存的比例,默认是0.2。也就是说,Executor默认只有20%的内存用来进行该操作。shuffle操作在进行聚合时,如果发现使用的内存超出了这个20%的限制,那么多余的数据就会溢写到磁盘文件中去,此时就会极大地降低性能。

参数调优建议:如果Spark作业中的RDD持久化操作较少,shuffle操作较多时,建议降低持久化操作的内存占比,提高shuffle操作的内存占比比例,避免shuffle过程中数据过多时内存不够用,必须溢写到磁盘上,降低了性能。此外,如果发现作业由于频繁的gc导致运行缓慢,意味着task执行用户代码的内存不够用,那么同样建议调低这个参数的值。

 

原创粉丝点击