之前一直在百度用内部改过的 hadoop 版本, streaming 接口下, 一直将 map command 写成 “sh mapper.sh | sort | sh combiner.sh” 来做人肉 combiner, 相安无事. 到人人后, 发现这个做法有问题, 今天测试了下, 果然很奇怪, 求 hadoop 大拿解答.
当前实验的版本是 hadoop 社区 0.21.0
实验 1. 跟经验不符的情况
mapper.sh
awk '{print $$}'
reducer.sh
wc -l
map command
sh mapper.sh | sort | sh reducer.sh
这时候, 单个 map 并不只输出一行信息, 而是一行输入会导致一行输出
实验 2. 符合预期, 但很别扭的写法
修改 mapper.sh 如下
awk '{print $$}' | sort | wc -l
修改 map command 如下
sh mapper.sh
这时候, 单个 map task 输出就只有一行了
实验 3. 不得已再封一层的方法
基于实验 1 新增一个脚本 xp.sh 如下
sh mapper.sh | sort | sh reducer.sh
并修改 map command 如下
sh xp.sh
这时候的效果和实验 2 结果一致
结论
至少在 Hadoop Streaming 0.21.0 这个版本里, 其执行方式并不是 cat input_data | map_command
这样, 其中 map_command 必须是一个单指令时才符合这个假设