原标题:使用Python语言写Hadoop MapReduce程序

Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。

在本教程中,我将描述如何使用Python语言为Hadoop编写一个简单的MapReduce程序。

目的

尽管Hadoop框架是用Java编写的,但是为Hadoop编写的程序不必非要Java写,还可以使用其他语言开发,比如Python或C++(Haoop在0.14.1版本提供C++ API)。然而,Hadoop的官方文档和在官网上最著名的Python的例子会让你觉得你必须使用Jython(译者注:用Java语言写的一个Python解释器,原生的Python解释器是用C语言写的。)将Python代码转换成一个Java的jar文件。很显然,这非常不方便甚至会出问题,如果你依赖的Python特性不被Jython提供。另一个Jython方式的问题是:编写与Haoop交互的Python程序存在着间接开销——你只要看一下这个例子$HADOOP_HOME/src/examples/python/WordCount.py,你就可以明白我的意思了。

也就是说,本教程的目的是:以Python风格,编写一个Hadoop MapReduce程序,即你应该熟悉的方式。

我们想要做什么

我们将用Python写一个简单的MapReduce程序(可以看下维基的MapReduce条目)但是不用Jython将我们的代码转换成Java的jar文件。

我们的程序会模仿单词计数,即读取文本文件并计算单词出现的次数。输入是文本文件,输出也是文本文件,其中每一行包含一个单词及它出现的次数,以Tab分隔。

注意:你也可以使用本教程描述的“技术”,而使用Python之外的编程语言比如Perl或Ruby。

前提条件

你应该有一个Hadoop的集群在运行,因为我们将用到。如果你还没有一个集群,我下面的教程可能会帮助你搭建一个。本教程是在Ubuntu系统下测试的,但应该也适用于其他Linux/Unix系统。

在Ubuntu上运行Hadoop(单节点集群)——如何搭建一个伪分布式,单节点Hadoop集群,后台存储是Hadoop分布式文件系统(HDFS)。

在Ubuntu上运行Hadoop(多节点集群)——如何搭建一个分布式,多节点的Hadoop集群,后台存储是Hadoop分布式文件系统(HDFS)。

MapReduce的Python代码

下面Python代码的一个“窍门”是我们将使用Hadoop流API(可以看下相关的维基条目)来帮助我们通过STDIN(标准输入)和STDOUT(标准输出)在Map和Reduce代码间传递数据。我们只是使用Python的sys.stdin读取输入数据和打印输出到sys.stdout。这就是我们需要做的,因为Hadoop流将处理好一切。

Map部分代码:mapper.py

将下面的代码保存在文件 /home/hduser/mapper.py 中。它将从STDIN读取数据,拆分为单词并输出一组映射单词和它们数量(中间值)的行到STDOUT。尽管这个Map脚本不会计算出单词出现次数的总和(中间值)。相反,它会立即输出( 1)元组的形式——即使某个特定的单词可能会在输入中出现多次。在我们的例子中,我们让后续的Reduce做最终的总和计数。当然,你可以按照你的想法在你自己的脚本中修改这段代码,但是,由于教学原因,我们在本教程中就先这样做。:-)

请确保该文件具有可执行权限(chmod +x /home/hduser/mapper.py ),否则你会遇到问题。

Reduce部分代码:reducer.py

将下面的代码保存在文件 /home/hduser/reducer.py 中。它将从STDIN读取mapper.py的结果(因此mapper.py的输出格式和reducer.py预期的输入格式必须匹配),然后统计每个单词出现的次数,最后将结果输出到STDOUT中。

请确保该文件具有可执行权限(chmod +x /home/hduser/reducer.py ),否则你会遇到问题。

代码测试(cat data | map | sort | reduce)

在MapReduce作业中使用它们之前,我建议先在本地测试你的mapper.py和reducer.py脚本。否则,你的作业可能成功完成了但没有作业结果数据或得到了不是你想要的结果。如果发生这种情况,很有可能是你(或我)搞砸了。

这里有一些想法,关于如何测试这个Map和Reduce脚本的功能。

在Hadoop上运行Python代码

下载示例输入数据

对于这个示例,我们将使用来自Gutenberg项目的三个文本:

下载每个文件为纯文本文件,以UTF-8编译并且将这些文件存储在一个临时目录中,如/tmp/gutenberg。

***说明:你将需要在你的Cloudera虚拟机中打开浏览器。选择适当的文件下载(UTF-8 版本),它将显示在你的浏览器中。点击鼠标右键按钮来保存该文件。给它一个合适的名称(如"Ulysses"),并注意它将保存在下载目录中。***

将本地示例数据拷贝到HDFS

在我们运行实际的MapReduce作业前,我们首先必须从我们本地文件系统中拷贝文件到Hadoop的HDFS内。

***说明:

我们假设你是在你的下载目录中。我们必须在HDFS中创建一个子目录,然后拷贝文件过来。最后,我们验证拷贝文件成功。

首先,我们在HDFS中创建子目录MyFirst:

[cloudera@quickstart Downloads]$ hadoop fs -mkdir MyFirst

然后,我们拷贝文件。注意,三个文件以.txt结尾:

[cloudera@quickstart Downloads]$ hadoop fs -copyFromLocal *.txt MyFirst

最后,我们验证拷贝成功:

[cloudera@quickstart Downloads]$ hadoop fs -ls MyFirst

Found 3 items

-rw-r--r-- 1 cloudera cloudera 1423803 2014-11-30 08:02 MyFirst/Leonardo.txt

-rw-r--r-- 1 cloudera cloudera 674570 2014-11-30 08:02 MyFirst/OutlineOfScience.txt

-rw-r--r-- 1 cloudera cloudera 1573150 2014-11-30 08:02 MyFirst/Ulysses.txt

运行MapReduce作业

***说明:

运行MapReduce作业,敲入如下命令:

[cloudera@quickstart ~]$ hadoop jar /usr/lib/hadoop-0.20-mapreduce/contrib/streaming/hadoop-streaming.jar -file mapper.py -mapper mapper.py

-file reducer.py -reducer reducer.py -input MyFirst/* -output MyFirst4-output

你会收到有关文件被弃用的警告,不用担心。重要的是:当你发出这条命令时,输出目录(在这个示例中是MyFirst-output)不存在。

验证这个程序工作正常。首先,输入命令:hadoop fs -ls MyFirst4-output

[cloudera@quickstart ~]$ hadoop fs -ls MyFirst4-output

Found 2 items

-rw-r--r-- 1 cloudera cloudera 0 2014-11-30 09:23 MyFirst4-output/_SUCCESS

-rw-r--r-- 1 cloudera cloudera 880829 2014-11-30 09:23 MyFirst4-output/part-00000

然后,查看输出文件:

[cloudera@quickstart ~]$ hadoop fs -cat MyFirst4-output/part-00000

将文件从HDFS中拷入到你本地文件系统中:

[cloudera@quickstart ~]$ hadoop fs -copyToLocal MyFirst4-output/part-00000

MyFirstOutputLocal.txt

现在,一切都准备好了,我们终于可以在Hadoop集群上运行我们的Python MapReduce作业了。如上所述,我们使用Hadoop流API通过STDIN和STDOUT在Map和Reduce间传递数据。

如果你想要在运行的时候修改Hadoop参数,如增加Reduce任务的数量,你可以使用-D选项:

hduser@ubuntu:/usr/local/hadoop$ bin/hadoop jar contrib/streaming/hadoop-*streaming*.jar -D mapred.reduce.tasks=16 ...

关于mapred.map.tasks说明:Hadoop does not honor mapred.map.tasks beyond considering it a hint。但是,Hadoop接受用户指定mapred.reduce.tasks并且不操作。你不能强制指定mapred.map.tasks,但可以指定mapred.reduce.tasks。

这个任务将读取HDFS目录/user/hduser/gutenberg中的所有文件,处理它们,并将结果存储在HDFS目录/user/hduser/gutenberg-output中。一般情况下,Hadoop对每个reducer产生一个输出文件;在我们的示例中,然而它将只创建单个文件因为输入的文件都很小。

在终端中前一个命令的输出示例︰

**译者说明:截图中的命令不完整,完整命令如下:

hduser@ubuntu:/usr/local/hadoop$ bin/hadoop jar contrib/streaming/hadoop-*streaming*.jar -mapper /home/hduser/mapper.py -reducer /home/hduser/reducer.py -input /user/hduser/gutenberg/* -output /user/hduser/gutenberg-output

在上面的输出中你可以看到,Hadoop也为统计和信息提供一个基本的web界面。Hadoop集群运行时,在浏览器中打开http://localhost:50030/ ,浏览下界面。这里有一张我们刚才运行任务的Hadoop Web界面的截图。

图1:Hadoop的JobTracker界面截图,详细显示了我们刚运行的MapReduce作业。

检查结果是否成功存储在了HDFS目录/user/hduser/gutenberg-output中:

然后,你可以使用dfs -cat命令查看文件的内容:

请注意,上面特定的输出中被双引号引用的单词没有被Hadoop插入。他们是我们的Python代码拆分单词的结果,在这种情况下它匹配了文件中引用的开头。进一步查看下part-00000这个文件。

改进Mapper和Reducer代码:使用Python的迭代器(iterator)和生成器(generator)

上面的Mapper和Reducer例子应该给你提供了一种思路,关于如何创建第一个MapReduce程序。重点是代码简洁和易于理解,特别是对于Python语言的初学者。在现实程序中,你可能想要通过Python的迭代器和生成器(一个更好的介绍PDF文档)优化你的代码。

一般来说,迭代器和生成器(生成迭代器的函数,举例Python中yield语句)有一个优点:序列中的元素在你确时需要它的时候才会生成。这会很有用,当你手头上计算资源昂贵或内存紧缺。

注意:下面的Map和Reduce脚本只有运行在Hadoop环境中才会正常工作,即在 MapReduce任务中作为Mapper和Reducer。这表示在本地运行的测试命令"cat DATA | ./mapper.py | sort -k1,1 | ./reducer.py"不会正常工作,因为一些功能是由Hadoop来完成的。

准确地说,我们计算了一个单词出现的次数,例如("foo", 4),只有恰巧相同的单词(foo)相继出现多次。然而,在大多数情况下,我们让Hadoop在Map和Reduce过程时自动分组(key, value)对这样的形式,因为Hadoop在这方面比我们简单的Python脚本效率更高。

mapper.py

reducer.py

英文原文:http://www.emunix.emich.edu/~sverdlik/COSC472/WritingAnHadoopMapReduceProgramInPython-MichaelG.Noll.html

译者:leisants

了解野狗,请点击阅读原文。返回搜狐,查看更多

责任编辑:

mapreduce编程实例python-使用Python语言写Hadoop MapReduce程序相关推荐

  1. mapreduce编程实例python-使用Python实现Hadoop MapReduce程序

    在这个实例中,我将会向大家介绍如何使用Python 为Hadoop编写一个简单的MapReduce 程序. 尽管Hadoop 框架是使用Java编写的但是我们仍然需要使用像C++.Python等语言来 ...

  2. 三、MapReduce编程实例

    前文 一.CentOS7 hadoop3.3.1安装(单机分布式.伪分布式.分布式) 二.JAVA API实现HDFS MapReduce编程实例 文章目录 前文 MapReduce编程实例 前言 注 ...

  3. 除了 Python ,这些语言写的机器学习项目也很牛(二)

    2019独角兽企业重金招聘Python工程师标准>>> Python 由于本身的易用优势和强大的工具库储备,成为了在人工智能及其它相关科学领域中最常用的语言之一.尤其是在机器学习,已 ...

  4. C语言第五篇 python调用C语言写的动态链接库DLL文件

    学习目标:1.学会C语言写windows下的DLL文件.2.用gcc命令将C程序编译成DLL文件.3.学会用python调用C语言写的DLL. 学习内容1:先用C语言写一个简单程序,先建立dll.c文 ...

  5. python画完图 程序暂停运行_[Python实战]你也能写的计时器程序

    文章地址:[Python实战]你也能写的计时器程序 上次,公众号介绍了如何使用 Pyqt5 制作猜数游戏界面,并介绍了如何在 Pycharm 中使用 Qt Designer 生成 UI 文件.这次,我 ...

  6. 大数据之Hadoop学习——动手实战学习MapReduce编程实例

    文章目录 一.MapReduce理论基础 二.Hadoop.Spark学习路线及资源收纳 三.MapReduce编程实例 1.自定义对象序列化 需求分析 报错:Exception in thread ...

  7. MapReduce编程实例

    实验目的 搭建MapReduce编程模型 配置Eclipse和Maven Hadoop集群与启动顺序 MapReduce的WordCount应用 书上代码练习 学习编写一个MapReduce程序 实验 ...

  8. 简单介绍三个C语言图形库C语言其实最擅长的是写纯数据处理的程序 . 非得用C语言写个界面程序那将会变得很困难 . 我刚开始学C语言就是从hello world 开始的 , 后来慢慢开始学从三个数中找

    C语言其实最擅长的是写纯数据处理的程序 . 非得用C语言写个界面程序那将会变得很困难 . 我刚开始学C语言就是从hello world 开始的 , 后来慢慢开始学从三个数中找出最大值 , 和对数组进行 ...

  9. c语言程序字体放大,C语言写的俄罗斯方块程序减小字体 增大字体 作者.docx

    C语言写的俄罗斯方块程序减小字体 增大字体 作者 C语言写的俄罗斯方块程序减小字体增大字体作者:佚名来源:不详发布时间:2009-9-21 1:11:22收藏到网摘:合作洽谈大概在最近两天之内编码完成 ...

最新文章

  1. [bzoj2333] [SCOI2011]棘手的操作 (可并堆)
  2. python3 collections模块_Python3之内建模块collections
  3. Metasploit远程调用Nessus出错
  4. Learn from mistake, i.e. 和 e.g. 是不同的
  5. 用VIPER构建iOS应用
  6. 【计算机组成原理】逻辑运算
  7. 电脑两边黑边怎么还原_Mac电脑录制的视频有黑边?如何解决
  8. AI 假冒老板骗取 173 万!
  9. HDU2186 一定要记住我爱你【水题】
  10. subsring 截取
  11. jquery中单选选中及清除选中状态
  12. Android app 页面加载统计工具
  13. k8s-kubeadm安装(五 网络插件calico)
  14. Lan内部是如何完成通信的
  15. 【CS学习笔记】14、powerup提权的方法
  16. 股票指标php源码,【图】成功率98.7%超高成功率指标(源码 有图 无未来)_炒股,炒股公式,股票论坛,炒股软件,股票指标_指标公式分享交流论坛_理想论坛 - 股票论坛...
  17. 轮播图左右按钮会被选中的问题
  18. metasploit小白教程总结
  19. 什么IT项目可以兼职在学校做
  20. 程序员可以收藏的几个导航网站

热门文章

  1. 放个手机在单位自动打卡_钉钉自动打卡(家校打卡,寒假特辑)
  2. 高斯混合模型Gaussian Mixture Model (GMM)——通过增加 Model 的个数,我们可以任意地逼近任何连续的概率密分布...
  3. 倒排索引优化 - 跳表求交集 空间换时间 贪心
  4. 孕期出血是否先兆流产——B超看婴儿是否在子宫内+hcg值是否过低孕激素不足...
  5. css美化单选款、复选框
  6. ES6的export与Nodejs的module.exports比较
  7. 2018牛客网暑期ACM多校训练营第二场 D - money(贪心)
  8. mysql 用命令行复制表数据到新表
  9. C语言指针数组和数组指针
  10. eclipse 使 用Ctrl+鼠标左键进入mapper.xml文件的方法