hadoopStreamming 编程
熟悉hadoop作业提交的人,只要明白streaming的参数就可以学会提交了,streaming提交作业比较灵活,支持多种语言,但是streaming有个缺陷就是,其封装的参数涉及到mapreduce类的就会默认其继承自org.apache.hadoop.mapred包中的类,因此继承自mapreduce包中的类不可用,但是有一个方法可以解决这个问题,就是将参数,通过-jobconf prop=value 的方式传进去。 这里的prop的名字必须是hadoop job file中那个名字。具体查看源代码。 下面一片文章很好的展示了 stream 提交 python和c语言写的作业,可作为初学参考: 作者:马士华 发表于:2008-03-05 12:51 最后更新于:2008-03-25 11:18 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息。 http://www.hadoop.org.cn/hadoop/hadoop-streaming/ Michael G. Noll在他的Blog中提到如何在Hadoop中用Python编写MapReduce程序,韩国的gogamza在其Bolg中也提到如何用C编写MapReduce程序(我稍微修改了一下原程序,因为他的Map对单词切分使用tab键)。我合并他们两人的文章,也让国内的Hadoop用户能够使用别的语言来编写MapReduce程序。 首先您得配好您的Hadoop集群,这方面的介绍网上比较多,这儿给个链接(Hadoop学习笔记二 安装部署)。Hadoop Streaming帮 助我们用非Java的编程语言使用MapReduce,Streaming用STDIN (标准输入)和STDOUT (标准输出)来和我们编写的Map和Reduce进行数据的交换数据。任何能够使用STDIN和STDOUT都可以用来编写MapReduce程序,比如 我们用Python的sys.stdin和sys.stdout,或者是C中的stdin和stdout。 我们还是使用Hadoop的例子WordCount来 做示范如何编写MapReduce,在WordCount的例子中我们要解决计算在一批文档中每一个单词的出现频率。首先我们在Map程序中会接受到这批 文档每一行的数据,然后我们编写的Map程序把这一行按空格切开成一个数组。并对这个数组遍历按" 1"用标准的输出输出来,代表这个单词出现了一次。在Reduce中我们来统计单词的出现频率。 Python Code Map: mapper.py #!/usr/bin/env python import sys # maps words to their counts word2count = {} # input comes from STDIN (standard input) for line in sys.stdin: # remove leading and trailing whitespace line = line.strip() # split the line into words while removing any empty strings words = filter(lambda word: word, line.split()) # increase counters for word in words: # write the results to STDOUT (standard output); # what we output here will be the input for the # Reduce step, i.e. the input for reducer.py # # tab-delimited; the trivial word count is 1 print '%s/t%s' % (word, 1) Reduce: reducer.py #!/usr/bin/env python from operator import itemgetter import sys # maps words to their counts word2count = {} # input comes from STDIN for line in sys.stdin: # remove leading and trailing whitespace line = line.strip() # parse the input we got from mapper.py word, count = line.split() # convert count (currently a string) to int try: count = int(count) word2count[word] = word2count.get(word, 0) + count except ValueError: # count was not a number, so silently # ignore/discard this line pass # sort the words lexigraphically; # # this step is NOT required, we just do it so that our # final output will look more like the official Hadoop # word count examples sorted_word2count = sorted(word2count.items(), key=itemgetter(0)) # write the results to STDOUT (standard output) for word, count in sorted_word2count: print '%s/t%s'% (word, count) C Code Map: Mapper.c #include #include #include #include #define BUF_SIZE 2048 #define DELIM "/n" int main(int argc, char *argv[]){ char buffer[BUF_SIZE]; while(fgets(buffer, BUF_SIZE - 1, stdin)){ int len = strlen(buffer); if(buffer[len-1] == '/n') buffer[len-1] = 0; char *querys = index(buffer, ' '); char *query = NULL; if(querys == NULL) continue; querys += 1; /* not to include '/t' */ query = strtok(buffer, " "); while(query){ printf("%s/t1/n", query); query = strtok(NULL, " "); } } return 0; } h>h>h>h> Reduce: Reducer.c #include #include #include #include #define BUFFER_SIZE 1024 #define DELIM "/t" int main(int argc, char *argv[]){ char strLastKey[BUFFER_SIZE]; char strLine[BUFFER_SIZE]; int count = 0; *strLastKey = '/0'; *strLine = '/0'; while( fgets(strLine, BUFFER_SIZE - 1, stdin) ){ char *strCurrKey = NULL; char *strCurrNum = NULL; strCurrKey = strtok(strLine, DELIM); strCurrNum = strtok(NULL, DELIM); /* necessary to check error but.... */ if( strLastKey[0] == '/0'){ strcpy(strLastKey, strCurrKey); } if(strcmp(strCurrKey, strLastKey)){ printf("%s/t%d/n", strLastKey, count); count = atoi(strCurrNum); }else{ count += atoi(strCurrNum); } strcpy(strLastKey, strCurrKey); } printf("%s/t%d/n", strLastKey, count); /* flush the count */ return 0; } h>h>h>h> 首先我们调试一下源码: chmod +x mapper.py chmod +x reducer.py echo "foo foo quux labs foo bar quux" | ./mapper.py | ./reducer.py bar 1 foo 3 labs 1 quux 2 g++ Mapper.c -o Mapper g++ Reducer.c -o Reducer chmod +x Mapper chmod +x Reducer echo "foo foo quux labs foo bar quux" | ./Mapper | ./Reducer bar 1 foo 2 labs 1 quux 1 foo 1 quux 1 你可能看到C的输出和Python的不一样,因为Python是把他放在词典里了.我们在Hadoop时,会对这进行排序,然后相同的单词会连续在标准输出中输出. 在Hadoop中运行程序 首先我们要下载我们的测试文档wget http://www.gutenberg.org/dirs/etext04/7ldvc10.txt.我们把文档存放在/tmp/doc这个目录下.拷贝测试文档到HDFS中. bin/hadoop dfs -copyFromLocal /tmp/doc doc 运行 bin/hadoop dfs -ls doc 看看拷贝是否成功.接下来我们运行我们的MapReduce的Job. bin/hadoop jar /home/hadoop/contrib/hadoop-0.15.1-streaming.jar -mapper /home/hadoop/Mapper/ -reducer /home/hadoop/Reducer -input doc/* -output c-output -jobconf mapred.reduce.tasks=1 additionalConfSpec_:null null=@@@userJobConfProps_.get(stream.shipped.hadoopstreaming packageJobJar: [] [/home/msh/hadoop-0.15.1/contrib/hadoop-0.15.1-streaming.jar] /tmp/streamjob60816.jar tmpDir=null 08/03/04 19:03:13 INFO mapred.FileInputFormat: Total input paths to process : 1 08/03/04 19:03:13 INFO streaming.StreamJob: getLocalDirs(): [/home/msh/data/filesystem/mapred/local] 08/03/04 19:03:13 INFO streaming.StreamJob: Running job: job_200803031752_0003 08/03/04 19:03:13 INFO streaming.StreamJob: To kill this job, run: 08/03/04 19:03:13 INFO streaming.StreamJob: /home/msh/hadoop/bin/../bin/hadoop job -Dmapred.job.tracker=192.168.2.92:9001 -kill job_200803031752_0003 08/03/04 19:03:13 INFO streaming.StreamJob: Tracking URL: http://hadoop-master:50030/jobdetails.jsp?jobid=job_200803031752_0003 08/03/04 19:03:14 INFO streaming.StreamJob: map 0% reduce 0% 08/03/04 19:03:15 INFO streaming.StreamJob: map 33% reduce 0% 08/03/04 19:03:16 INFO streaming.StreamJob: map 100% reduce 0% 08/03/04 19:03:19 INFO streaming.StreamJob: map 100% reduce 100% 08/03/04 19:03:19 INFO streaming.StreamJob: Job complete: job_200803031752_0003 08/03/04 19:03:19 INFO streaming.StreamJob: Output: c-output bin/hadoop jar /home/hadoop/contrib/hadoop-0.15.1-streaming.jar -mapper /home/hadoop/mapper.py/ -reducer /home/hadoop/reducer.py -input doc/* -output python-output -jobconf mapred.reduce.tasks=1 additionalConfSpec_:null null=@@@userJobConfProps_.get(stream.shipped.hadoopstreaming packageJobJar: [] [/home/hadoop/hadoop-0.15.1/contrib/hadoop-0.15.1-streaming.jar] /tmp/streamjob26099.jar tmpDir=null 08/03/04 19:05:40 INFO mapred.FileInputFormat: Total input paths to process : 1 08/03/04 19:05:41 INFO streaming.StreamJob: getLocalDirs(): [/home/msh/data/filesystem/mapred/local] 08/03/04 19:05:41 INFO streaming.StreamJob: Running job: job_200803031752_0004 08/03/04 19:05:41 INFO streaming.StreamJob: To kill this job, run: 08/03/04 19:05:41 INFO streaming.StreamJob: /home/msh/hadoop/bin/../bin/hadoop job -Dmapred.job.tracker=192.168.2.92:9001 -kill job_200803031752_0004 08/03/04 19:05:41 INFO streaming.StreamJob: Tracking URL: http://hadoop-master:50030/jobdetails.jsp?jobid=job_200803031752_0004 08/03/04 19:05:42 INFO streaming.StreamJob: map 0% reduce 0% 08/03/04 19:05:48 INFO streaming.StreamJob: map 33% reduce 0% 08/03/04 19:05:49 INFO streaming.StreamJob: map 100% reduce 0% 08/03/04 19:05:52 INFO streaming.StreamJob: map 100% reduce 100% 08/03/04 19:05:52 INFO streaming.StreamJob: Job complete: job_200803031752_0004 08/03/04 19:05:52 INFO streaming.StreamJob: Output: python-output 当Job提交后我们还能够在web的界面http://localhost:50030/看到每一个工作的运行情况。 当Job工作完成后我们能够在c-output和python-output看到一些文件 bin/hadoop dfs -ls c-output 输入下面的命令我们能够看到我们运行完MapReduce的结果 bin/hadoop dfs -cat c-output/part-00000 用Hadoop Streaming运行MapReduce会比较用Java的代码要慢,因为有两方面的原因: 使用 Java API >> C Streaming >> Perl Streaming 这样的一个流程运行会阻塞IO. 不像Java在运行Map后输出结果有一定数量的结果集就启动Reduce的程序,用Streaming要等到所有的Map都运行完毕后才启动Reduce 如果用Python编写MapReduce的话,另一个可选的是使用Jython来转编译Pyhton为Java的原生码.另外对于C程序员更好的选择是使用Hadoop新的C++ MapReduce API Pipes来编写.不管怎样,毕竟Hadoop提供了一种不使用Java来进行分布式运算的方法. 下面是从http://www.lunchpauze.com/2007/10/writing-hadoop-mapreduce-program-in-php.html页面中摘下的用php编写的MapReduce程序,供php程序员参考: Map: mapper.php #!/usr/bin/php $word2count = array(); // input comes from STDIN (standard input) while (($line = fgets(STDIN)) !== false) { // remove leading and trailing whitespace and lowercase $line = strtolower(trim($line)); // split the line into words while removing any empty string $words = preg_split('//W/', $line, 0, PREG_SPLIT_NO_EMPTY); // increase counters foreach ($words as $word) { $word2count[$word] += 1; } } // write the results to STDOUT (standard output) // what we output here will be the input for the // Reduce step, i.e. the input for reducer.py foreach ($word2count as $word => $count) { // tab-delimited echo $word, chr(9), $count, PHP_EOL; } ?> Reduce: mapper.php #!/usr/bin/php $word2count = array(); // input comes from STDIN while (($line = fgets(STDIN)) !== false) { // remove leading and trailing whitespace $line = trim($line); // parse the input we got from mapper.php list($word, $count) = explode(chr(9), $line); // convert count (currently a string) to int $count = intval($count); // sum counts if ($count > 0) $word2count[$word] += $count; } // sort the words lexigraphically // // this set is NOT required, we just do it so that our // final output will look more like the official Hadoop // word count examples ksort($word2count); // write the results to STDOUT (standard output) foreach ($word2count as $word => $count) { echo $word, chr(9), $count, PHP_EOL; } ?>
hadoopStreamming 编程的更多相关文章
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议
软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...
- 读书笔记:JavaScript DOM 编程艺术(第二版)
读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- C#异步编程(一)
异步编程简介 前言 本人学习.Net两年有余,是第一次写博客,虽然写的很认真,当毕竟是第一次,肯定会有很多不足之处, 希望大家照顾照顾新人,有错误之处可以指出来,我会虚心接受的. 何谓异步 与同步相对 ...
- UE4新手之编程指南
虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程. 新的游戏类.Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写,并且在使用Visual Studio 或 ...
- C#与C++的发展历程第三 - C#5.0异步编程巅峰
系列文章目录 1. C#与C++的发展历程第一 - 由C#3.0起 2. C#与C++的发展历程第二 - C#4.0再接再厉 3. C#与C++的发展历程第三 - C#5.0异步编程的巅峰 C#5.0 ...
- 猫哥网络编程系列:HTTP PEM 万能调试法
注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...
- 关于如何提高Web服务端并发效率的异步编程技术
最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...
随机推荐
- Executors相关的类(线程池)
一.概述 Java是天生就支持并发的语言,支持并发意味着多线程,线程的频繁创建在高并发及大数据量是非常消耗资源的,因为java提供了线程池.在jdk1.5以前的版本中,线程池的使用是及其简陋的,但是在 ...
- 梯度下降法实现最简单线性回归问题python实现
梯度下降法是非常常见的优化方法,在神经网络的深度学习中更是必会方法,但是直接从深度学习去实现,会比较复杂.本文试图使用梯度下降来优化最简单的LSR线性回归问题,作为进一步学习的基础. import n ...
- 关于sys.dm_exec_requests
我知道SQL Server有很多视图和函数让我来了解SQL Server的运行状态.我还想知道SQL Server上关于来自用户或者应用的活动请求信息.怎么查询这些信息呢? SQL Server的动态 ...
- spring mvc 解决跨域问题
Spring MVC 从4.2版本开始增加了对CORS的支持. 在Controller上使用@CrossOrigin注解: // 指定域名 @CrossOrigin("http://doma ...
- UNIX高级环境编程(3)Files And Directories - stat函数,文件类型,和各种ID
在前面的两篇,我们了解了IO操作的一些基本操作函数,包括open.read和write. 在本篇我们来学习一下文件系统的其他特性和一个文件的属性,涉及的函数功能包括: 查看文件的所有属性: 改变文件所 ...
- 铁乐学python_Day43_协程
铁乐学python_Day43_协程 引子 之前我们学习了线程.进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位. 按道理来说我们已经算是把cpu的利用率提高很多了. ...
- zabbix日常监控项TCP连接状态(六)
TCP的连接状态对于我们web服务器来说是至关重要的,尤其是并发量ESTAB或者是syn_recv值,假如这个值比较大的话我们可以认为是不是受到了攻击,或是time_wait值比较高的话,我们要考虑看 ...
- 解析JS运动
解析JS运动 物体运动原理:通过改变物体的位置,而发生移动变化. 任何运动都是相对的,就像物理中的运动公式:s(要达到的)=s0(当前的样式值)+vt. 方法: 1.运动的物体使用绝对定位 ...
- struts2 标签使用注意
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/qilixiang012/article/details/31954501 通常是用html标签.而不 ...
- 1877. [SDOI2009]晨跑【费用流】
Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他 坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个 ...