spark学习笔记五:spark编程
来源:互联网 发布:知乎乒乓球衰败 编辑:程序博客网 时间:2024/05/22 13:13
Spark编程
Window下的IDE环境
安装ide前先安装scala。我在配置eclipse的过程中遇到一些莫名其妙的问题。建议直接使用IntelliJ IDEA。使用方法如下。
1. 使用IntelliJ IDEA新建普通项目或maven项目。
2. 以普通项目为例,新建项目后,需要依赖spark的jar包,在安装包中可以找到,名为spark-assembly-*.jar。File->Project Structure->Library可以选择这个jar包从而添加到依赖路径中。如果需要依赖其他jar包,也通过这种方式加入。比如,以下的例子需要使用hbase依赖,所以这里还需要依赖hbase-0.94.17.jar。
3. 编码完成后,使用File->Project Structure->Artifacts可以为工程添加一个编译目标,选择“+”->JAR->From Modules …. ,跳出对话框,这里需要选择main函数,以及依赖的编译方式:1.是集成到一个jar包中,2.或者是把所有jar包放到一个目录下。这里,我选择copy to the output…..,即依赖jar包和编译产生的jar包会放到一个输出目录下。
4. 编译的方式是:Build->Build Artifacts。这步操作完成后,会在输出目录产生各个jar包,这些jar包在以后将被提交给spark运行。
Spark属性的配置
Spark可配置的属性一般包括:针对某个应用的应用名、master模式(yarn、local、standalone)、master地址、worker可用的内存(这个一般用在worker实例上)。对于某个spark应用而言,Spark属性可以通过以下几种方式来进行配置:
1. 编程时使用SparkConf类,调用其set函数来设置属性。这将以后文介绍。
2. 编程时使用SparkContex类,这个类的也可以用来设置属性,比如,在他的构造函数可选地传入应用名、master地址等。
3. 使用spark-submit脚本提交应用时,由命令选项传入。
4. 使用环境变量,环境变量一般在$SPARK_HOME/conf/spark-env.sh中配置。spark-env.sh.template文件是其模板,这个文件中的注释基本给出了所有可以配置的选项。
5. 使用配置文件,配置文件是$SPARK_HOME/conf/spark-default.conf。spark-defaults.conf.template是其模板文件,这个文件中的注释给出了几个可以配置的选项。
6. 使用$SPARK_HOME/conf/log4j.properties文件,log4j.properties.template是其模板文件。
一般推荐使用3、4、5三种方式来配置,这样灵活性高。
API的使用
Spark编程,其实就是scala语言 + spark的api。一段典型的代码如下所示:
object Stat {
def main( args:Array[String] ): Unit ={
val table = args(0)
val family = args(1)
val column = args(2)
val startTime = args(3)
val endTime = args(4)
val saveFile = args(5)
val spConf= new SparkConf()
/*spConf.setMaster(args(0))
.setAppName(args(1)).setSparkHome(System.getenv("SPARK_HOME"))
.setJars(Seq(System.getenv("SPARK_JAR_PATH")))*/
val spContext= newSparkContext(spConf)
val hbConf =HBaseConfiguration.create()
hbConf.set(TableInputFormat.INPUT_TABLE,table)
hbConf.set(TableInputFormat.SCAN_COLUMN_FAMILY, family )
hbConf.set(TableInputFormat.SCAN_TIMERANGE_START, startTime )
hbConf.set(TableInputFormat.SCAN_TIMERANGE_END, endTime )
val hbRdd =spContext.newAPIHadoopRDD(hbConf,
classOf[TableInputFormat],
classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
classOf[org.apache.hadoop.hbase.client.Result] )
val strRDD = hbRdd.map[String]( (tup:(org.apache.hadoop.hbase.io.ImmutableBytesWritable,org.apache.hadoop.hbase.client.Result)) => new String( tup._2.getValue(family.getBytes,column.getBytes)) )
strRDD.saveAsTextFile(saveFile)
}
}
这段代码从hbase表中读取出某个时间段内的数据,并保存到hdfs上。对照以上代码,下文将给出代码的解释。
1. SparkConf
SparkConf用于配置本应用的基本选项,包括master地址、应用名、jar包地址等。具体的可配置选项参考api文档。基本的使用方法如下:
val conf = newSparkConf().setAppName(appName).setMaster(master)
master可以是”local”,代表在本机运行,这一般是调试时候用。也可以是“spark:// ”、“yarn://”、“Mesos://”三种取值。另外,像master和AppName,一般建议由程序的选项传入,而不要使用SparkConf或SparkContext来设置,如以上示例所示,这样灵活性好。
2. sparkcontex
SparkContext是spark应用的上下文,在一个JVM中只能有一个实例有效,所以一般只new一个。它的创建方法如下:
val spContext= new SparkContext(spConf)
3. RDD
示例中的spContext.newAPIHadoopRDD语句用于产生一个RDD。本质而言,一个spark应用实际上是对各个RDD对象的操作,这些操作包括:变换、持久化、产出(就是action的概念)。
RDD的来源有两种:
1) 把scala中的集合并行化(分片);
把集合并行化的方法是:
val data = Array(1, 2, 3, 4, 5)
val distData =sc.parallelize(data)
或
val distData = sc.parallelize(data,10)
一般是按照每个cpu有2-4个分片的方式进行分片,上面的最后一种方式是手动设置分片数。
2) 从外部存储介质中读入。
从外部存储介质读入的方法:
scala> val distFile =sc.textFile("data.txt")
distFile: RDD[String] = MappedRDD@1d4cee08
textFile()中的文件名允许使用目录、文件名通配符。一般而言,从HDFS读入的话,是一个文件block对应一个rdd分片。textFile读文件的方式是一行作为一条记录。另外还有SequenceFiles是把[k,v]格式的数据读入。
示例中的newAPIHadoopRDD用于读取Hadoop数据源,通过代码中各项配置,这个RDD实际上是从hbase中读取数据,其逻辑请参考以上代码。
调用persist或cache函数可以把RDD数据持久化到本地,可以持久化到内存、磁盘,也可以在其他work上放置副本。
4. 动作
strRDD.saveAsTextFile(saveFile)是一个动作,用于把RDD产出到文件中,这个saveFile可以给出一个hdfs的地址。
Worker间数据共享机制
正常上,drive把函数分发到每个work上运行,这个函数是个闭包,包含变量值。但是spark还是提供了两种cluster间共享数据的机制。
Broadcast Variables
广播变量,即由drive一次性把变量广播给各个work(只广播一次),这个数据在各个work上是只读的,之后各个work一旦用到这个变量,就不需要作为闭包再传一次。当然,必须保证这个变量是只读的。
使用方法如下:
scala> val broadcastVar =sc.broadcast(Array(1, 2, 3))
broadcastVar: org.apache.spark.broadcast.Broadcast[Array[Int]]= Broadcast(0)
scala> broadcastVar.value
res0: Array[Int] = Array(1, 2, 3)
定义了val broadcastVar = sc.broadcast后,之后要使用这个值就直接broadcastVar.value即可。
Accumulators
累加器,即各个work可以对这个累加器执行加法操作,但不可读。只有drive可读,并且可以在ui上显示出来。用法如下:
scala> val accum = sc.accumulator(0,"My Accumulator")
accum: spark.Accumulator[Int] = 0
scala> sc.parallelize(Array(1, 2, 3,4)).foreach(x => accum += x)
应用提交
在Standalone模式下,提交的方式是:
spark-submit –master<mater地址> --name <应用名> --class <main函数所在类> --jars <所依赖的jar包,spark-assembly可以不用包含进来> --executor-memory <应用在每个executor占用的内存>--total-executor-cores <应用占用的总CPU核数> <要运行的jar包> <参数>
如果master地址在配置文件中指定了,这里就不需要--mastert选项。它可选择的参数有 spark://host:port standalone模式
mesos://host:port mesos模式
yarn yarn模式
local[n] 在本地用n个核运行spark应用。
- spark学习笔记五:spark编程
- 学习spark:五、spark编程指南
- Spark学习笔记(五)
- Spark (Python版) 零基础学习笔记(五)—— Spark RDDs编程
- Spark学习五:spark sql
- Spark机器学习笔记1--Spark Python编程入门
- spark学习笔记:Spark Streaming
- Spark学习笔记:初识Spark
- Spark学习笔记--Spark基础知识
- spark学习笔记:初识spark
- Spark学习笔记(一)--RDD编程
- Spark学习笔记2:RDD编程
- Spark学习笔记2:RDD编程
- Spark学习笔记1-RDD编程
- Spark编程指南笔记
- Spark编程指南笔记
- Spark编程笔记
- Spark编程指南笔记
- AFNetWorking 文件上传Demo
- 单例模式
- android 开发之activity之间传递数据
- 解决HierarchyViewer不能连接真机的问题
- Linux 路由 (1)
- spark学习笔记五:spark编程
- Myeclipse 2014 安装 Spket IDE
- 软件架构师
- 黑马程序员——IO流详解
- JSCharts 3 去掉LOGO方法
- 如何在Eclipse中导入Android源码(使用的是别人的图片)
- 说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
- linux上su与sudo su的区别
- 介绍Robotium+Orange实现androidUI自动化测试