http://spark.apache.org/docs/latest/quick-start.html#more-on-dataset-operations
本教程提供了使用Spark的快速入门教程。我们将首先通过Spark的交互式shell(Python或Scala)介绍其API,然后展示如何用Java,Scala和Python编写Spark应用程序。
要学习本教程,请先从Spark网站下载Spark的安装包。由于我们不会使用HDFS,因此您可以下载任何版本的Hadoop的软件包。
请注意,在Spark 2.0之前,Spark的主要编程接口是弹性分布式数据集(RDD)。在Spark 2.0之后,RDD被DataSet取代,DataSet类似于RDD的加强版,在引擎盖下有更丰富的优化。
RDD接口仍然可使用,您可以在RDD编程指南中获得更完整的参考资料。但是,我们强烈建议您切换到使用DataSet,这具有比RDD更好的性能。请参阅SQL编程指南以获取有关数据集的更多信息。
使用Spark Shell进行交互式分析
基础
Spark的shell提供了一个学习API的简单方法,同时也是交互式分析数据的强大工具。它可以使用Scala或Python语言进行开发,可通过在Spark目录运行以下命令启动Spark-Shell:
./bin/spark-shell
Spark的主要抽象是一个名为Dataset的分布式集合。DataSet可以从Hadoop输入格式或者其他Dataset转换得来。
让我们利用Spark源目录中的README文件的文本中创建一个新的DataSet:
scala> val textFile = spark.read.textFile("README.md")
textFile: org.apache.spark.sql.Dataset[String] = [value: string]
我们可以直接调用方法从DataSet里得出某些值,也可以把一个DataSet转换成一个新的Dataset。更多信息,请看DataSet API文档。
scala> textFile.count() // Number of items in this Dataset
res0: Long = 126 // May be different from yours as README.md will change over time, similar to other outputs
scala> textFile.first() // First item in this Dataset
res1: String = # Apache Spark
现在让我们转换这个Dataset到一个新的Dataset。我们调用filter来返回一个新的Dataset。
scala> val linesWithSpark = textFile.filter(line => line.contains("Spark"))
linesWithSpark: org.apache.spark.sql.Dataset[String] = [value: string]
当然,我们可以把Transform 和 Action 连接起来一起执行:
scala> textFile.filter(line => line.contains("Spark")).count() // How many lines contain "Spark"?
res3: Long = 15
更多DataSet 操作
DataSet的Action和Transformation操作可实现更复杂的计算。比方说,我们想找到最多的单词:
scala> textFile.map(line => line.split(" ").size).reduce((a, b) => if (a > b) a else b)
res4: Long = 15
里面的操作如下:
1. 将一行map到一个整数值,创建一个新的DataSet。
2. 在该DataSet上调用reduce来查找最大的字数
一种常见的数据流模式是MapReduce,正如Hadoop所普及的。Spark可以轻易实现MapReduce的操作:
scala> val wordCounts = textFile.flatMap(line => line.split(" ")).groupByKey(identity).count()
wordCounts: org.apache.spark.sql.Dataset[(String, Long)] = [value: string, count(1): bigint]
具体流程如下:
1. 调用flatMap将行数据集转换为单词数据集
2. 结合groupByKey和count来计算文件中每个字的计数,作为(String,Long)格式保存起来。
如果想要把结果收集起来,可以调用collect方法:
scala> wordCounts.collect()
res6: Array[(String, Int)] = Array((means,1), (under,2), (this,3), (Because,1), (Python,2), (agree,1), (cluster.,1), ...)
缓存
Spark还支持将DataSet保存到集群范围内的内存缓存中。当重复访问数据时,如查询小的“热”数据集或运行迭代算法(如PageRank)时,这非常有用。
举一个简单的例子,让我们标记我们的linesWithSpark数据集被缓存:
scala> linesWithSpark.cache()
res7: linesWithSpark.type = [value: string]
scala> linesWithSpark.count()
res8: Long = 15
scala> linesWithSpark.count()
res9: Long = 15
使用Spark探索和缓存100行文本文件似乎很愚蠢,但有趣的部分是这些相同的功能可以用在非常大的数据集上,即使当它们被划分成数十或数百个节点时也可以缓存。
Spark应用程序
假设我们希望使用Spark API编写一个Spark 应用程序。我们将通过一个简单的应用程序,通过Scala(与SBT),Java(与Maven)和Python(PIP)。
我们将在Scala中创建一个非常简单的Spark应用程序,事实上,它被命名为SimpleApp.scala:
/* SimpleApp.scala */
import org.apache.spark.sql.SparkSession
object SimpleApp {
def main(args: Array[String]) {
val logFile = "YOUR_SPARK_HOME/README.md" // Should be some file on your system
val spark = SparkSession.builder.appName("Simple Application").getOrCreate()
val logData = spark.read.textFile(logFile).cache()
val numAs = logData.filter(line => line.contains("a")).count()
val numBs = logData.filter(line => line.contains("b")).count()
println(s"Lines with a: $numAs, Lines with b: $numBs")
spark.stop()
}
}
请注意,应用程序应该定义一个main()方法,而不是扩展scala.App。 scala.App的子类可能无法正常工作。
这个程序只是计算Spark Readme文件中包含’a’的行数和包含’b’的数字。
我们调用SparkSession.builder来构造[[SparkSession]],然后设置应用程序名称,最后调用getOrCreate来获取[[SparkSession]]实例。
我们的应用程序依赖于Spark API,所以我们还将包含一个sbt配置文件build.sbt,它解释了Spark是一个依赖项。该文件还添加了Spark所依赖的存储库:
name := "Simple Project"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.2.1"
为了正常工作,我们需要根据典型的目录结构来放置SimpleApp.scala和build.sbt。一旦放置好,我们可以创建一个包含应用程序代码的JAR包,然后使用spark-submit脚本来运行我们的程序。
# Your directory layout should look like this
$ find .
.
./build.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.11/simple-project_2.11-1.0.jar
# Use spark-submit to run your application
$ YOUR_SPARK_HOME/bin/spark-submit \
--class "SimpleApp" \
--master local[4] \
target/scala-2.11/simple-project_2.11-1.0.jar
...
Lines with a: 46, Lines with b: 23
更多
祝贺您运行您的第一个Spark应用程序!
最后,Spark在示例目录(Scala,Java,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