2017年2月25日 星期六

[Scala] Big Data(5) 雜記,Cloudera Quickstart VM和萬年word count

其實蠻久之前就有用過Spark這個東西了,只是最近再拿出來玩玩發現發現好多東西都忘記,忘得精光那種,筆記這種東西真的好重要啊啊啊啊啊。

Cloudera Quickstart VM


為了練習Spark自己搞一個server雖然很霸氣,但不是所有人都有錢有閒這樣做的,如果只是為了練習,或是用少量資料驗證一下想法可不可行,誠心建議使用Cloudera Quickstart VM就好了。這個東西真的超級佛心的,一包拿來裡面該有的都有(Hadoop, Spark, Hive...),然後設定也算簡單,尤其是對於我這種對Architecture很沒轍的技術廢物(無誤)來說。

題外話,中視《飢餓遊戲》好看!
喔對了,為了平衡報導,其實另外一家叫做Hortonworks提供的Sandbox也不錯,有興趣的人也可以試試看。

然後我選用Docker VM,因為設定超級無敵簡單的就一頁而已,指令也沒幾行,連我都搞得定簡直太棒!不過得先安裝Docker就是了。設定步驟很簡單,以下也不過是把網頁上的Instruction翻成中文而已就醬。

在安裝好Docker之後,就打開terminal,用docker pull指令開始下載Cloudera QuickstartVM。
$ docker pull cloudera/quickstart

整包東西大概4GB左右,要稍微等一下。

然後鍵入指令,裡就會發現有一個image叫做cloudera/quickstart耶!(訝異個屁)
$ docker images
EPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
cloudera/quickstart  latest              4239cd2958c6        10 months ago       6.34 GB

記下對應的IMAGE ID,以上圖為例也就是4239cd2958c6,用來啟動Docker VM囉!
$ docker run \
--hostname=quickstart.cloudera \
--privileged=true \
-t -i -p 8888 \
[IMAGE ID] /usr/bin/docker-quickstart

然後那個[IMAGE ID]記得要換一下。然後基本上經過一段時間的等在就可以成功進入VM的根目錄了,我啟動的時候hue沒有成功,但是在Docker VM開始run之後重複幾次restart神奇的事情就發生了,像這樣:
[root@quickstart /]# service hue restart
Shutting down hue:
Starting hue:                                              [  OK  ]

但如果不是很在意hue的話也可以不理它啦,反正天下事只要牽涉到UI就是神煩(翻白眼)。至於確切原因我也不知到為何,反正它就是好了,很煩(知道原因的拜託留言或是托夢告訴我拜託!)。

看到Hue web UI就是心曠神怡而已

然後注意,如果這時候關掉terminal的話,所有資料都會消失,如果不想資料消失的話,請在剛剛的啟動加上-p選項或者用ctrl+p -> ctrl+q關掉terminal,這樣VM就會繼續運行。如果要重新接上,請用docker ps找到對應的conatiner id
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED    
56703ef28dc3        4239cd2958c6        "/usr/bin/docker-q..."   2 hours ago

然後docker attach
$ docker attach [CONTAINER ID]

如果要在執行其他指令的話,可以用docker exec,概念上和ssh差不多
$ sudo docker exec -i -t [CONTAINER ID] /bin/bash

千篇一律的Word count problem


接下來就是用Spark跑跑看最白爛(對,即便就是白爛我還是要跑)的word count,就是計算字數啦。首先得把檔案用docker cp從本機丟過去docker VM的container裡面。
$ docker cp word_count.txt [CONTAINER ID]:/word_count.txt

然後進入docker VM,把這個剛剛丟過來的檔案推到HDFS上。
[root@quickstart /]# hdfs dfs -mkdir temp
[root@quickstart /]# hdfs dfs -put word_count.txt temp/word_count.txt

之後進入Spark shell
[root@quickstart /]# spark-shell

之後就開始跑罐頭程式
scala> val file = sc.textFile("temp/word_count.txt")
file: org.apache.spark.rdd.RDD[String] = temp/word_count.txt MapPartitionsRDD[1] at textFile at :27

scala> val counts = file.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey(_ + _)
counts: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[4] at reduceByKey at :29

scala> counts.collect().foreach(println)
(Groovy..,1)
(found,1)
(Check,1)...

scala> counts.saveAsTextFile("temp/output")

寫資料路徑的時候要稍微小心一點,其實不一定像網路上的demo一樣寫完整的路徑,像這樣。

scala> val file = sc.textFile("hdfs://quickstart.cloudera:8020/user/root/temp/word_count.txt")

然後看一下HDFS看看有沒有存成功
[root@quickstart /]# hdfs dfs -ls temp/output
Found 3 items
-rw-r--r--   1 root supergroup          0 2017-02-25 19:56 temp/output/_SUCCESS
-rw-r--r--   1 root supergroup         93 2017-02-25 19:56 temp/output/part-00000
-rw-r--r--   1 root supergroup        127 2017-02-25 19:56 temp/output/part-00001