Scalding是对Cascading框架的Scala封装,或者更确切地说是一种函数式封装。看到Cascading的时候你可能会觉得这么麻烦的东西有必要学吗?但是再看看Scalding就会发现,这好像跟写一般的Scala代码也没什么区别……小小的封装带来巨大的改变。MapReduce/Spark这一遍玩下来最大的体会就是——用命令式语言表达函数式的东西真是太费劲了(map/reduce是函数式语言的基本操作)!
写惯了Spark再来看java的MapReduce的感觉就是再也回不去了。MapReduce是初恋又如何,函数式语言天生表达map、reduce就是比java这种命令式的要强得多得多得多。在用Spark用了一年之后基本上还是能总结出相对于MapReduce来说Spark的缺点:在单轮任务(典型的的ETL)上基本上没有什么优势,对于集群的利用来说与MapReduce还是有差距,具体表现在资源使用模式固定,无法像MR一样伸缩式的起大量map,这在资源空闲时是巨大的浪费。
1. 为什么是Scalding
网上找到一篇文章列举了列举了Pig, Scalding, Scoobi, Hive, Spark, Scrunch, Cascalog相关介绍的文章列表1。对于我自己而言:
1. 我需要一个简单框架来写MapReduce,并且能够很好利用现有库,hive、pig、spark出局;
2. 需要函数式使用API,Scala封装是很好的选择,还剩下Scoobi, Scalding, Scrunch
3. 易用,满足我司常见的三个场景的需求(列举在下文)。Scoobi, Scrunch对Thrift Parquet支持不好,出局。
从实际使用上来看,用Scala封装得比较好的MapReduce一样可以和写Spark一样简单。赞!
2. 实际用例
Scalding有两种API:Type-safe API2和 Fields Based API3。Fields Based API有点SQL的意思,喜欢的话还是不错的,专门有一本书叫《programming mapreduce with scalding4》,里面全部都是用Fields Based API讲的。全书总共也就100来页,很快就可以学完。
个人是先接触的Spark,已经被Typesafe洗脑,还是更倾向于接受Type-safe API。下面所有的例子都 是基于Type-safe API的。下面是针对一种是针对我司常见的三种应用场景分别介绍,
直接上的例子,具体地有兴趣可以自行查询API,一些相关的参考资料已经标在脚注中了。
2.1 读写纯文本文件
import com.twitter.scalding._
class TextFileExample(args: Args) extends Job(args) {
TypedPipe.from(TextLine(args("input")))
.flatMap(line => line.split("\\s"))
.map { word => (word, 1L) }
.sumByKey // reduce num not set
.write(TypedTsv[(String, Long)](args("output")))
}