本文主要内容来源于spark官网:http://spark.apache.org/docs/1.6.0/programming-guide.html,本文主要学习java方式
Overview
每个Spark应用程序都包含一个驱动程序,该程序运行用户的Main函数并在集群上执行各种并行操作。
Spark提供的最主要抽象是弹性分布式数据集(RDD)关于RDD这里不再详细写了。Spark中的第二个抽象是可以在并行操作中使用的共享变量,Spark支持两种类型的共享变量:广播变量(将值缓存到所有节点的内存中)和累加器(仅“添加”到其上的变量,例如计数器和求和)。
Linking with Spark
spark1.6.0对应的scala版本为scala2.10、java7以上,python2.6或python3.4。
对于scala和java,连接的方式类似,
spark的maven依赖:
groupId = org.apache.spark
artifactId = spark-core_2.10
version = 1.6.0
如果想要使用hdfs,则需要添加hdfs依赖:
groupId = org.apache.hadoop
artifactId = hadoop-client
version = <your-hdfs-version>
在程序中使用导入spark相关类:
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf
Spark 1.6.0适用于Java 7及更高版本。如果使用Java 8,Spark支持lambda表达式以简洁地编写函数,否则可以使用org.apache.spark.api.java.function包中的类。
对于python,使用下面的方式导入:
from pyspark import SparkContext, SparkConf
Initializing Spark
编写Spark程序首先需要创建一个SparkContext对象,该对象告诉Spark如何访问集群。创建SparkContext之前,需要构建一个SparkConf对象,用来配置应用程序的信息。
scala:
val conf = new SparkConf().setAppName(appName).setMaster(master)
new SparkContext(conf)
java:
SparkConf conf = new SparkConf().setAppName(appName).setMaster(master);
JavaSparkContext sc = new JavaSparkContext(conf);
python:
conf = SparkConf().setAppName(appName).setMaster(master)
sc = SparkContext(conf=conf)
其中的appName参数是应用程序在WEB UI上显示的名称。master是Spark,Mesos或YARN群集URL,或local(以本地模式运行)。
Using the Shell
在spark shell中,系统已经为我们创建好SparkContext 对象sc,执行spark-shell --help或pyspark --help可以查看其支持的所有选项。
Resilient Distributed Datasets
Spark围绕弹性分布式数据集(RDD)的概念展开,RDD是可并行操作的元素的容错集合。创建RDD的方法有两种:对驱动程序中的现有数据集合执行parallelize()操作,或引用外部存储系统(例如HDFS,HBase或提供Hadoop InputFormat的任何数据源)中的数据集。
Parallelized Collections(并行化现有数据集)
通过在驱动程序中的现有集合(Scala Seq)上调用SparkContext的parallelize方法来创建并行集合。复制集合的元素以形成可以并行操作的分布式数据集。
比如:
val data = Array(1, 2, 3, 4, 5)
val distData = sc.parallelize(data)
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5);
JavaRDD<Integer> distData = sc.parallelize(data);
data = [1, 2, 3, 4, 5]
distData = sc.parallelize(data)
并行数据集一个重要的参数是将数据集分成的分区数,Spark将为集群的每个分区运行一个任务,我们一般为群集中的每个CPU分配2-4个分区。通常,Spark会尝试根据您的集群自动设置分区数,我们也可以通过将其作为第二个参数传递来进行手动设置(例如sc.parallelize(data,10))。
External Datasets(外部数据集)
Spark的外部数据集支持的数据源包括本地文件系统,HDFS,Cassandra,HBase,Amazon S3等,支持的格式包括文本文件,SequenceFiles和任何Hadoop InputFormat。
可以使用SparkContext的textFile方法创建文本文件RDD,此方法获取文件的URI(本地路径,或hdfs://等URI),并将其作为行的集合读取。
scala:
scala> val distFile = sc.textFile("data.txt")
java:
JavaRDD<String> distFile = sc.textFile("data.txt");
python:
distFile = sc.textFile("data.txt")
Spark的所有基于文件的输入(包括textFile)都支持在目录、压缩文件和文件通配符上运行,比如:textFile("/my/directory")
, textFile("/my/directory/*.txt")
, textFile("/my/directory/*.gz")
。
textFile方法还带有一个可选的第二个参数,用于控制文件的分区数。默认情况下,Spark为文件的每个块创建一个分区(HDFS中的块默认为64MB),但也可以通过传递更大的值来请求更大数量的分区。需要注意的是,分区不能少于块数。
除文本文件外,Spark的JAVA API还支持其他几种数据格式:
- JavaSparkContext.wholeTextFiles 可以读取包含多个小文本文件的目录,并将每个小文本文件作为(文件名,内容)对返回。这与textFile相反,后者将在每个文件的每一行返回一条记录。
- 对于SequenceFiles,我们使用SparkContext的sequenceFile [K,V]方法,其中K和V是文件中键的类型和值。这些应该是Hadoop的Writable接口的子类,例如IntWritable和Text。
- 对于其他Hadoop InputFormat,可以使用SparkContext.hadoopRDD/ JavaSparkContext.hadoopRDD方法,该方法可应用于任意
JobConf
和输入格式的类,键类和值类。 - JavaRDD.saveAsObjectFile和JavaSparkContext.objectFile支持以包含序列化Java对象的简单格式保存RDD。尽管它不如Avro这样的专用格式有效,但它提供了一种保存任何RDD的简便方法。
RDD Operations