Spark 學習筆記

黃思喆發表於2015-05-27

Spark 學習筆記

Spark作為分散式系統框架的後起之秀(據說)各方面都要優於hadoop,有本地快取,原生支援潮潮的scala, 對python的支援強大到直接可以用ipython notebook 作為互動介面。 還有幾個正在開發中的分支框架分別用於機器學習和社交網路分析,簡直華麗的飛起。

安裝

根據阿帕奇基金會的尿性,應該是沒有所謂的安裝一說的,下載,解壓就能使用了,當然不要忘了設定環境變數,具體不囉嗦.

使用

spark全面支援scala和java,部分支援python。好在scala也是指令碼語言,所以相對比hadoop方便的多,先來看看兩種互動模式。

pyspark

命令列使用pyspark以後terminal中就會出現個大大SPARK圖案和熟悉的python預設互動介面,這太醜了有啥更優秀的沒?

利用PYSPARK_DRIVER_PYTHON=ipython ./bin/pyspark撥出ipython互動介面,這個比原來的好多了。

利用

 PYSPARK_DRIVER_PYTHON=ipython PYSPARK_DRIVER_PYTHON_OPTS="notebook --pylab inline" pyspark

呼叫ipython notebook

隨便進去個試試示例的程式,還是用WordCount好了

file = sc.textFile("hdfs://localhost:9000/user/huangsizhe/input/README.md")

count = file.flatMap(lambda line: line.split()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a+b)
count.saveAsTextFile("hdfs://localhost:9000/user/huangsizhe/wc")

成功輸出~

對了,為了避免hadoop警告建議把native lib 遮蔽了

spark-shell

這個是最常用的工具了,開發語言是scala,scala的話可以用指令碼也可以編譯執行,我覺得還是指令碼方便

使用寫的指令碼方法是

$spark-shell -i XXX.scala

這樣就會一條一條的執行了

還是WordCount

WordCount.scala放在$SPARKPATH/scala目錄下

val file = sc.textFile("hdfs://localhost:9000/user/huangsizhe/input/README.md")
val counts = file.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey(_ + _)
counts.saveAsTextFile("hdfs://localhost:9000/user/huangsizhe/wc")

執行

$spark-shell -i WordCount.scala

成功!

spark-submit

這個就有點像hadoop了,一般用於寫app,可以使用python,java,scala來寫程式,python不用編譯, java需要用maven編譯成jar檔案,scala也需要用sbt編譯成jar檔案。

python例子:

檔案結構如下

WordCountpy |
            |-input
            |-script|
                    |-WordCount.py

WordCount.py如下

import sys
from operator import add

from pyspark import SparkContext


if __name__ == "__main__":
    if len(sys.argv) != 3:
        print >> sys.stderr, "Usage: wordcount <input> <output>"
        exit(-1)
    sc = SparkContext(appName="PythonWordCount")
    lines = sc.textFile(sys.argv[1], 1)
    counts = lines.flatMap(lambda x: x.split(' ')) \
                  .map(lambda x: (x, 1)) \
                  .reduceByKey(add)
    output = counts.collect()
    for (word, count) in output:
        print "%s: %i" % (word, count)
    counts.saveAsTextFile(sys.argv[2])
    sc.stop()

cd 到WordCount專案根目錄下執行: spark-submit --master local[4] script/WordCount.py input/TheMostDistantWayInTheWorld.txt output 然後就會多出一個output資料夾,裡面存有結果~

scala例子

java的我就不寫了。。。

scala例子檔案結構如下: WordCountScala | |-input| | |-TheMostDistantWayInTheWorld.txt | |-src| | |-wordcountApp.scala | |-wordcountAPP.sbt

wordcountApp.scala如下

import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf

object WordCountApp {
    def main(args: Array[String]) {
        if (args.length < 2) {
          System.err.println("Usage: WordCountApp <input> <output>")
          System.exit(1)
        }

        val conf = new SparkConf().setAppName("WordCountAPP")
        val sc = new SparkContext(conf)
        val file = sc.textFile(args(0))
        val counts = file.flatMap(line => line.split(" ")).map(word => (word,1)).reduceByKey(_+_)
        println(counts)
        counts.saveAsTextFile(args(1))

        }
    }

wordcountAPP.sbt如下:

name := "wordcount"

version := "1.0"

scalaVersion := "2.10.4"

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

編譯:

cd 到 WordCountScala專案資料夾下

$ find .
$ sbt package

編譯成功你編譯完的程式就在target/scala-2.10/simple-project_2.10-1.0.jar

執行:

spark-submit   --class "WordCountApp"  \
 --master local[4]   \
 target/scala-2.10/wordcount_2.10-1.0.jar input/TheMostDistantWayInTheWorld.txt output

你就能看到output了

Streaming spark的流式計算系統

這個stream很牛,實時運算,似乎是strom的替代品,試試官方例子Networkwordcount.py

import sys

from pyspark import SparkContext
from pyspark.streaming import StreamingContext

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print >> sys.stderr, "Usage: network_wordcount.py <hostname> <port>"
        exit(-1)
    sc = SparkContext(appName="PythonStreamingNetworkWordCount")
    ssc = StreamingContext(sc, 1)

    lines = ssc.socketTextStream(sys.argv[1], int(sys.argv[2]))
    counts = lines.flatMap(lambda line: line.split(" "))\
                  .map(lambda word: (word, 1))\
                  .reduceByKey(lambda a, b: a+b)
    counts.pprint()

    ssc.start()
    ssc.awaitTermination()

執行

  1. nc -lk 9999開啟埠監聽
  2. 新開個terminal,cd 到該指令碼所在地址spark-submit network_wordcount.py localhost 9999
  3. 在nc -lk 那個terminal下輸入句子試試~ 可以在另一個terminal中看到每次回車後該行的單詞次數~

相關文章