专栏首页应兆康的专栏用Python来写MapReduce之Wordcount

用Python来写MapReduce之Wordcount

前言

虽然Hadoop是用Java编写的一个框架, 但是并不意味着他只能使用Java语言来操作, 在Hadoop-0.14.1版本后, Hadoop支持了Python和C++语言, 在Hadoop的文档中也表示可以使用Python进行开发, 通常来说都会考虑将源码打包成jar包再运行, 例子: PythonWordCount 这明显不方便. 在Hadoop的文档中提到了Hadoop Streaming, 我们可以使用流的方式来操作它. 它的语法是

hadoop jar hadoop-streaming-2.9.2.jar \
  -input myInputDirs \
  -output myOutputDir \
  -mapper /bin/cat \
  -reducer /usr/bin/wc

指定输入输出文件和mapper, reducer即可. 在Python中的sys包中存在, stdin和stdout,输入输出流, 我们可以利用这个方式来进行MapReduce的编写. 本文以WordCount进行举例

Coding

我们在工程目录下创建两个文件,分别是mapper.py和reducer.py, 之后使用命令chmod +x mapper.py来给他们赋予执行权限.

Mapper

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
-------------------------------
FileName: mapper
Author: ying
Date: 18-12-6
-------------------------------
Change Activity: 18-12-6
"""
import sys

__author__ = "YingJoy"

for line in sys.stdin:
    # 捕获输入流
    line = line.strip()
    words = line.split()

    for word in words:
        # 注意这里哦
        print("%s\t%s" % (word, 1))

Reducer

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
-------------------------------
FileName: reducer
Author: ying
Date: 18-12-6
-------------------------------
Change Activity: 18-12-6
"""
import sys

__author__ = "YingJoy"

word_dict = {}

for line in sys.stdin:

    line = line.strip()
    word, count = line.split('\t')

    try:
        count = int(count)
    except ValueError:
        continue

    if word in word_dict:
        word_dict[word] += 1
    else:
        word_dict.setdefault(word, 1)

for k, v in word_dict.items():
    print('%s\t%s' % (k, v))

测试代码

这里使用Linux的管道来进行测试, 将前一项的输出作为后一项的输入

echo "foo foo quux labs foo bar quux" | ./mapper.py

`
foo     1
foo     1
quux    1
labs    1
foo     1
bar     1
quux    1
`

echo "foo foo quux labs foo bar quux" | ./mapper.py | sort -k1,1 | ./reducer.py

`
bar     1
foo     3
labs    1
quux    2
`

在Hadoop上运行代码

准备

首先我们在http://www.gutenberg.org/这个网站上随便下基本电子书(选择Plain Text UTF-8) 然后使用命令将文本上传到HDFS中

# 创建文件夹, 否则出错
hdfs dfs -mkdir gutenberg 
hdfs dfs -put *.txt gutenberg
hdfs dfs -ls gutenberg 

这里说明一下, HDFS的相对目录, 是相对于当前用户的目录, 如我的用户是ying, 它默认的位置就是/user/ying 然后你就可以在HDFS看到刚刚上传的文件了

启动MapReduce任务

运行下面的命令

hadoop jar /opt/hadoop-2.9.2/share/hadoop/tools/lib/hadoop-streaming-2.9.2.jar -file ./mapper.py -mapper ./mapper.py -file ./reducer.py -reducer ./reducer.py -input /user/ying/gutenberg/* -output /user/ying/output

注意,这里使用的hadoop命令, 如果你使用hdfs命令会报错误: 找不到主类 运行之后你可以在本地: localhost:8088 看到你的任务, 如图

等待任务完成即可在输出目录下看到结果,注意这里的output目录运行之前不能存在,否则报错

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 12步轻松搞定Python装饰器

    Python里面的装饰器比较复杂,下面12步可以帮你你较好的理解Python中的装饰器 1. 函数 在python中,函数通过 def关键字、函数名和可选的参数...

    YingJoy_
  • 贝叶斯分类器及Python实现

    由于某些不可抗拒的原因,LaTeX公式无法正常显示. 点击这里查看PDF版本 Github: https://github.com/yingzk/MyML 博 ...

    YingJoy_
  • Python实现栈

    YingJoy_
  • word中图片太大压缩

    电子文档word中经常需要插入图片,然而过多的图片会使word占用空间大,导致word打开缓慢,编辑卡顿等现象。word过大还非常不利于文档的网络传输和拷贝使用...

    似水的流年
  • 并发与竞态 (自旋锁)

    由以上介绍大概了解,自旋锁就是内核为防止临界区被多个进程同时访问出错的一种机制。其作用是保证临界区在任一时刻有且仅有一个进程访问。

    开源519
  • PHP面向对象核心(二)——继承、多态、接口

    PHP面向对象核心(二) (原创内容,转载请注明来源,谢谢) 三、继承与多态 3.1 继承 1、继承是类级别的复用,关键词为extends;多态是方法级别的复用...

    用户1327360
  • 为什么有人说 Redis 的 set 命令是一个危险命令?

    原文链接:https://redislabs.com/

    业余草
  • wordpress手动升级版本方法

    之前都是直接在后台升级的,现在换了linux的服务器,但是后台直接升级的时候。 需要提供ftp链接,但是我一直不喜欢用ftp,都是直接用Xshell在操作,有...

    速企云
  • java学习笔记(基础篇)—关键字static和final

    a)所有类实例共享 b)使用静态变量 类名.变量名 c)静态变量是属于这个类,非静态变量是属于对象 d)代码加载到内存静态变量就已经存在了 e)sta...

    chlinlearn
  • WebDriver自动化项目设计模式快速入门-自动化测试系列笔记

    朵拉小序:Page Object,即”页面对象“,就是将单个页面作为一个对象来处理。 以面向对象的方式来处理页面和业务流程的好处在于,如果某个页面元素的属性有了...

    企鹅号小编

扫码关注云+社区

领取腾讯云代金券