twitter 发布的 scalding 是 concurrent 的 cascade 的 scala API,cascade 是在 hadoop API 上的一个 thin layer,目的是提供一些数据处理的基本流程,比如 PIG 里面常见的 group、co-group 等。有了这些基本的东西之后我们就可以在 cascade 的 API 上写一些更加 high level 的数据处理程序。但是说到必须写 java 程序可能就觉得比较麻烦。比起 pig 可能的确麻烦不少,尽管 pig 的很多功能依然要靠外挂的 UDF(还得写 java)。那 scalding 跑来说俺是 scala(比起 java 写起来更简洁),同时不仅仅数据处理的流程可以用 scala 描述,连处理的实现(相当于 PIG UDF 的那些东西)它也能胜任了。这听起来还是挺 inspiring 的事情,于是就跑来试了试。
单机版
如果我们想实现一个 word count 功能,记得写 map/reduce 需要提供 mapper 将字符串拆分成为 token,然后 reducer 将同个词出现次数相加。出去繁杂的声明 import 和写 mapper/reducer 类少说也有 10+ 行代码。使用 PIG 稍微简单一些,首先用 TextLoader 将文本载入,然后通过 UDF 将 chararray 拆分成 bag 并 flatten,然后 group 和 count 即可。大概程序如下,尚未验证
A = load '$input' as line : chararray using TextLoader () ;
B = foreach A generate flatten (STRSPLIT (line, '\s+', 100)) as word ;
C = group B by word ;
D = foreach C generate group as word, COUNT (B) as frequency ;
store D into '$output' ;
这里还好有 builtin 的 UDF(STRSPLIT 和 COUNT),如果碰上了复杂的我们就只好另外写个 Java 程序了。那使用 scalding 如何写呢?
import com.twitter.scalding._
class WordCountJob(args : Args) extends Job(args) {
TextLine(args("input"))
.flatMap('line -> 'word) { line : String => line.split("""\s+""") }
.groupBy('word) { _.size }
.write(Tsv(args("output")))
}
看上去紧凑很多,而且其中还包含了 UDF 部分 STRSPLIT 的实现。这就是 scala/scalding 的魅力。这个类似的可以参看 scalding 的代码中的 tutorial/Tutorial4.scala 的实现。为了执行它,只需要使用给出的 ruby 脚本,并指定 input/output 参数即可。
$ scripts/scald.rb --local tutorial/Tutorial4.scala \
--input tutorial/data/hello.txt --output tutorial/data/output4.tsv
cluster 版
以上任务是否可以提交到某个配置好的 grid 上运行呢?实际上也很简单,这个脚本干的事情就是通过 scala-assembly 这个 jar 提交任务,因此它会编译 scala 变成 .class 然后进行打包变成 jar,之后利用 hadoop jar 执行 job,我们只需要设定远程 gateway 的主机以及合适的认证信息就 OK 了,成功提交 job!
问题
一个将 scala/scalding 应用到 production 的主要问题是每个公司可能都有自己的一些格式,那么如何解决输入输出就是 scalding 的核心问题了。前面的程序我们看见使用了一个 TextInput 这跟 Pig 的 TextLoader 作用类似,而 Tsv 与 PigStorage 类似,因此需要搞定两种思路是或者写自己的对应类,或者是利用现有 PIG 的这些实现做成一个 wrapper,然后通过 reflection 配置使用哪个存储。
emacs 的 scala-mode
可以先去 co 这个
http://lampsvn.epfl.ch/svn-repos/scala/scala-tool-support/trunk/src/emacs/
之后 make 让其 byte compile,根据 README 搞定即可。
——————
And Abraham reproved Abimelech because of a well of water, which Abimelech’s servants had violently taken away.