2015/10/18

Apache Spark 測試 FPGrowth(傳統C語言與Spark 的簡易測試)


因為剛剛把 Apache 的 Spark 設定好,順便驗證測試看看效能如何?
剛好發現 Spark 的 MLLIB 內有內建的 FPGrowth 演算法,剛好跟它有點熟所以就用這個演算法加上網路上的資料來測試看看。

先講結論:資料量小,不利於使用巨量資料工具。


關於 fpgrowth 演算法請先參考這篇:
http://blog.jangmt.com/2015/10/fpgrowth-algorithm.html

底下紀錄測試的過程,及使用的參數。

測試運算資料來源:http://fimi.ua.ac.be/data/ Frequent Itemset Mining Dataset Repository---

LAB (1)
Christian Borgelt 寫的 C 語言程式 FPGrowth 對上 Spark scala fpgrowth 程式
---
# FPGrowth 先把 -m1 同時出現的SET設為1個,支持度 5 ,信任度為 80%(default)
# 這個案例花費了 0.09s 運算了 0.01s
[hadoop@hnamenode FrequentItemset]$ ./fpgrowth -m1 -s5 T10I4D100K.dat T10I4D100K.out.txt
./fpgrowth - find frequent item sets with the fpgrowth algorithm
version 6.7 (2015.08.18)         (c) 2004-2015   Christian Borgelt
reading T10I4D100K.dat ... [870 item(s), 100000 transaction(s)] done [0.09s].
filtering, sorting and recoding items ... [10 item(s)] done [0.00s].
sorting and reducing transactions ... [281/100000 transaction(s)] done [0.01s].
writing T10I4D100K.out.txt ... [10 set(s)] done [0.00s].
[hadoop@hnamenode FrequentItemset]$ cat T10I4D100K.out.txt
368 (7.828)
529 (7.057)
829 (6.81)
766 (6.265)
722 (5.845)
354 (5.835)
684 (5.408)
217 (5.375)
494 (5.102)
419 (5.057)

----
上面這個 fp-growth 程式是以 同一台機器的 masternode 跑的,但是沒有 20 台 SlaveNode。
----
底下這個案例參考官方網站的範例:scala 語言的 fp-growth 程式
http://spark.apache.org/docs/latest/mllib-frequent-pattern-mining.html#fp-growth 
FPgrowth MLIB
https://spark.apache.org/docs/latest/mllib-frequent-pattern-mining.html

使用 spark 用 standalone 模式,啟動 spark-shell
spark-shell  --master spark://192.168.1.100:7077
這套 spark 有1台 masternode 以及 20 台 slavenode,

首先把檔案放到 hadoop HDFS 內
[hadoop@hnamenode FrequentItemset]$ hdfs dfs -ls /public/FrequentItemset
Found 4 items
-rw-r--r--   3 hadoop supergroup    4022055 2015-10-17 21:39 /public/FrequentItemset/T10I4D100K.dat
-rw-r--r--   3 hadoop supergroup   15478113 2015-10-17 21:39 /public/FrequentItemset/T40I10D100K.dat
-rw-r--r--   3 hadoop supergroup         68 2015-10-17 21:42 /public/FrequentItemset/sample_fpgrowth.txt
-rw-r--r--   3 hadoop supergroup 1481890176 2015-10-17 23:13 /public/FrequentItemset/webdocs.dat

---
Apache Spark scala FPGrowth 並將支持度、出現數量設定為一樣。
---
import org.apache.spark.rdd.RDD
import org.apache.spark.mllib.fpm.FPGrowth

val data = sc.textFile("/public/FrequentItemset/T10I4D100K.dat")

val transactions: RDD[Array[String]] = data.map(s => s.trim.split(' '))

# setMinSupport(0.05) 為./fpgrowth程式的 -s5
val fpg = new FPGrowth().setMinSupport(0.05).setNumPartitions(10)
val model = fpg.run(transactions)

model.freqItemsets.collect().foreach { itemset =>
  println(itemset.items.mkString("[", ",", "]") + ", " + itemset.freq)
}


# 這是信任度 80%,可以忽略不計
val minConfidence = 0.8
model.generateAssociationRules(minConfidence).collect().foreach { rule =>
  println(
    rule.antecedent.mkString("[", ",", "]")
      + " => " + rule.consequent .mkString("[", ",", "]")
      + ", " + rule.confidence)
}
----
時間:約 40s
----
[368], 7828
[529], 7057
[829], 6810
[766], 6265
[722], 5845
[354], 5835
[684], 5408
[217], 5375
[494], 5102
[419], 5057

----
LAB(1)結果:
不用比了,Christian Borgelt 寫的 C 語言程式 FPGrowth  狂勝。
Spark 跑了快約 40 - 50 秒因為在分散資料及 I/O 的時間浪費太多了...
但這例子先確認正確的這樣產生的結果是一樣的,後續的比對才可以繼續下去。
----


----
LAB (2) 資料檔案更換為  http://fimi.ua.ac.be/data/webdocs.dat.gz 來測試
webdocs.dat 檔案約 1.4GB 
----
# 花費 39.75 + 2.02 + 1.57 = 43.34 秒
[hadoop@hnamenode FrequentItemset]$ ./fpgrowth -m1 -s50 webdocs.dat webdocs.out
./fpgrowth - find frequent item sets with the fpgrowth algorithm
version 6.7 (2015.08.18)         (c) 2004-2015   Christian Borgelt
reading webdocs.dat ... [5267656 item(s), 1692082 transaction(s)] done [39.75s].
filtering, sorting and recoding items ... [5 item(s)] done [2.02s].
sorting and reducing transactions ... [32/1692082 transaction(s)] done [1.57s].
writing webdocs.out ... [10 set(s)] done [0.00s].

[hadoop@hnamenode FrequentItemset]$ more webdocs.out
122 (84.4832)
8 122 (72.566)
8 (77.4013)
49 122 (65.9012)
49 8 122 (61.1858)
49 8 (63.1131)
49 (69.6349)
124 122 (50.2531)
124 (52.4418)
516 (50.7154)

---
scala FPGrowth
---
import org.apache.spark.rdd.RDD
import org.apache.spark.mllib.fpm.FPGrowth

# 檔案放到 HDFS 內
val data = sc.textFile("/public/FrequentItemset/webdocs.dat")

val transactions: RDD[Array[String]] = data.map(s => s.trim.split(' '))

val fpg = new FPGrowth().setMinSupport(0.5).setNumPartitions(10)
val model = fpg.run(transactions)

model.freqItemsets.collect().foreach { itemset =>
  println(itemset.items.mkString("[", ",", "]") + ", " + itemset.freq)
}

val minConfidence = 0.8
model.generateAssociationRules(minConfidence).collect().foreach { rule =>
  println(
    rule.antecedent.mkString("[", ",", "]")
      + " => " + rule.consequent .mkString("[", ",", "]")
      + ", " + rule.confidence)
}

----
15/10/18 02:48:47
15/10/18 02:49:34  共花費 47秒
----
[122], 1429525
[8], 1309694
[8,122], 1227876
[49], 1178279
[49,8], 1067926
[49,8,122], 1035314
[49,122], 1115102
[124], 887358
[124,122], 850323
[516], 858146
----
LAB(2) 結果:
47 > 43 仍是傳統作法獲勝,但是時間上已經相差不多。資料量確實影響了計算的速度。
----


----
LAB (3) 
----
接著繼續把檔案放大,這個 webdocs.dat 檔案放大 *2 , *4 , * 10 的倍數來測試。
-rw-rw-r--. 1 hadoop hadoop  14G Oct 18 00:29 webdocs10.dat
-rw-rw-r--. 1 hadoop hadoop 2.8G Oct 18 00:29 webdocs2.dat
-rw-rw-r--. 1 hadoop hadoop 5.6G Oct 18 00:29 webdocs4.dat
-rw-rw-r--. 1 hadoop hadoop 1.4G Oct 14  2010 webdocs.dat

-----
此處以 webdocs10.dat 這個 14G 的檔案來說,如果以傳統的方法會遇到巨大的困難
光是 load 資料到記憶體就花了 436.84s ,運算 8.30s + 15.03s 約計 460 秒
-----
[hadoop@hnamenode FrequentItemset]$ ./fpgrowth -m1 -s50 webdocs10.dat webdocs10.out
./fpgrowth - find frequent item sets with the fpgrowth algorithm
version 6.7 (2015.08.18)         (c) 2004-2015   Christian Borgelt
reading webdocs10.dat ... [5267656 item(s), 16920820 transaction(s)] done [436.84s].
filtering, sorting and recoding items ... [5 item(s)] done [8.30s].
sorting and reducing transactions ... [32/16920820 transaction(s)] done [15.03s].
writing webdocs10.out ... [10 set(s)] done [0.00s].
----
[hadoop@hnamenode FrequentItemset]$ cat webdocs10.out 
122 (84.4832)
8 122 (72.566)
8 (77.4013)
49 122 (65.9012)
49 8 122 (61.1858)
49 8 (63.1131)
49 (69.6349)
124 122 (50.2531)
124 (52.4418)
516 (50.7154)

-----
如果以 Spark Scala FPGrowth 運算,它透過分散運算到 20 台 pc 配合 hdfs 分散存取
spark-shell  --master spark://192.168.1.100:7077
----
import org.apache.spark.rdd.RDD
import org.apache.spark.mllib.fpm.FPGrowth

# 更換檔案為 /public/FrequentItemset/webdocs10.dat (在 HDFS內)
val data = sc.textFile("/public/FrequentItemset/webdocs10.dat")

val transactions: RDD[Array[String]] = data.map(s => s.trim.split(' '))

# 條件一樣
val fpg = new FPGrowth().setMinSupport(0.5).setNumPartitions(10)
val model = fpg.run(transactions)

model.freqItemsets.collect().foreach { itemset =>
  println(itemset.items.mkString("[", ",", "]") + ", " + itemset.freq)
}
----
15/10/18 02:18:29 開始
15/10/18 02:20:28 結束,約 119 秒
[122], 14295250
[8], 13096940
[8,122], 12278760
[49], 11782790
[49,8], 10679260
[49,8,122], 10353140
[49,122], 11151020
[124], 8873580
[124,122], 8503230
[516], 8581460
----

Spark 工作流程
Spark 運算流程 https://spark.apache.org/docs/1.5.1/img/cluster-overview.png 

----
心得:
* 使用 Hadoop or Spark 這類的 big data 運算工具,初期消耗的運算成本很高,當資料量大到超過一般機器無法處理的程度時,才能顯示它和傳統運算的差異。

* 就這陣子測試的心得,如果你的資料量大於 1GB 後才有使用巨量運算的價值。

* 不過,兩種方式本來就是不一樣,硬是拿來比較不是很妥當。在適當的資料量,選擇適合的工具,才是比較正確的作法。


關聯規則--用來發現資料中屬性具有高度關聯的樣式(fpgrowth algorithm)


這篇不是要講很艱深的東西,簡單解釋一下啥事關聯規則。


基本上上面這張購物欄交易資料,透過底下的 apriori 演算法程式,可以找到啤酒和尿布具有很大的相關性,他的支持度高達 50 。故事請看這裡。這是個範例,只是說明關聯規則程式可發覺這樣形式的規則關聯樣式。



在網路上有個人 Christian Borgelt 寫了很多程式,其中有 apriori 和 fpgrowth ,基本上這兩個程式做的工作差不多,但是 fpgrowth 有效率多了。

所以今天用這個 fpgrowth 程式來跑跑看數據。

我從:http://fimi.ua.ac.be/data/ Frequent Itemset Mining Dataset Repository 抓了很多資料
http://fimi.ua.ac.be/data/T10I4D100K.dat
http://fimi.ua.ac.be/data/T40I10D100K.dat
http://fimi.ua.ac.be/data/webdocs.dat.gz

放到我的電腦內,然後去找 Christian Borgelt http://www.borgelt.net/fpgrowth.html 抓了一些程式。
大概長的這樣:
[hadoop@hnamenode FrequentItemset]$ ls -la
-rwxrwxr-x. 1 hadoop hadoop      486760 Sep  5 05:17 fpgrowth
-rw-rw-r--. 1 hadoop hadoop     4022055 Oct 14  2010 T10I4D100K.dat
-rw-rw-r--. 1 hadoop hadoop    15478113 Oct 14  2010 T40I10D100K.dat
-rw-rw-r--. 1 hadoop hadoop         151 Oct 17 23:15 webdocs.out

有個很簡單的檔案  sample_fpgrowth.txt

[hadoop@hnamenode FrequentItemset]$ cat sample_fpgrowth.txt 
r z h k p
z y x w v u t s
s x o n r
x z y m t s q e
z
x z y r q t p

# -m3 為找出三個元素在一起 , -s50 支持度 50  , 預設信任度為 80%
[hadoop@hnamenode FrequentItemset]$ ./fpgrowth -m3 -s50 sample_fpgrowth.txt sample_fpgrowth.out
./fpgrowth - find frequent item sets with the fpgrowth algorithm
version 6.7 (2015.08.18)         (c) 2004-2015   Christian Borgelt
reading sample_fpgrowth.txt ... [17 item(s), 6 transaction(s)] done [0.00s].
filtering, sorting and recoding items ... [6 item(s)] done [0.00s].
sorting and reducing transactions ... [4/6 transaction(s)] done [0.00s].
writing sample_fpgrowth.out ... [5 set(s)] done [0.00s].

[hadoop@hnamenode FrequentItemset]$ cat sample_fpgrowth.out 
y x z (50)
t z x y (50)
t z x (50)
t z y (50)
t x y (50)

可以知道上面這五個組合,是 sample_fpgrowth.txt 這裡最常出現的組合。

後來繼續用 fpgrowth 依序分析底下這些檔案,做了一些範例。
[hadoop@hnamenode FrequentItemset]$ ./fpgrowth -m2 -s1 T10I4D100K.dat T10I4D100K.out.txt
./fpgrowth - find frequent item sets with the fpgrowth algorithm
version 6.7 (2015.08.18)         (c) 2004-2015   Christian Borgelt
reading T10I4D100K.dat ... [870 item(s), 100000 transaction(s)] done [0.09s].
filtering, sorting and recoding items ... [375 item(s)] done [0.01s].
sorting and reducing transactions ... [87314/100000 transaction(s)] done [0.02s].
writing T10I4D100K.out.txt ... [10 set(s)] done [0.09s].
[hadoop@hnamenode FrequentItemset]$ cat T10I4D100K.out.txt
829 368 (1.194)
789 829 (1.194)
682 368 (1.193)
346 217 (1.336)
825 39 (1.187)
390 722 (1.042)
227 390 (1.049)
704 39 (1.107)
704 825 39 (1.035)
704 825 (1.102)

[hadoop@hnamenode FrequentItemset]$ ./fpgrowth -m3 -s2 T40I10D100K.dat T40I10D100K.out.txt
./fpgrowth - find frequent item sets with the fpgrowth algorithm
version 6.7 (2015.08.18)         (c) 2004-2015   Christian Borgelt
reading T40I10D100K.dat ... [942 item(s), 100000 transaction(s)] done [0.29s].
filtering, sorting and recoding items ... [610 item(s)] done [0.01s].
sorting and reducing transactions ... [99929/100000 transaction(s)] done [0.13s].
writing T40I10D100K.out.txt ... [6 set(s)] done [1.81s].

[hadoop@hnamenode FrequentItemset]$ cat T40I10D100K.out.txt
829 529 368 (2.288)
217 529 368 (2.181)
682 489 368 (2.42)
692 529 368 (2.373)
895 937 368 (2.081)
198 937 368 (2.099)


[hadoop@hnamenode FrequentItemset]$ ./fpgrowth -m6 -s23 webdocs.dat webdocs.out.txt
./fpgrowth - find frequent item sets with the fpgrowth algorithm
version 6.7 (2015.08.18)         (c) 2004-2015   Christian Borgelt
reading webdocs.dat ... [5267656 item(s), 1692082 transaction(s)] done [40.53s].
filtering, sorting and recoding items ... [39 item(s)] done [2.25s].
sorting and reducing transactions ... [959755/1692082 transaction(s)] done [3.50s].
writing webdocs.out.txt ... [13 set(s)] done [1.47s].

[hadoop@hnamenode FrequentItemset]$ cat webdocs.out.txt
171 124 516 49 8 122 (24.2785)
51 124 516 49 8 122 (26.1091)
51 171 516 49 8 122 (23.7428)
121 124 516 49 8 122 (26.9704)
121 51 516 49 8 122 (26.0395)
121 51 124 49 8 122 (24.6961)
121 51 124 516 8 122 (23.2243)
121 171 516 49 8 122 (24.2021)
121 171 124 49 8 122 (23.0385)
60 124 516 49 8 122 (24.0302)
60 121 516 49 8 122 (24.4904)
60 121 124 49 8 122 (23.5529)
60 51 516 49 8 122 (23.2219)

如果仔細看可以得知,這幾個檔案容量大小差很多。可以仔細觀察它門的執行時間。
-rw-r--r--. 1 hadoop hadoop   68 Oct 17 22:12 sample_fpgrowth.txt
-rw-rw-r--. 1 hadoop hadoop 3.9M Oct 14  2010 T10I4D100K.dat
-rw-rw-r--. 1 hadoop hadoop  15M Oct 14  2010 T40I10D100K.dat
-rw-rw-r--. 1 hadoop hadoop 1.4G Oct 14  2010 webdocs.dat

除了 webdocs.dat 這個檔案,跑比較久外,其他都很快。
講這多,就是剛有機會用 apache spark 來跑   fpgrowth algorithm 想要知道揪竟 big data 要多大才有他的效益。

延伸閱讀:
Apache Spark 測試 FPGrowth(傳統C語言與Spark 的簡易測試)http://blog.jangmt.com/2015/10/apache-spark-fpgrowthcspark.html

2015/10/17

Hadoop HDFS 上傳檔案速度測試


因為不太清楚 Hadoop HDFS 在傳輸檔案的速度,所以寫了一個小程式來測試 HDFS 上傳檔案的速度。

先講結論:hdfs 大概會花3秒的時間做協調的傳輸工作,所以大約 1MB 左右的時間都是 3 秒。傳輸的檔案越大,速度越快。

結果整理如下:

容量      傳輸時間  平均速度(MBytes)
110K 3 36KB/S
1.1MB 3 375KB/S
10.7MB   4 2739.2KB/S --> 2.675MB
107.1MB   9   11.9MB/S
1.0GB   23 44.521MB/S
11GB   216 52.148MB/S

過程及程式測試 shell script
[hadoop@hnamenode input]$ cat run_put.sh
#!/bin/bash
ARGC1='input.txt'
ARGC1=$1
if [ "ARGC1" != "" ]; then
PROG_START=$(date +%s)
hdfs dfs -put ${ARGC1} /public/data/
PROG_END=$(date +%s)
PROG_DURING=$(expr $PROG_END - $PROG_START)
echo "上傳 ${ARGC1} 檔案到 HDFS:/public/data/ 目錄下"
echo "花費時間: ${PROG_DURING} 秒"
hdfs dfs -ls -h /public/data/${ARGC1}
fi

[hadoop@hnamenode input]$ ls -alh
total 12G
drwxrwxr-x. 2 hadoop hadoop 4.0K Oct 17 13:23 .
drwxrwxr-x. 4 hadoop hadoop 4.0K Oct  4 00:26 ..
-rw-rw-r--. 1 hadoop hadoop  11G Oct  1 22:33 input100K.txt
-rw-rw-r--. 1 hadoop hadoop  11M Oct  1 22:31 input100.txt
-rw-rw-r--. 1 hadoop hadoop 1.1G Oct  1 22:32 input10K.txt
-rw-rw-r--. 1 hadoop hadoop 1.1M Oct  1 22:30 input10.txt
-rw-rw-r--. 1 hadoop hadoop 108M Oct  1 22:31 input1K.txt
-rw-r--r--. 1 hadoop hadoop 110K Oct  1 22:18 input.txt
-rwxrwxr-x. 1 hadoop hadoop  343 Oct 17 13:23 run_put.sh

[hadoop@hnamenode input]$ ./run_put.sh input.txt
上傳 input.txt 檔案到 HDFS:/public/data/ 目錄下
花費時間: 3 秒
-rw-r--r--   3 hadoop supergroup    109.7 K 2015-10-17 13:32 /public/data/input.txt
[hadoop@hnamenode input]$ ./run_put.sh input10.txt
上傳 input10.txt 檔案到 HDFS:/public/data/ 目錄下
花費時間: 3 秒
-rw-r--r--   3 hadoop supergroup      1.1 M 2015-10-17 13:24 /public/data/input10.txt
[hadoop@hnamenode input]$ ./run_put.sh input100.txt
上傳 input100.txt 檔案到 HDFS:/public/data/ 目錄下
花費時間: 4 秒
-rw-r--r--   3 hadoop supergroup     10.7 M 2015-10-17 13:25 /public/data/input100.txt
[hadoop@hnamenode input]$ ./run_put.sh input1K.txt
上傳 input1K.txt 檔案到 HDFS:/public/data/ 目錄下
花費時間: 9 秒
-rw-r--r--   3 hadoop supergroup    107.1 M 2015-10-17 13:25 /public/data/input1K.txt
[hadoop@hnamenode input]$ ./run_put.sh input10K.txt
上傳 input10K.txt 檔案到 HDFS:/public/data/ 目錄下
花費時間: 23 秒
-rw-r--r--   3 hadoop supergroup      1.0 G 2015-10-17 13:26 /public/data/input10K.txt
[hadoop@hnamenode input]$ ./run_put.sh input100K.txt
上傳 input100K.txt 檔案到 HDFS:/public/data/ 目錄下
花費時間: 216 秒
-rw-r--r--   3 hadoop supergroup      10.5 G 2015-10-17 13:31 /public/data/input100K.txt


2015/10/11

chrony 網路對時服務


----
chrony 網路對時服務
----
NTPd 套件在 CentOS 7 以後,逐漸被棄用了。改成 chrony 套件提供服務

# 安裝 chrony 移除 ntp ,並啟動服務
yum remove -y ntp
yum install -y chrony
systemctl start chronyd.service
systemctl enable chronyd.service

# 驗證程序是否工作
[root@hnamenode ~]# systemctl status chronyd.service
chronyd.service - NTP client/server
   Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled)
   Active: active (running) since Sat 2015-10-10 15:57:08 CST; 23h ago
 Main PID: 886 (chronyd)
   CGroup: /system.slice/chronyd.service
           └─886 /usr/sbin/chronyd -u chrony

Oct 10 15:57:08 hnamenode.cm.nsysu.edu.tw systemd[1]: Starting NTP client/server...
Oct 10 15:57:08 hnamenode.cm.nsysu.edu.tw chronyd[886]: chronyd version 1.29.1 starting
Oct 10 15:57:08 hnamenode.cm.nsysu.edu.tw chronyd[886]: Linux kernel major=3 minor=10 patch=0
Oct 10 15:57:08 hnamenode.cm.nsysu.edu.tw chronyd[886]: hz=100 shift_hz=7 freq_scale=1.00000000 nominal...l=2
Oct 10 15:57:08 hnamenode.cm.nsysu.edu.tw chronyd[886]: Frequency -21.302 +/- 0.046 ppm read from /var/...ift
Oct 10 15:57:08 hnamenode.cm.nsysu.edu.tw systemd[1]: Started NTP client/server.
Oct 10 15:57:22 hnamenode.cm.nsysu.edu.tw chronyd[886]: Selected source 120.119.31.1
Oct 10 16:02:32 hnamenode.cm.nsysu.edu.tw chronyd[886]: Selected source 140.117.69.1
Oct 11 15:36:00 hnamenode.cm.nsysu.edu.tw systemd[1]: Started NTP client/server.
Hint: Some lines were ellipsized, use -l to show in full.

# 觀看目前的同步狀態
[root@hnamenode ~]# chronyc sources -v
210 Number of sources = 4

  .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
 / .- Source state '*' = current synced, '+' = combined , '-' = not combined,
| /   '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
||                                                 .- xxxx [ yyyy ] +/- zzzz
||                                                /   xxxx = adjusted offset,
||         Log2(Polling interval) -.             |    yyyy = measured offset,
||                                  \            |    zzzz = estimated error.
||                                   |           |                        
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* cm.nsysu.edu.tw               3  10   377   903  +7941ns[  +35us] +/-   22ms
^- atelieralica.idv.tw           3   9   135   410    -52ms[  -52ms] +/-  426ms
^- venus.stu.edu.tw              2  10   377    63  -3401us[-3401us] +/-   71ms
^- edm.butyshop.com              3   9   337   398  -3305us[-3305us] +/-   66ms

R in HADOOP - install


R in HADOOP - install
----------------

就是再 R 透過 lib 呼叫 HADOOP 的 api 跑 hdfs 及 mapreduce 程式

------
Step 0 : 先把 hadoop 的系統環境變數確認,可以用 env 看到底下設定的環境變數
------
# 底下為我設定的範例,請以你的 hadoop env 路徑修改
[root@hdatanode17 ~]# cat .bash_profile 
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi


# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

# ----------------------------------------------
# HADOOP ENV
# ----------------------------------------------
#JAVA
export JAVA_HOME=/usr/java/latest
export JRE_HOME=/usr/java/latest/jre

# HADOOP
export HADOOP_PREFIX=/home/hadoop/hadoop
export HADOOP_HOME=$HADOOP_PREFIX
export HADOOP_COMMON_HOME=$HADOOP_PREFIX
export HADOOP_CONF_DIR=$HADOOP_PREFIX/etc/hadoop
export HADOOP_HDFS_HOME=$HADOOP_PREFIX
export HADOOP_MAPRED_HOME=$HADOOP_PREFIX
export HADOOP_YARN_HOME=$HADOOP_PREFIX
export HADOOP_NAMENODE_OPTS="-XX:+UseParallelGC -Xmx1g"

export YARN_HOME=$HADOOP_HOME
#export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
#export HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib"

# mapreduce app
export HADOOP_CLASSPATH=${JAVA_HOME}/lib/tools.jar

# R-HADOOP
export HADOOP_CMD=$HADOOP_PREFIX/bin/hadoop
export HADOOP_STREAMING="$HADOOP_PREFIX/share/hadoop/tools/lib/hadoop-streaming-2.7.1.jar"

# HIVE
export HIVE_HOME=/home/hadoop/apache-hive

# ANT
export ANT_LIB=/usr/java/ant/lib
export ANT_HOME=/usr/java/ant/

# Maven
export MAVEN_HOME=/usr/java/maven/
export MAVEN_LIB=/usr/java/maven/lib

# PIG
export PIG_HOME=/home/hadoop/apache-pig

# SCALA
export SCALA_HOME=/usr/local/scala/scala-2.11.7

# SPARK
export SPARK_HOME=/home/hadoop/apache-spark/

# APP ENV
export PATH=$PATH:$PIG_HOME/bin:$HIVE_HOME/bin:$HADOOP_PREFIX/sbin:$HADOOP_PREFIX/bin:$ANT_HOME/bin:$MAVEN_HOME/bin:$SCALA_HOME/bin:$SPARK_HOME/bin

# JAVA ENV
export PATH=$PATH:$HADOOP_PREFIX/sbin:$HADOOP_PREFIX/bin:$JAVA_HOME/bin:$JRE_HOME/bin

# 重新 load .bash_profile  設定檔,讓目前的環境變數可以動作生效
[root@hdatanode17 ~]# source .bash_profile
# env 指令可以驗證
[root@hdatanode17 ~]# env

------
Step 1 :先執行做 R javareconf 確定預設的 javareconf 路徑是正確的才進行後續的安裝,不對的話請修正 java 路徑
------
[root@hdatanode17 ~]# echo $JAVA_HOME
/usr/java/latest

[root@hdatanode17 dl]# java -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)

[root@hdatanode17 ~]#  R CMD javareconf
Java interpreter : /usr/java/latest/jre/bin/java
Java version     : 1.8.0_51
Java home path   : /usr/java/latest
Java compiler    : /usr/java/latest/bin/javac
Java headers gen.: /usr/java/latest/bin/javah
Java archive tool: /usr/java/latest/bin/jar
Java archive tool: /usr/java/latest/bin/jar

trying to compile and link a JNI program
detected JNI cpp flags    : -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
detected JNI linker flags : -L$(JAVA_HOME)/jre/lib/amd64/server -ljvm
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -I/usr/java/latest/include -I/usr/java/latest/include/linux -I/usr/local/include    -fpic  -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic  -c conftest.c -o conftest.o
gcc -m64 -std=gnu99 -shared -L/usr/lib64/R/lib -Wl,-z,relro -o conftest.so conftest.o -L/usr/java/latest/jre/lib/amd64/server -ljvm -L/usr/lib64/R/lib -lR


JAVA_HOME        : /usr/java/latest
Java library path: $(JAVA_HOME)/jre/lib/amd64/server
JNI cpp flags    : -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
JNI linker flags : -L$(JAVA_HOME)/jre/lib/amd64/server -ljvm
Updating Java configuration in /usr/lib64/R
Done.

------
Step 2 : 安裝更新 R base
------
[root@hdatanode17 ~]# yum install R -y

------
Step 3 : 用 Root 進入 R 安裝 rmr2 所需要的libs ,先從 CRAN 抓檔案,沒有的再抓檔案編譯。
------
[root@hdatanode17 ~]#  R
# 自動化步驟:(底下你可以直接複製貼入 R 內)
chooseCRANmirror(ind=83);
install.packages(c("codetools","R","Rcpp","RJSONIO","bitops","digest","functional","stringr","plyr","reshape2","rJava","caTools"));

------
Step 4: 安裝 rmr2 and rhdfs 套件
------
軟體可以到這裡抓: https://github.com/RevolutionAnalytics/RHadoop/wiki
以 rmr2 (3.3.0) 為例,抓取檔案:
wget --no-check-certificate https://raw.github.com/RevolutionAnalytics/rmr2/3.3.1/build/rmr2_3.3.1.tar.gz
命令列安裝:
R CMD INSTALL rmr2_3.3.1.tar.gz

以rhdfs (1.0.8) 為例,抓取檔案:
wget --no-check-certificate  https://raw.github.com/RevolutionAnalytics/rhdfs/master/build/rhdfs_1.0.8.tar.gz
命令列安裝:
R CMD INSTALL rhdfs_1.0.8.tar.gz

如果寫批次命令,如下列,可以直接貼到命令列安裝:
R CMD INSTALL bitops_1.0-6.tar.gz
R CMD INSTALL caTools_1.17.1.tar.gz
R CMD INSTALL digest_0.6.8.tar.gz
R CMD INSTALL functional_0.6.tar.gz
R CMD INSTALL magrittr_1.5.tar.gz
R CMD INSTALL plyr_1.8.3.tar.gz
R CMD INSTALL Rcpp_0.12.0.tar.gz
R CMD INSTALL reshape2_1.4.1.tar.gz
R CMD INSTALL rJava_0.9-7.tar.gz
R CMD INSTALL RJSONIO_1.3-0.tar.gz
R CMD INSTALL stringi_0.5-5.tar.gz
R CMD INSTALL stringr_1.0.0.tar.gz
R CMD INSTALL rhdfs_1.0.8.tar.gz
R CMD INSTALL rmr2_3.3.1.tar.gz

------
Step 5 :驗證安裝是否正確, rmr2 and rhdfs 是否可以工作?
------
[root@hdatanode20 R]# R
Sys.getenv()
Sys.setenv(HADOOP_CMD="/home/hadoop/hadoop/bin/hadoop")
Sys.setenv(JAVA_HOME="/usr/java/latest")
Sys.setenv(HADOOP_STREAMING="/home/hadoop/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.7.1.jar")
library(rhdfs)
library(rmr2)
hdfs.init()
hdfs.ls("/")
q()

執行的過程大概是這樣結果,主要看 rmr2 及 rhdfs 的 lib load 過程:
[root@hdatanode20 R]# R

..略 ...

> Sys.setenv(HADOOP_CMD="/home/hadoop/hadoop/bin/hadoop")
> Sys.setenv(JAVA_HOME="/usr/java/latest")
> Sys.setenv(HADOOP_STREAMING="/home/hadoop/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.7.1.jar")
> library(rhdfs)
Loading required package: rJava

HADOOP_CMD=/home/hadoop/hadoop/bin/hadoop

Be sure to run hdfs.init()
> library(rmr2)
Please review your hadoop settings. See help(hadoop.settings)
Warning message:
S3 methods ‘gorder.default’, ‘gorder.factor’, ‘gorder.data.frame’, ‘gorder.matrix’, ‘gorder.raw’ were declared in NAMESPACE but not found
> hdfs.init()
15/10/11 00:46:34 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
> hdfs.ls("/")
  permission  owner      group size          modtime    file
1 drwxr-xr-x hadoop supergroup    0 2015-10-01 11:10   /home
2 drwxr-xr-x hadoop supergroup    0 2015-09-29 14:03 /public
3 drwxrwxrwx hadoop supergroup    0 2015-10-02 12:57    /tmp
4 drwxr-xr-x hadoop supergroup    0 2015-10-01 14:10   /user
> q()
Save workspace image? [y/n/c]: n
[root@hdatanode20 R]#


REF:
https://bigdatastudy.hackpad.com/ep/pad/static/IADMBeqF0vV
https://github.com/RevolutionAnalytics/RHadoop/wiki

-----------------------------------
install OK
-----------------------------------


----
以上可以寫成批次檔案執行:
----

1.建立檔案: install_pack.R
[root@hdatanode19 R]# cat install_pack.R
chooseCRANmirror(ind=83);
install.packages(c("codetools","R","Rcpp","RJSONIO","bitops","digest","functional","stringr","plyr","reshape2","rJava","caTools"));
install.packages(c("arules"));

2.建立檔案: install_check.R
[root@hdatanode19 R]# cat install_check.R
Sys.getenv()
Sys.setenv(HADOOP_CMD="/home/hadoop/hadoop/bin/hadoop")
Sys.setenv(JAVA_HOME="/usr/java/latest")
Sys.setenv(HADOOP_STREAMING="/home/hadoop/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.7.1.jar")
library(rhdfs)
library(rmr2)
hdfs.init()
hdfs.ls("/")

3.建立檔案: install_lib.sh
[root@hdatanode19 R]# cat install_lib.sh 
#/bin/bash
P='/root/dl/R/'
R CMD javareconf
R CMD BATCH ${P}install_pack.R
R CMD INSTALL ${P}bitops_1.0-6.tar.gz
R CMD INSTALL ${P}caTools_1.17.1.tar.gz
R CMD INSTALL ${P}digest_0.6.8.tar.gz
R CMD INSTALL ${P}functional_0.6.tar.gz
R CMD INSTALL ${P}magrittr_1.5.tar.gz
R CMD INSTALL ${P}plyr_1.8.3.tar.gz
R CMD INSTALL ${P}Rcpp_0.12.0.tar.gz
R CMD INSTALL ${P}reshape2_1.4.1.tar.gz
R CMD INSTALL ${P}rJava_0.9-7.tar.gz
R CMD INSTALL ${P}RJSONIO_1.3-0.tar.gz
R CMD INSTALL ${P}stringi_0.5-5.tar.gz
R CMD INSTALL ${P}stringr_1.0.0.tar.gz
R CMD INSTALL ${P}rhdfs_1.0.8.tar.gz
R CMD INSTALL ${P}rmr2_3.3.1.tar.gz
R CMD javareconf
R CMD BATCH ${P}install_check.R 

4. 把會用到的檔案都先抓下來
[root@hdatanode19 R]# ls -la *.tar.gz
-rw-r--r--. 1 hadoop hadoop    8734 Sep 10 21:10 bitops_1.0-6.tar.gz
-rw-r--r--. 1 hadoop hadoop   63358 Sep 10 21:10 caTools_1.17.1.tar.gz
-rw-r--r--. 1 root   root     36464 Jun 25 00:01 chron_2.3-47.tar.gz
-rw-rw-r--. 1 hadoop hadoop  949746 Oct  2  2014 data.table_1.9.4.tar.gz
-rw-r--r--. 1 hadoop hadoop   97985 Sep 10 21:10 digest_0.6.8.tar.gz
-rw-r--r--. 1 hadoop hadoop    2794 Sep 10 21:10 functional_0.6.tar.gz
-rw-r--r--. 1 hadoop hadoop  200504 Sep 10 21:10 magrittr_1.5.tar.gz
-rw-r--r--. 1 hadoop hadoop  392337 Sep 10 21:10 plyr_1.8.3.tar.gz
-rw-r--r--. 1 hadoop hadoop 2297548 Sep 10 21:10 Rcpp_0.12.0.tar.gz
-rw-r--r--. 1 hadoop hadoop   34693 Sep 10 21:10 reshape2_1.4.1.tar.gz
-rw-rw-r--. 1 hadoop hadoop   25105 Sep  7 22:48 rhdfs_1.0.8.tar.gz
-rw-r--r--. 1 hadoop hadoop  711181 Sep 10 21:10 rJava_0.9-7.tar.gz
-rw-r--r--. 1 hadoop hadoop 1148375 Sep 10 21:10 RJSONIO_1.3-0.tar.gz
-rw-rw-r--. 1 hadoop hadoop   63137 Sep  7 22:49 rmr2_3.3.1.tar.gz
-rw-rw-r--. 1 hadoop hadoop   29205 Nov  7  2014 sqldf_0.4-10.tar.gz
-rw-r--r--. 1 hadoop hadoop 3639183 Sep 10 21:10 stringi_0.5-5.tar.gz
-rw-r--r--. 1 hadoop hadoop   34880 Sep 10 21:10 stringr_1.0.0.tar.gz

5.命令列批次執行, Rout 附檔名為執行後的結果
[root@hdatanode19 R]#./install_lib.sh
[root@hdatanode19 R]# cat install_pack.Rout
[root@hdatanode19 R]# cat install_check.Rout



2015/10/03

Linux Bash Shell for and loop (迴圈)


Linux Shell 上常用的 for in 迴圈結構,可以幫忙很多工作。

----
for in 迴圈及結構
----
# 帶入變數內容的迴圈,自訂字串
[mtchang@c7 linux_shell]$ vim for.sh
#!/bin/bash
for VAR in file1 file2 file3
do
echo $VAR
done

# 設定可以執行權
[mtchang@c7 linux_shell]$ chmod +x for.sh 

# 執行
[mtchang@c7 linux_shell]$ ./for.sh 
file1
file2
file3

----
for in 迴圈及結構,搭配程式執行結果
----
# 將某個檔案或是程式執行的結果,帶入 for 迴圈內。
[mtchang@c7 linux_shell]$ head /etc/passwd | cut -f 1 -d:
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator

$ 使用 $() 將程式結果變成變數內容
[mtchang@c7 linux_shell]$ cat for_fileread.sh 
#!/bin/bash
for VAR in $(head /etc/passwd | cut -f 1 -d:)
do
echo $VAR
done

# 執行
[mtchang@c7 linux_shell]$ ./for_fileread.sh 
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator

----
for in 進階的新功能
----
# 程式
[mtchang@c7 linux_shell]$ cat for_adv.sh 
#!/bin/bash
for i in {1..5}
do
   echo "for loop 產生 1-5 目前內容為 $i "
done

echo 'Bash V4.0+ 功能 {START..END..INCREMENT} '
echo "Bash 版本 ${BASH_VERSION}"
for i in {1..12..2}
do
   echo "for loop 產生 1-12 目前內容為 $i 間隔為 2"
done

[mtchang@c7 linux_shell]$ chmod +x for_adv.sh 

# 執行
[mtchang@c7 linux_shell]$ ./for_adv.sh 
for loop 產生 1-5 目前內容為 1 
for loop 產生 1-5 目前內容為 2 
for loop 產生 1-5 目前內容為 3 
for loop 產生 1-5 目前內容為 4 
for loop 產生 1-5 目前內容為 5 
Bash V4.0+ 功能 {START..END..INCREMENT} 
Bash 版本 4.2.46(1)-release
for loop 產生 1-12 目前內容為 1 間隔為 2
for loop 產生 1-12 目前內容為 3 間隔為 2
for loop 產生 1-12 目前內容為 5 間隔為 2
for loop 產生 1-12 目前內容為 7 間隔為 2
for loop 產生 1-12 目前內容為 9 間隔為 2
for loop 產生 1-12 目前內容為 11 間隔為 2


我覺的這個 for in 就可以解決大部份的問題了,其他詳細的可以看這一邊 http://www.cyberciti.biz/faq/bash-for-loop/