[譯]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
函式找出最大行的單詞數。map
和reduce
的引數是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
這裡我們結合了flatmap,map和reduceByKey轉換來計算檔案中每個單詞的數量,生成一個(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.scala
和simple.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目錄中包含了很多示例(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
相關文章
- Draft 文件翻譯 - 快速開始 - 概念Raft
- Draft 文件翻譯 - 快速開始 - 基礎APIRaftAPI
- kafka快速開始Kafka
- 從零開始認識 SparkSpark
- AngularJS快速開始AngularJS
- 【譯】如何開始CI
- 如何用 Spark 快速開發應用?Spark
- silky微服務快速開始微服務
- Cordova快速開始(安卓篇)安卓
- bootstrap-sass 快速開始boot
- Hbase快速開始——shell操作
- Airflow 中文文件:快速開始AI
- 快速開始grid佈局
- AngularJS教程一——快速開始AngularJS
- Spark 快速入門Spark
- 大資料開發-Spark-初識Spark-Graph && 快速入門大資料Spark
- SpringCloudConfig-快速開始SpringGCCloud
- 從演算法開始[快速排序]演算法排序
- 玩轉spring boot——快速開始Spring Boot
- [譯]UISearchController 教程:開始使用UIController
- 翻譯 | 開始使用 TypeScript 和 ReactTypeScriptReact
- [譯]Create ML教程:開始入門
- 快速開始HelloWorld和Python之禪Python
- Spark 叢集搭建從零開始之3 Spark Standalone叢集安裝、配置與測試Spark
- 快速開始api開發(一)專案初始化API
- 快速開始api開發(四)登入與認證API
- Spark 叢集搭建從零開始之2 Spark單機偽分散式安裝與配置Spark分散式
- gf 框架快速開始骨架 gf-start-kit框架
- Detectron2 快速開始,使用 WebCam 測試Web
- 快速開始api開發(三)第一個介面-註冊API
- 【譯】2019年開始使用TypescriptTypeScript
- 從零開始學typescript— 自動編譯TypeScript編譯
- 從Oclint開始接觸Clang編譯編譯
- [譯] 開始使用新的 CSS Typed Object ModelCSSObject
- Spark 安裝部署與快速上手Spark
- [譯] 5 款工具助力 React 快速開發React
- Spring Boot系列(一):Spring Boot快速開始Spring Boot
- 快速開始構建一個簡單專案