Python+Hadoop Streaming实现MapReduce(word count)

1. hadoop本身是用java写的,所以用java写mapreduce是比较合适的,然而hadoop提供了Streaming的方式,让很多语言可以来写mapreduce,下面就介绍如何用python写一个mapreduce程序,我们就从最简单的word count写起吧

2. word count是比较简单的,所以我们直接上代码,

3. map.py

#!/usr/bin/env python
# vim: set fileencoding=utf-8
import sys

def read_from_input(file):
    for line in file:
        yield line.split(' ')


def main(separator = ' '):
    data = read_from_input(sys.stdin)
    for words in data:
        for word in words:
            # write to the reduce
            print '%s%s%d' % (word, '\t', 1)
if __name__ == '__main__':
    main()

这个还是比较简单的,输入是从标准输入得到的,最后输出到reduce端是<word, 1>的形式,相当于用java写的那个context.write(key, value)

4. red.py

#!/usr/bin/env python
# vim: set fileencoding=utf-8
import sys
from itertools import groupby
from operator import itemgetter


def read_from_mapper(file, separator):
    for line in file:
        yield line.strip().split(separator, 2)

def main(separator = '\t'):
    data = read_from_mapper(sys.stdin, separator)
    for current_word, group in groupby(data, itemgetter(0)):
        try:
            total_count = sum(int(count) for current_word, count in group)
            print "%s%s%d" % (current_word, separator, total_count)
        except ValueError:
            pass

if __name__ == '__main__':
    main()

reduce的代码还是稍微有点复杂的,主要他不像用java写那么简便,会直接给你生成<word, list>这样的形式,所以我们就必须自己进行group,这里就用到了python的几个module:itertools和operator,既然他不给我们<word, list>的形式,那么我们就取构造这样的形式,首先输入是从map端过来的,是<word'\t'1>这样的形式,我们用yield将他们组装成generator, 然后 for current_word, group in groupby(data, itemgetter(0))是在data中进行group。key呢就是data里面项的第一个item,其实就是我们的word,最后用了一个简单的列表推导式进行统计每个word的个数,最后输出。

5. 我们需要用shell来运行他

#!/bin/bash


hadoop jar ../hadoop-streaming-2.0.0-mr1-cdh4.7.0.jar \
        -input /user/xxx/output/qianjc/python/input \
        -output /user/xxx/output/qianjc/python/output \
        -file map.py \
        -file red.py \
        -mapper "python map.py" \
        -reducer "python red.py" \
        -jobconf mapred.reduce.tasks=1 \
        -jobconf mapred.job.name="qianjc_test"

指定hadoop-streaming的jar包位置,几个参数的解释如下:

-input hdfs的输入位置

-output 结果写入hdfs的位置

-file 加载辞典,其实就是在运行的时候会将这些file拷贝到每个tasktracker的机器上

-mapper map的代码

-reducer reduce的代码

-jobconf mapred.reduce.tasks 设置reduce的个数

-jobconf mapred.job.name 设置job的名字

6. 本文主要讲了如何用python写简单mapreduce, 学会了这个处理一些简单的问题就比较迅速了,毕竟写脚本是比较快的

    其实我们可以不直接在集群中运行,我们可以先看看这2个python写得对不对,我们可以这么测试:

    cat xxxx.txt | ./map.py | sort | ./reduce.py,然后看输出对不对

7. 如果想了解更多hadoop streaming编程可以访问如下链接:

http://dongxicheng.org/mapreduce/hadoop-streaming-programming/

http://dongxicheng.org/mapreduce/hadoop-streaming-advanced-programming/

http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/

http://cs.smith.edu/dftwiki/index.php/Hadoop_Tutorial_2_--_Running_WordCount_in_Python

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值