環(huán)境配置凿宾,Spark實(shí)現(xiàn)WordCount
本人準(zhǔn)備參加騰訊實(shí)習(xí)菌湃,有關(guān)大數(shù)據(jù)與機(jī)器學(xué)習(xí)惧所。由于本人對(duì)大數(shù)據(jù)一無(wú)所知下愈,因此準(zhǔn)備由Spark作為切入口開始自學(xué)势似,一步步完成機(jī)器學(xué)習(xí)各個(gè)算法在Spark上的應(yīng)用履因。自學(xué)過程中的點(diǎn)點(diǎn)滴滴都會(huì)記錄在簡(jiǎn)書上栅迄,希望可以與大家交流毅舆,共同學(xué)習(xí)。
配環(huán)境永遠(yuǎn)是開始學(xué)習(xí)一個(gè)新領(lǐng)域最難的一部分岂津,我花了兩天時(shí)間配置成功了MacOS下的Spark開發(fā)環(huán)境吮成,實(shí)現(xiàn)了基于Scala與sbt的WordCount粱甫,下面來(lái)一步步把步驟記錄下來(lái)魔种。
第1步:配置sbt在IntelliJ下編程環(huán)境
打開terminal
查看java版本节预,由于MacOS自帶java安拟,因此無(wú)需安裝
$ java -version
安裝sbt糠赦,這是編譯scala的工具
$ brew install sbt
查看sbt與scala信息
$ sbt about
下載安裝IntelliJ
安裝Scala Plugin:打開IntelliJ锅棕,在選擇項(xiàng)目界面,選擇Configure → Plugins → Install JetBrains Plugins顾瞻,搜索Scala并安裝
選擇默認(rèn)SDK:Configure → Project defaults → Project structure荷荤,SDK選擇Java1.8
至此scala在IntelliJ下的開發(fā)環(huán)境配置完畢
第2步:配置Spark工具包
下載Spark:下載地址会油,注意如果已經(jīng)安裝了Hadoop的話要下載對(duì)應(yīng)的版本古毛,下面的命令可以查看Hadoop版本
$ hadoop version
下載完畢后解壓并將其放在一個(gè)目錄下,假設(shè)放在/usr/shar/spark-2.1.0-bin-hadoop2.7
喇潘,那么我們往環(huán)境變量中添加Spark方便以后使用
$ vim .bash_profile
加入一行体斩,保存后重啟terminal即可
export SPARK_HOME=/usr/shar/spark-2.1.0-bin-hadoop2.7
至此,Spark環(huán)境配置完畢颖低,是不是非常方便
第3步:命令行形式操控Spark
(1) Python Spark
terminal中執(zhí)行命令
$ $SPARK_HOME/bin/pyspark
看到帥氣的Spark logo就表示已經(jīng)成功了
美中不足的是自帶的python shell沒有自動(dòng)補(bǔ)全等功能絮吵,使用ipython可以完美解決
首先,安裝ipython
$ pip install ipython
運(yùn)行Spark
$ PYSPARK_DRIVER_PYTHON=ipython $SPARK_HOME/bin/pyspark
讓我們來(lái)使用一些Spark的API來(lái)嘗試一些命令
>>> lines = sc.textFile("README.md") # 創(chuàng)建一個(gè)名為lines的RDD
>>> lines.count() # 統(tǒng)計(jì)RDD中的元素個(gè)數(shù)
127
>>> lines.first()
(2) Scala Spark Shell
$ $SPARK_HOME/bin/spark-shell
同樣完成一下行數(shù)統(tǒng)計(jì)的小應(yīng)用
scala> val lines = sc.textFile("README.md") // 創(chuàng)建一個(gè)名為lines的RDD
lines: spark.RDD[String] = MappedRDD[...]
scala> lines.count() // 統(tǒng)計(jì)RDD中的元素個(gè)數(shù)
res0: Long = 127
scala> lines.first() // 這個(gè)RDD中的第一個(gè)元素忱屑,也就是README.md的第一行
res1: String = # Apache Spark
第4步:構(gòu)建Spark獨(dú)立應(yīng)用蹬敲,WordCount
上面的是shell形式下調(diào)用Spark,而現(xiàn)在進(jìn)入更為重要的建立獨(dú)立項(xiàng)目莺戒,我看了很多教程伴嗡,但是每個(gè)教程都有一步兩步講的含糊不清,或者就是版本太老从铲,留下了許多坑。現(xiàn)在我總結(jié)了一個(gè)可以跑通的例子麻惶。
首先静稻,IntelliJ下創(chuàng)建sbt項(xiàng)目:打開IntelliJ → Create New Project → Scala → sbt → ProjectName = wordcount → Create
修改build.sbt,在最后加入一行Spark的包。注意scalaVersion一定要改成2.11嗅回,因?yàn)镾park2.1.0是基于Scala2.11的娃豹,默認(rèn)的2.12會(huì)報(bào)錯(cuò)躯畴!
name := "wordcount"
version := "1.0"
scalaVersion := "2.11.7"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.1.0"
讓我們先來(lái)看一下sbt項(xiàng)目的目錄結(jié)構(gòu)
├── build.sbt
├── project
│ ├── build.properties
│ ├── plugins.sbt
│ ├── project
│ └── target
├── src
│ ├── main
│ │ ├── java
│ │ ├── resources
│ │ ├── scala
│ │ └── scala-2.12
│ └── test
│ ├── java
│ ├── resources
│ ├── scala
│ └── scala-2.12
└── target
├── resolution-cache
├── scala-2.12
└── streams
我們需要寫的代碼主要放在/src/main/scala里面
下一步嚷缭,我們開始寫我們的代碼优床,具體細(xì)節(jié)不用深究,本章節(jié)只是為了配通環(huán)境
新建目錄/src/main/scala/com/oreilly/learningsparkexamples/mini/scala
添加第一個(gè)文件/src/main/scala/com/oreilly/learningsparkexamples/mini/scala/BasicMap.scala
/**
* Illustrates a simple map in Scala
*/
package com.oreilly.learningsparkexamples.scala
import org.apache.spark._
object BasicMap {
def main(args: Array[String]) {
val master = args.length match {
case x: Int if x > 0 => args(0)
case _ => "local"
}
val sc = new SparkContext(master, "BasicMap", System.getenv("SPARK_HOME"))
val input = sc.parallelize(List(1,2,3,4))
val result = input.map(x => x*x)
println(result.collect().mkString(","))
}
}
添加第二個(gè)文件/src/main/scala/com/oreilly/learningsparkexamples/mini/scala/WordCount.scala
/**
* Illustrates flatMap + countByValue for wordcount.
*/
package com.oreilly.learningsparkexamples.mini.scala
import org.apache.spark._
import org.apache.spark.SparkContext._
object WordCount {
def main(args: Array[String]) {
val inputFile = args(0)
val outputFile = args(1)
val conf = new SparkConf().setAppName("wordCount")
// Create a Scala Spark Context.
val sc = new SparkContext(conf)
// Load our input data.
val input = sc.textFile(inputFile)
// Split up into words.
val words = input.flatMap(line => line.split(" "))
// Transform into word and count.
val counts = words.map(word => (word, 1)).reduceByKey{case (x, y) => x + y}
// Save the word count back out to a text file, causing evaluation.
counts.saveAsTextFile(outputFile)
}
}
點(diǎn)擊右上角的Build Project圖標(biāo)就編譯成功了频蛔,如果沒有報(bào)錯(cuò)瀑粥,那么恭喜你舟肉,環(huán)境配置成功了。
第5步:使用spark-submit來(lái)運(yùn)行應(yīng)用
spark-submit腳本可以為我們配置 Spark 所要用到的一系列環(huán)境變量院领。
首先需要將我們編譯好的項(xiàng)目打包强法,最方便的方式就是進(jìn)入wordcount
目錄下,輸入
$ sbt package
打包好的文件就在/wordcount/target/scala-2.11/wordcount_2.11-1.0.jar
接下來(lái)就是利用Spark為我們提供的spark-submit來(lái)運(yùn)行應(yīng)用了,進(jìn)入wordcount
目錄下
$ $SPARK_HOME/bin/spark-submit \
--class com.oreilly.learningsparkexamples.mini.scala.WordCount \
./target/scala-2.11/wc_2.11-1.0.jar \
./input.txt ./wordcounts
下面來(lái)簡(jiǎn)單解釋一下上面的命令贪壳,--class
為使用的Class钻注,后面為jar包的路徑识埋,最后兩個(gè)為wordcount的兩個(gè)參數(shù)系忙,分別為輸入文件热监,和輸出文件路徑
我們的輸入文件\wordcount\input.txt
是這樣的
one two three four
four five six
one five six
one one three
運(yùn)行后,如果成功會(huì)在\wordcount\wordcounts\part-00000
中看到
(two,1)
(one,4)
(six,2)
(three,2)
(five,2)
(four,2)
至此香浩,我們的整個(gè)環(huán)境都配置成功啦,有問題請(qǐng)留言
參考資料
Big Data Analysis with Scala and Spark 洛桑聯(lián)邦理工學(xué)院 - Coursera