Map Reduce流程
map.py脚本如下:
"""
wordcount单词统计
map阶段
"""
import sys
def map():
for line in sys.stdin: # 从标准输入里面读取的,是一个字符串格式
words = line.split("\t")
for word in words:
print("\t".join([word.strip(), "1"]))
if __name__ == "__main__":
map()
reduce.py脚本如下:
'''
wordcount单词统计
reduce阶段
'''
import sys
from operator import itemgetter
def reduce():
word_count_dict = {} # 定义一个空字典
for line in sys.stdin: # for循环是为了计算每个单词最终出现的次数
kv = line.split("\t") # 用split分割
word = kv[0].strip() # 为防止分割后有空格或者是换行符而采用strip,把字符串左右两边的空格去掉
count = int(kv[1].strip()) # 使用int,把获取到的字符串类型转化为整型
word_count_dict[word] = word_count_dict.get(word, 0) + count
# 用该字典get方法,获取字典中存储的单词,若单词不存在,则返回值为0,再加上从标准输入获取到的值count
sorted_word_count = sorted(word_count_dict.items(), key=itemgetter(0))
for word, count in sorted_word_count:
print("\t".join([word, str(count)]))
if __name__ == "__main__":
reduce()
写好脚本之后在本地测试,使用命令:
echo "YTT hhh Hello YTT World Bye World hhh YTT" | python map.py | sort | python reduce.py
注意:
本地服务器测试没问题之后,要先把数据上传到hdfs,脚本不用传,-file 参数填的是本地的路径
hdfs dfs -copyFromLocal MR/test.dat hdfs:///JJW/
#-copyFromLocal只能拷贝本地文件到HDFS中限制严格。
hdfs dfs -put MR/test.dat hdfs:///JJW/
#可以把本地或者HDFS上的文件拷贝到HDFS中。
如果有报错信息,去对应的网址查看日志
然后发现居然是python版本的问题...于是就在执行的语句里面指定用哪个版本的python
hadoop jar /xxx/hadoop-streaming.jar
-mapper '/xxx/python map.py'
-file /xxx/map.py
-reducer '/xxx/python reduce.py'
-file /xxx/reduce.py
-input ${pwd}/xxx/input
-output ${pwd}/xxx/output
成功后可以看到:
参考资料:
MapReduce 原理与 Python 实践
python版MR任务完整过程(附代码)
Python中的MapReduce以及在Hadoop环境下运行之词频统计
用python写MapReduce函数——以WordCount为例
python中MapReduce实战代码演示