saprk-quick start tutorial
spark 教程(scala)
该教程提供了使用spark的简要介绍。我们将通过交互shell首先介绍一下API,之后我们将介绍如何使用java,scala和python编写spark应用程序。完整参考请参考spark的编程指南。使用spark shell 进行交互式分析
基础
spark shell 是一种简单的使用spark API的方式,也是一种交互式的分析数据的有力工具。它对于scala,java 和python都是适用的。我们在spark的源码目录下运行以下程序:
./bin/spark-shell
spark 主要抽象是一个分布式的数据集,我们称它为离散分布数据集(RDD)。RDD可以通过
hadoop 输入格式创建或者由其他的RDDS转换创建。我们使用spark源码目录下的README文本文件
创建一个RDD。
scala> val textFile = sc.textFile("README.md")
textFile: spark.RDD[String] = spark.MappedRDD@2ee9b6e3
RDD包含actions 和 transformations,其中actions 返回数值,transformations 操作返回新的
RDDS的指针。以下是几个actions:
scala> textFile.count() // Number of items in this RDD
res0: Long = 126
scala> textFile.first() // First item in this RDD
res1: String = # Apache Spark
对于transformations 操作,我们使用上述文件中数据子集 通过 filter转换创建一个新的RDD。
scala> val linesWithSpark = textFile.filter(line => line.contains("Spark"))
linesWithSpark: spark.RDD[String] = spark.FilteredRDD@7dd4af09
我们可以合并actions 和 transformations 两种操作:
res3: Long = 15
更多关于RDD的操作。
RDD 可以使用actions和transformations进行错综复杂的计算。我们可以结合两种操作查找包含单词数量最多的文本行。scala> textFile.map(line => line.split(" ").size).reduce((a, b) => if (a > b) a else b)
res4: Long = 15
map操作将文本行映射为一个数值。创建一个新的RDD。reduce操作计算出包含单词数量最多的文本行。
map函数,reduce函数的参数是scala函数,而且可以使用任何语言特征和java/scala类库。例如,
我们可以调用在别处声明的函数。我们可以使用Math.max()来使代码更加容易理解。
scala> import java.lang.Math
import java.lang.Math
scala> textFile.map(line => line.split(" ").size).reduce((a, b) => Math.max(a, b))
res5: Int = 15
随着hadoop的推广,MapReduce成为一种常用的数据流模式。spark很容易实现mapreduce数据流模式:
scala> val wordCounts = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey((a, b) => a + b)
wordCounts: spark.RDD[(String, Int)] = spark.ShuffledAggregatedRDD@71f027b8
我们综合flatmap, map 和 reduceByKey 转换来计算在上述文件中每个单词的数量。并输出(String,int)对最为新的RDD。
在shell中统计单词数量,我们可以使用collect 操作。
scala> wordCounts.collect()
res6: Array[(String, Int)] = Array((means,1), (under,2), (this,3), (Because,1), (Python,2), (agree,1), (cluster.,1), ...)
缓存:
spark支持基于集群内存的缓存机制,当数据会被反复访问时,该机制非常有用。比如我们查询一个小的“hot”数据集或者运行迭代算法,像PageRank算法。 比如,我们缓存
我们的lineWithSpark.
scala> linesWithSpark.cache()
res7: spark.RDD[String] = spark.FilteredRDD@17e51082
scala> linesWithSpark.count()
res8: Long = 19
scala> linesWithSpark.count()
res9: Long = 19
也许使用spark导出或者缓存100行的数据看起来是非常愚蠢的。但是有意思的是这些通用的函数可以被应用于
大的数据集,甚至这些数据被分散存储在数十或者成百的节点上。你也可以使用spark-shell连接上集群进行交互式操作,详细参考spark的编程指南。
独立的应用程序
我们将使用spark 的API来编写一个独立的应用程序。你可以使用java,scala 或者python。
我们这里以scala语言为例进行独立的应用程序开发。
/* SimpleApp.scala */
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf
object SimpleApp {
def main(args: Array[String]) {
val logFile = "YOUR_SPARK_HOME/README.md" // Should be some file on your system
val conf = new SparkConf().setAppName("Simple Application")
val sc = new SparkContext(conf)
val logData = sc.textFile(logFile, 2).cache()
val numAs = logData.filter(line => line.contains("a")).count()
val numBs = logData.filter(line => line.contains("b")).count()
println("Lines with a: %s, Lines with b: %s".format(numAs, numBs))
}
}
请注意,应用程序应该定义一个main()方法,而不是扩展scala.App. scala.App的子类可能无法正常运行。
这个程序只是统计README.md文件中包含a和包含b的文本行数。
你需要替换YOUR_SPARK_HOME为运行环境中的spark的安装目录。
区别于之前的spark shell运行方式,spark shell自行初始化了sparkContext,我们的程序中需要
初始化sparkContext的程序。
我们传递一个sparkConf参数给sparkContext的构造函数,sparkConf中包含了我们应用程序的一些信息。
由于我们的程序需要依赖spark的API,所以我们需要使用sbt 配置文件(如果使用sbt开发项目的话)或者
使用pom.xml文件(如果使用maven开发项目),将我们需要使用的依赖包导入到我们的应用中。这里以sbt为例:
name := "Simple Project"
version := "1.0"
scalaVersion := "2.10.5"
libraryDependencies += "org.apache.spark" %% "spark-core" % "1.6.1"
打包应用程序代码后使用 spark-submit 脚本运行我们的程序。
# Your directory layout should look like this
$ find .
.
./simple.sbt
./src
./src/main
./src/main/scala
./src/main/scala/SimpleApp.scala
# Package a jar containing your application
$ sbt package
...
[info] Packaging {..}/{..}/target/scala-2.10/simple-project_2.10-1.0.jar
# Use spark-submit to run your application
$ YOUR_SPARK_HOME/bin/spark-submit \
--class "SimpleApp" \
--master local[4] \
target/scala-2.10/simple-project_2.10-1.0.jar
...
Lines with a: 46, Lines with b: 23
更过关于spark编程的内容,可以参考spark官网的详细参考指南。
其实,在spark的安装目录下包含了若干个可以运行的spark运行实例(语言涉及java,scala,python和R)。
可以通过以下方式运行:
# For Scala and Java, use run-example:
./bin/run-example SparkPi
# For Python examples, use spark-submit directly:
./bin/spark-submit examples/src/main/python/pi.py
# For R examples, use spark-submit directly:
./bin/spark-submit examples/src/main/r/dataframe.R