关于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