hadoop中使用Python语言实现wordcount功能

wordcount案例

run.sh

HADOOP_CMD="/usr/local/src/hadoop-2.6.5/bin/hadoop"
STREAM_JAR_PATH="/usr/local/src/hadoop-2.6.5/share/hadoop/tools/lib/hadoop-streaming-2.6.5.jar"

INPUT_FILE_PATH_1="/1.txt"
OUTPUT_PATH="/output"

$HADOOP_CMD fs -rmr -skipTrash $OUTPUT_PATH

# Step 1.
$HADOOP_CMD jar $STREAM_JAR_PATH \
    -input $INPUT_FILE_PATH_1 \
    -output $OUTPUT_PATH \
    -mapper "python map_new.py" \
    -reducer "python red_new.py" \
    -file ./map_new.py \
    -file ./red_new.py

run.sh是一个shell脚本。由于我们用的是Python开发的,因此需要使用hadoop-streaming方式提交作业。
其中,HADOOP_CMD="/usr/local/src/hadoop-1.2.1/bin/hadoop"指的是hadoop命令的路径。
STREAM_JAR_PATH="/usr/local/src/module/hadoop-2.6.5/share/hadoop/tools/lib/hadoop-streaming-2.6.5.jar"指的是hadoop-Streaming的jar包。
INPUT_FILE_PATH_1="./test.data"指的是统计单词个数的源文件。这里是本地文件路径。
OUTPUT_PATH="/output"指的是结果输出路径,这里指的是hdfs路径。

$HADOOP_CMD fs -rmr -skipTrash $OUTPUT_PATH
这里指的是清楚上一次任务的输出结果,避免出现没必要的错误。

map.py

#!/usr/local/bin/python

import sys
import time
import re

for line in sys.stdin:
    ss = line.strip().split(' ')
    for s in ss:
        #time.sleep(100000)
        if s.strip() != "":
            l = re.findall(r"[^a-zA_Z]*([a-zA-Z]+)[^a-zA-Z]*", s)
            if len(l) > 0:
                s = l[0]
                print "%s\t%s" % (s, 1)

需要注意的是,map和reduce都是从标准输入读数据。
map.py 处理文中单词的输出格式如下:
在这里插入图片描述

red.py

map阶段的输出结果,作为red阶段的标准输入。

#!/usr/local/bin/python

import sys

current_word = None
count_pool = []
sum = 0

for line in sys.stdin:
    word, val = line.strip().split('\t')

    if current_word == None:
        current_word = word

    if current_word != word:
        for count in count_pool:
            sum += count
        print "%s\t%s" % (current_word, sum)
        current_word = word
        count_pool = []
        sum = 0

    count_pool.append(int(val))

for count in count_pool:
    sum += count
print "%s\t%s" % (current_word, str(sum))

red.py数据处理的结果

在这里插入图片描述

mapreduce实现wordcount

现在,我们使用mapreduce实现单词统计,并查看结果。
执行bash run.sh
在这里插入图片描述

查询输出结果 在/output/part-00000中
在这里插入图片描述
上面可以看到,单个出现次数统计完成。 之后的博文中,我将会详细介绍hadoop-Streaming的其他参数,尤其是jobconf。谢谢阅读。

streaming

1)Streaming简介

Hadoop的MapReduce和HDFS均采用Java进行实现,默认提供Java编程接口,用户通过这些编程接口,可以定义map、reduce函数等等。
  但是如果希望使用其他语言编写map、reduce函数怎么办呢?
  Hadoop提供了一个框架Streaming,Streaming的原理是用Java实现一个包装用户程序的MapReduce程序,该程序负责调用hadoop提供的Java编程接口。

2)运行命令

/…/bin/hadoop streaming

-input /…/input

-output /…/output

-mapper “mapper.py

-reducer “reducer.py

-file mapper.py

-file reducer.py

-D mapred.job.name =“wordcount”

-D mapred.reduce.tasks = “1”

3)Streaming常用命令

(1)-input
指定作业输入,path可以是文件或者目录,可以使用*通配符,-input选项可以使用多次指定多个文件或目录作为输入。
(2)-output
指定作业输出目录,path必须不存在,而且执行作业的用户必须有创建该目录的权限,-output只能使用一次。
(3)-mapper:
指定mapper可执行程序或Java类,必须指定且唯一。
(4)-reducer:
指定reducer可执行程序或Java类,必须指定且唯一。
(5)-file, -cacheFile, -cacheArchive:
分别用于向计算节点分发本地文件、HDFS文件和HDFS压缩文件,具体使用方法参考文件分发与打包。
(6)numReduceTasks:
指定reducer的个数,如果设置-numReduceTasks 0或者-reducer NONE则没有reducer程序,mapper的输出直接作为整个作业的输出。
(7)-jobconf | -D NAME=VALUE:
指定作业参数,NAME是参数名,VALUE是参数值,可以指定的参数参考hadoop-default.xml。
   -jobconf mapred.job.name='My Job Name’设置作业名
   -jobconf mapred.job.priority=VERY_HIGH | HIGH | NORMAL | LOW | VERY_LOW设置作业优先级
   -jobconf mapred.job.map.capacity=M设置同时最多运行M个map任务
   -jobconf mapred.job.reduce.capacity=N设置同时最多运行N个reduce任务
   -jobconf mapred.map.tasks 设置map任务个数
   -jobconf mapred.reduce.tasks 设置reduce任务个数  
   -jobconf mapred.compress.map.output 设置map的输出是否压缩
   -jobconf mapred.map.output.compression.codec 设置map的输出压缩方式  
   -jobconf mapred.output.compress 设置reduce的输出是否压缩
   -jobconf mapred.output.compression.codec 设置reduce的输出压缩方式
   -jobconf stream.map.output.field.separator 设置map输出分隔符
    例子:-D stream.map.output.field.separator=: \ 以冒号进行分隔
     -D stream.num.map.output.key.fields=2 \ 指定在第二个冒号处进行分隔,也就是第二个冒号之前的作为key,之后的作为value
(8)-combiner:
指定combiner Java类,对应的Java类文件打包成jar文件后用-file分发。
(9)-partitioner:
指定partitioner Java类,Streaming提供了一些实用的partitioner实现,参考KeyBasedFiledPartitoner和IntHashPartitioner。
(10)-inputformat, -outputformat:
指定inputformat和outputformat Java类,用于读取输入数据和写入输出数据,分别要实现InputFormat和OutputFormat接口。如果不指定,默认使用TextInputFormat和TextOutputFormat。
(11)cmdenv NAME=VALUE:
给mapper和reducer程序传递额外的环境变量,NAME是变量名,VALUE是变量值。
(12)-mapdebug, -reducedebug:
分别指定mapper和reducer程序失败时运行的debug程序。
(13)-verbose:
指定输出详细信息,例如分发哪些文件,实际作业配置参数值等,可以用于调试。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值