[译]Spark快速开始

本文是一个如何使用Spark的简要教程。首先通过Spark的交互式Shell来介绍API(使用Python或Scala),然后展示如何用Java,Scala和Python来写Spark引用程序。更完整的内容请参考编程指南

为了跟随这篇指南进行学习,请首先从Spark网站上下载一个Spark release包。因为我们这里不会使用HDFS,所以下载一个用于任意Hadoop版本的包即可。

使用Spark Shell进行交互式分析

基础

Spark的Shell提供了一种学习API的简单方法,同样也是交互式分析数据的强大工具。在Scala(运行在Java虚拟机上,可以使用现有的Java库)或Python中可用。在Spark目录下运行下面命令:

./bin/spark-shell

Spark的主要抽象是弹性分布式数据集(RDD)。RDD可以通过Hadoop输入格式(比如HDFS文件)或者其它RDD转换来创建。让我们使用Spark源路径的README文件的文本内容来创建一个RDD。

scala> val textFile = sc.textFile("README.md")
textFile: org.apache.spark.rdd.RDD[String] = README.md MapPartitionsRDD[1] at textFile at <console>:25

RDD有可以返回值的actions,有可以返回指向新RDD指针的transformations。让我们从几个actions开始:

scala> textFile.count() // Number of items in this RDD
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 RDD
res1: String = # Apache Spark

接下来使用transformation。我们使用filter transformation来返回一个包含文件条目子集的RDD。

scala> val linesWithSpark = textFile.filter(line => line.contains("Spark"))
linesWithSpark: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[2] at filter at <console>:27

可以把transformations和actions链接起来使用。

scala> textFile.filter(line => line.contains("Spark")).count() // How many lines contain "Spark"?
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。然后在这个新RDD上调用reduce函数找出最大行的单词数。mapreduce的参数是Scala函数式(闭包),并且可以使用任何语言特性或者Scala/Java库。例如,可以很容易地调用声明在其它地方的函数。可以使用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

一种常见的数据流模式为MapReduce,是由Hadoop推广的。Spark可以很容易地实现MapReduce:

scala> val wordCounts = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey((a, b) => a + b)
wordCounts: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[8] at reduceByKey at <console>:28

这里我们结合了flatmapmapreduceByKey转换来计算文件中每个单词的数量,生成一个(String,Int)对的RDD。
为了在我们的Shell中统计单词数量,可以使用collect action:

scala> wordCounts.collect()
res6: Array[(String, Int)] = Array((means,1), (under,2), (this,3), (Because,1), (Python,2), (agree,1), (cluster.,1), ...)

缓存

Spark支持拉取数据集到集群范围的内存缓存中。当数据需要重复访问时会非常有用,比如查询一个热数据集或者运行像PageRank这样的迭代算法。作为一个简单的例子,让我们把linesWithSpark数据集标记为缓存:

scala> linesWithSpark.cache()
res7: linesWithSpark.type = MapPartitionsRDD[2] at filter at <console>:27

scala> linesWithSpark.count()
res8: Long = 15

scala> linesWithSpark.count()
res9: Long = 15

用Spark来探索和缓存一个100行的文本文件看起来有点呆。有意思的是这些相同的函数可以用在非常庞大的数据集上,即使跨越数十或者数百个节点。你也可以像编程指南中描述的一样通过使用bin/spark-shell连接到集群的方式,来交互式地做这件事。

独立的应用程序

假设我们想用Spark API写一个独立的应用程序。可以使用Scala(with sbt),Java(with Maven)和Python实现一个简单的应用程序。

在Scala中创建一个简单的Spark应用程序,命名为SimpleApp.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(s"Lines with a: $numAs, Lines with b: $numBs")
    sc.stop()
  }
}

可以看到应用程序应该定义main()函数而不是扩展scala.App。使用scala.App的子类可能会运行不正常。这个程序就计算了Spark的README文件中包含a的行数和包含b的行数。注意把YOUR_SPARK_HOME替换成Spark的安装路径。不像之前使用Spark Shell的例子会初始化自己的SparkContext,我们需要初始化SparkContext作为程序的一部分。

我们要传一个包含了应用程序信息的SparkConf对象给SparkContext构造函数。

应用程序需要依赖Spark API,所以会包含一个sbt配置文件,simple.sbt,里面说明了Spark是一个依赖。这个文件也添加了一个Spark依赖的库:

name := "Simple Project"

version := "1.0"

scalaVersion := "2.11.7"

libraryDependencies += "org.apache.spark" %% "spark-core" % "2.1.0"

为了让sbt正确运行,我们需要根据经典的目录结构来组织 SimpleApp.scalasimple.sbt。完成之后,我们可以创建一个包含我们应用程序代码的JAR包,然后使用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.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应用程序!

  • 查看API的深入概述,从Spark编程指南开始,或者看其它组件的编程指南菜单。
  • 要在集群上运行应用程序,请看部署概述
  • 最后,Spark在examples目录中包含了很多示例(ScalaJavaPythonR),可以使用如下方式运行:
# 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容