Hadoop 的 Native 语言是 Java,它也提供其他语言(如 C、Python)的接口。在 Hadoop 下面其他语言是怎么工作的呢?原理是使用 HadoopStreaming 的标准输入 STDIN 和标准输出 STDOUT 来帮我们在 Map 和 Reduce 间传递数据。
Python map/reduce
编写 map.py
#!/usr/bin/env pythonimport sysdef read_inputs(file): for line in file: line = line.strip() yield line.split()def main(): file = sys.stdin lines = read_inputs(file) for words in lines: for word in words: print("{}\t{}".format(word, 1))if __name__ == "__main__": main()
测试
echo "Hello world Bye world" | ./map.py Hello 1world 1Bye 1world 1
编写 reduce.py
#!/usr/bin/env pythonimport sysdef read_map_outputs(file): for line in file: yield line.strip().split("\t", 1)def main(): current_word = None word_count = 0 lines = read_map_outputs(sys.stdin) for word, count in lines: try: count = int(count) except ValueError: continue if current_word == word: word_count += count else: if current_word: print("{}\t{}".format(current_word, word_count)) current_word = word word_count = count if current_word: print("{}\t{}".format(current_word, word_count))if __name__ == "__main__": main()
测试
echo "Hello World Bye World Hello" | ./map.py | sort | ./reduce.pyBye 1Hello 2World 2
上面都是使用 Python 自己的特性去进行统计,下面展示使用 Hadoop 的流程来执行
使用 MapReduce 执行 Python 脚本
查找 hadoop-stream 库的位置
find ./ -name "hadoop-streaming*.jar" ./local/hadoop/share/hadoop/tools/sources/hadoop-streaming-2.7.3-test-sources.jar./local/hadoop/share/hadoop/tools/sources/hadoop-streaming-2.7.3-sources.jar./local/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar
在 HDFS 上建立读入文件夹 input
hadoop -fs mkdir input
将待处理文件放入 HDFS
hadoop -fs put allfiles input
运行命令处理
hadoop jar ~/local/hadoop/share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar -input input -output output -mapper ./map.py -reducer ./reduce.py
处理后的文件
Bye 1Goodbye 1Hadoop 2Hello 2World 2
Python 代码中 map.py 的 print 会将行输入到 Hadoop 中,而 reduce.py 中的 print 会将 hadoop 流中的数据输出到 HDFS 中。