关于maperduce,可以参考:http://en.wikipedia.org/wiki/MapReduce
这里假设你具备一定的hadoop编程经验。
Mapper接受原始输入,比如网站日志,分析并输出中间结果。经历排序,分组成为Reducer的输入,经过统计汇总,输出结果。当然这个过程可以是多个。
其中Mapper比较简单,但是需要对输入具有深入的理解,不光是格式还包括意义。其中有如下注意:
- 一条输入尽量不要拓展为多条输出,因为这会增加网络传输
- 对于partition的key要仔细选择,这会决定有多少reducer,确保这个的结果尽量均匀分布
reducer其实有现实的模板,这个是我要重点介绍的。下面的例子都是基于Perl语言。
对于简单的输入,模板如下:
# read configuration # initiate global vairables # initiate key level counter # initiate group level counter # initiate final counter ### reset all key level counter sub onBeginKey() {} ### aggregate count sub onSameKey {} ### print out the counter sub onEndKey() {} ### main loop while (<STDIN>) { chomp($_); # step 1:filter input # step 2: split input # step 3: get group and key # main logic if ($cur_key) { if ( $key ne $cur_key ) { &onEndKey(); &onBeginKey(); } &onSameKey(); } else { &onBeginKey(); &onSameKey(); } } if ($cur_key) { &onEndKey(); }
对于复杂的输入,模板如下:
# read configuration # initiate global vairables # initiate key level counter # initiate group level counter # initiate final counter ### reset all group level counter sub onBeginGroup() {} ### reset all key level counter sub onBeginKey() {} ### add count at key level sub onSameKey {} ### aggregate count from key level to group level sub onEndKey() {} ### aggregate count from group level to final result sub onEndGroup() {} ### main loop while (<STDIN>) { chomp($_); # step 1:filter input # step 2: split input # step 3: get group and key # main logic if ($cur_group) { if ( $group ne $cur_group ) { &onEndKey(); &onEndGroup(); &onBeginGroup(); &onBeginKey(); } else { if ( $key ne $cur_key ) { &onEndKey(); &onBeginKey(); } #else just the same key } &onSameKey(); } else { &onBeginGroup(); &onBeginKey(); &onSameKey(); } } if ($cur_key) { &onEndKey(); &onEndGroup(); } ### print out the final counter两个版本的区别在于,多了一级的group,但是原理一样。当然理论上还可以再嵌套更多的级别。
最后推荐一下市面上的hadoop编程书籍:
- Hadoop: The Definitive Guide
- Hadoop in Action
- Pro Hadoop