輸入文件
Scalding既可以處理HDFS上的數據,也可以很方便地在本地運行處理一些test case便於debug,Source有好多種
1 TextLine(filename)
TextLine(args("input"))或者TextLine("~/data/input.txt")
對每行數據,產生包含'line和'offset兩個field的tuple
2 Csv和Tsv
本地文件和HDFS文件都可以用,讀時可以指定field名
Tsv(args("input"), ('userid, 'computerguid, 'event, 'json)).read
第一行如果有headers還可以自動處理field名
3 WritableSequenceFile
讀取HDFS上的Sequence壓縮文件,將每一行解析為(Long, String)
WritableSequenceFile(args("input"), ('serialNo, 'data))
4 IterableSource
由scala的Iterable變量創建pipe
IterableSource(List(4,8,15,16,23,42), 'foo)
創建名為'foo的field
5 NullSource
Scalding有一個隱蔽的優化,如果job中對一個pipe進行變換而最終沒有write到任何地方,這段中間代碼就不會被執行,如果job中一個write操作就直接拋異常了。
如果分布式計算程序只是為了產生side effect,而不需要將pipe變換的結果,比如說這種場景,僅僅從HDFS讀取一些計算結果,然后將進一步計算的數據發送到數據可視化平台,又或者你只是想打印pipe的前幾行Csv(input).limit(10).debug,這種優化就是一個坑了。
因此你需要Csv(input).limit(10).debug.write(NullSource)來確保side effect被執行
更多請參考Scalding-Sources, Field rules
reduce和foldLeft的區別
reduce函數必須是associative的,類似combiner,會先在map side做中間結果合並的工作。
foldLeft函數可以不是associative的,而且output的類型可以與input類型不同,結果合並只在reduce side發生。
scald.rb有坑請注意
這個不知道為啥在我這兒不能使,倒騰了幾次提示我可以scald.rb --clean看看
於是乎悲劇就發生了,這個操作刪除了maven下載的一系列包,對於本月已經流量超了24個G的妹子來說是沉重的打擊,龜速更新完之后其他job也跑不了了,悲憤
error: error while loading <root>, error in opening zip file
error: scala.tools.nsc.MissingRequirementError: object scala not found.
一開始看了Stackoverflow上面的討論
Scala SBT / Maven2 Error on OSX: “Error Opening Zip File” -> MissingRequirementError
然后沖過去把scalac -classpath 后面跟的jar包全都chmode a+rwx了一把,我了個。。。。。。。。。完全沒用!而且~/.sbt/boot/scala-2.9.3/這個目錄根本就沒有蒙誰呢。。。
然后看這個 Running your Scalding jobs in Eclipse
本地寫法:
Eclipse runtime configuration:
Main class: com.twitter.scalding.Tool Program Args: <Fully Qualified Path to Job Class> <Other CLI Args> Example: org.hokiesuns.scaldingtest.WordCountJob --local --input ./input/input.txt --output ./output.txt VM Args: -Xmx3072m
Hadoop寫法:
hadoop jar scaldingsample-0.0.1-SNAPSHOT.jar org.hokiesuns.scaldingtest.WordCountJob --hdfs --input <some path> --output <some path>
又參考這個Using IntelliJ with Twitter’s Scalding
I am able to do a local or local-hdfs run from the sbt-console:
1
2
|
> run-main com.twitter.scalding.Tool com.wordnik.WordCountJob --local --input doc.txt --output /tmp/notice.tsv
> run-main com.twitter.scalding.Tool com.wordnik.WordCountJob --hdfs --input doc.txt --output /tmp/NOTICE
_
JOB
|
Note that the syntax is slightly different from the the Ruby scald.rb script — local hdfs mode is indicated with ‘–hdfs’. You’ll probably often want to run sbt with more memory than this.
想着是不是可以像唐大神一樣完全拋棄scald.rb自己寫個bash腳本運行scalding job啊。。。
各種方法未果決定重新編譯scalding,從19:05開始借流量,到22:28Google看到一個link命令scripts/scald.rb --local XXX.scala前加了sudo,試試看之后簡直不敢相信,神坑被fix了。。。
scalac -classpath /Users/wei.li/.sbt/boot/scala-2.9.3/lib/scala-library.jar:/Users/wei.li/codes/scalding/scalding-core/target/scala-2.9.3/scalding-core-assembly-0.9.0rc4.jar:/tmp/maven/hadoop-core-1.1.2.jar:/tmp/maven/commons-codec-1.8.jar:/tmp/maven/commons-configuration-1.9.jar:/tmp/maven/jackson-asl-0.9.5.jar:/tmp/maven/jackson-mapper-asl-1.9.13.jar:/tmp/maven/commons-lang-2.6.jar:/tmp/maven/slf4j-log4j12-1.6.6.jar:/tmp/maven/log4j-1.2.15.jar:/tmp/maven/commons-httpclient-3.1.jar:/tmp/maven/commons-cli-1.2.jar:/tmp/maven/commons-logging-1.1.1.jar:/tmp/maven/zookeeper-3.3.4.jar -d /tmp/script-build tutorial/Tutorial1.scala
這些jar包的路徑跟以前截然不同!開心得要轉圈圈~
不過最后我還是拋棄了scald.rb,在本地跑直接用sbt+Eclipse,在Hadoop上跑直接用sbt+shell script
Tuple里到底發生了什么
下面這個PPT很詳細地解釋了不同操作對Field的影響(此處應有翻牆)
Scalding大法好,退MR保平安
Scalding將HDFS的輸入抽象成一個分布式集合(和數據庫中Tuple和Field的概念是一致的),與MR不同,他可以很直觀地進行兩個表Join的操作。
可以運行的教程
https://github.com/twitter/scalding/tree/master/tutorial
https://github.com/sharethrough/scalding-emr-tutorial
一個更復雜的例子是
Generating Recommendations with MapReduce and Scalding
Movie recommendations and more via MapReduce and Scalding
你會發現Scalding代碼真的長得很像Spark
Movie Recommendations and More With Spark
再來對比一下
這個PPT里提到了Scalding可以跑在Spark上,不過除了Summingbird(scalding for hadoop, storm for realtime)里提了下,鮮有這方面實踐的資料
SBT讓程序跑起來
REPL交互式Shell支持
今天發現其實有個很簡單的方式,直接運行
~/codes/scalding/scripts/scald-repl.sh
就可以成功地導入並找到Scalding包啦
scalding> import com.twitter.scalding._
import com.twitter.scalding._
如果遇到一些找不到scala之類的問題,sudo一下試試看
可以在~/.bash_profile中加入
alias scalding="sudo ~/codes/scalding/scripts/scald-repl.sh"
好用得飛起來
如果你想加入第三方包(比如說json解析包)
可以vi scald.rb
參考MVNrepository的寫法
libraryDependencies += "org.json4s" % "json4s-jackson_2.10" % "3.2.7"
在第33行"depends" => [ "org.apache.hadoop/hadoop-core/1.1.2", 后面照着它的格式加入你需要的包依賴
然后就可以在REPL里面導入這個包啦
scripts$ sudo scald-repl.sh
可以試着玩玩兒,但還是有坑,IDE里的SpreadSheet其實更方便
添加IDE支持
在項目的project/plugins.sbt中加入
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0")
或者
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0")
在項目的build.sbt中添加Dependency,按照MVNrepository的寫法加入依賴
libraryDependencies ++= Seq(
"com.twitter" % "scalding-core_2.10" % "0.9.0rc12" exclude("com.esotericsoftware.minlog", "minlog"),
"org.apache.hadoop" % "hadoop-core" % "1.2.1" % "provided",
"org.json4s" %% "json4s-jackson" % "3.2.8"
)
sbt update
sbt eclipse
或者
sbt gen-idea
然后重新導入Eclipse就可以啦,我選擇Eclipse主要是因為它有集成Scala 2.10支持的版本下載,比配IntelliJ省事兒些,而且可以設置Eclipse在每次保存的時候自動format代碼,拯救了我的強迫症,知道在IntelliJ里怎么實現該功能的親可以教教我哦~
Plugin for sbt to create Eclipse project definitions
Using IntelliJ with Twitter’s Scalding