Hadoop streaming详细介绍

Hadoop streaming

Hadoop为MapReduce提供了不同的API,可以方便我们使用不同的编程语言来使用MapReduce框架,而不是只局限于Java。这里要介绍的就是Hadoop streaming API。Hadoop streaming 使用Unix的standard streams作为我们mapreduce程序和MapReduce框架之间的接口。所以你可以用任何语言来编写MapReduce程序,只要该语言可以往standard input/output上进行读写。

streamming是天然适用于文字处理的(text processing),当然,也仅适用纯文本的处理,对于需要对象和序列化的场景,hadoop streaming无能为力。它力图使我们能够快捷的通过各种脚本语言,快速的处理大量的文本文件。以下是steaming的一些特点:

  1. Map函数的输入是通过stand input一行一行的接收数据的。(不像Java API,通过InputFormat类做预处理,使得Map函数的输入是有Key和value的)
  2. Map函数的output则必须限定为key-value pair,key和value之间用\t分开。(MapReduce框架在处理intermediate的Map输出时,必须做sort和partition,即shuffle)
  3. Reduce函数的input是Map函数的output也是key-value pair,key和value之间用\t分开。

常用的Streaming编程语言:

  1. bash shell
  2. ruby
  3. python

Ruby

下面是一个Ruby编写的MapReduce程序的示例:

map

max_temperature_map.rb:

ruby
#!/usr/bin/env ruby
STDIN.each_line do |line|
val = line
year, temp, q = val[15,4], val[87,5], val[92,1]
puts "#{year}\t#{temp}" if (temp != "+9999" && q =~ /[01459]/)
end
  • 从标准输入读入一行data。
  • 处理数据之后,生成一个键值对,用\t分隔,输出到标准输出

reduce

max_temperature_reduce.rb:

ruby
#!/usr/bin/env ruby
last_key, max_val = nil, -1000000
STDIN.each_line do |line|
key, val = line.split("\t")
if last_key && last_key != key
puts "#{last_key}\t#{max_val}"
last_key, max_val = key, val.to_i
else
last_key, max_val = key, [max_val, val.to_i].max
end
end
puts "#{last_key}\t#{max_val}" if last_key
  1. 从标准输入读入一行数据
  2. 数据是用\t分隔的键值对
  3. 数据是被MapReduce根据key排序之后顺序一行一行读入
  4. reduce函数对数据进行处理,并输出,输出仍是用\t分隔的键值对

运行

% hadoop jar $HADOOP_INSTALL/contrib/streaming/hadoop-*-streaming.jar \
-input input/ncdc/sample.txt \
-output output \
-mapper ch02/src/main/ruby/max_temperature_map.rb \
-reducer ch02/src/main/ruby/max_temperature_reduce.rb
  1. hadoop jar $HADOOP_INSTALL/contrib/streaming/hadoop-*-streaming.jar指明了使用hadoop streaming
  2. hadoop-*-streaming.jar会将input里的文件,一行一行的输出到标准输出。
  3. 用-mapper指定Map函数。类似于通过管道将数据传给rb文件: data|ch02/src/main/ruby/max_temperature_map.rb
  4. -reducer指定Reduce函数。

Python

Map

#!/usr/bin/env python
import re
import sys
for line in sys.stdin:
val = line.strip()
(year, temp, q) = (val[15:19], val[87:92], val[92:93])
if (temp != "+9999" and re.match("[01459]", q)):
print "%s\t%s" % (year, temp)

Reduce

#!/usr/bin/env python
import sys
(last_key, max_val) = (None, -sys.maxint)
for line in sys.stdin:
(key, val) = line.strip().split("\t")
if last_key and last_key != key:
print "%s\t%s" % (last_key, max_val)
(last_key, max_val) = (key, int(val))
else:
(last_key, max_val) = (key, max(max_val, int(val)))
if last_key:
print "%s\t%s" % (last_key, max_val)

运行

% hadoop jar $HADOOP_INSTALL/contrib/streaming/hadoop-*-streaming.jar \
-input input/ncdc/sample.txt \
-output output \
-mapper ch02/src/main/ruby/max_temperature_map.py\
-reducer ch02/src/main/ruby/max_temperature_reduce.py

Bash shell

Map

#!/usr/bin/env bash
# NLineInputFormat gives a single line: key is offset, value is S3 URI
read offset s3file
# Retrieve file from S3 to local disk
echo "reporter:status:Retrieving $s3file" >&2
$HADOOP_INSTALL/bin/hadoop fs -get $s3file .
# Un-bzip and un-tar the local file
target=`basename $s3file .tar.bz2`
mkdir -p $target
echo "reporter:status:Un-tarring $s3file to $target" >&2
tar jxf `basename $s3file` -C $target
# Un-gzip each station file and concat into one file
echo "reporter:status:Un-gzipping $target" >&2
for file in $target/*/*
do
gunzip -c $file >> $target.all
echo "reporter:status:Processed $file" >&2
done
# Put gzipped version into HDFS
echo "reporter:status:Gzipping $target and putting in HDFS" >&2
gzip -c $target.all | $HADOOP_INSTALL/bin/hadoop fs -put - gz/$target.gz

运行

% hadoop jar $HADOOP_INSTALL/contrib/streaming/hadoop-*-streaming.jar \
-D mapred.reduce.tasks=0 \
-D mapred.map.tasks.speculative.execution=false \
-D mapred.task.timeout=12000000 \
-input ncdc_files.txt \
-inputformat org.apache.hadoop.mapred.lib.NLineInputFormat \
-output output \
-mapper load_ncdc_map.sh \
-file load_ncdc_map.sh
  1. 这里的-D mapred.reduce.tasks=0将reduce task观掉,因此也不需要设置-reducer
  2. 只使用Mapper,可以通过MapReduce帮助我们并行的完成一些平时只能串行的shell脚本
  3. 注意这里的-file,在集群模式下,需要并行运行时,需要-file把文件传输到其他节点

Combiner

在streaming模式下,仍然可以运行Combiner,两种方法:

  1. 通过Java编写一个combiner的函数,并使用-combiner option
  2. 以命令行的管道模式完成combiner的任务

这里具体解释第二种方法:

% hadoop jar $HADOOP_INSTALL/contrib/streaming/hadoop-*-streaming.jar \
-input input/ncdc/all \
-output output \
-mapper "ch02/src/main/ruby/max_temperature_map.rb | sort |
ch02/src/main/ruby/max_temperature_reduce.rb" \
-reducer ch02/src/main/ruby/max_temperature_reduce.rb \
-file ch02/src/main/ruby/max_temperature_map.rb \
-file ch02/src/main/ruby/max_temperature_reduce.rb

注意看-mapper这一行,通关管道的方式,把mapper的临时输出文件(intermediate file,Map完成后的临时文件)作为输入,送到sort进行排序,然后送到reduce脚本,来完成类似于combiner的工作。这时候的输出才真正的作为shuffle的输入,被分组并在网络上发送到Reduce

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • java结合HADOOP集群文件上传下载

    对HDFS上的文件进行上传和下载是对集群的基本操作,在<HADOOP权威指南>一书中,对文件的上传和下载都有代码的实例,但是对如何配置HADOOP客户端却是没有讲得很清楚,经过长时间的搜索和调试,总结了一下,如何配置使用集群的方法,以及自己测试可用的对集群上的文件进行操作的程序.首先,需要配置对应的环境变量: 复制代码 代码如下: hadoop_HOME="/home/work/tools/java/hadoop-client/hadoop" for f in $hadoo

  • Java访问Hadoop分布式文件系统HDFS的配置说明

    配置文件 m103替换为hdfs服务地址. 要利用Java客户端来存取HDFS上的文件,不得不说的是配置文件hadoop-0.20.2/conf/core-site.xml了,最初我就是在这里吃了大亏,所以我死活连不上HDFS,文件无法创建.读取. <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <co

  • Hadoop SSH免密码登录以及失败解决方案

    1. 创建ssh-key 这里我们采用rsa方式,使用如下命令: xiaosi@xiaosi:~$ ssh-keygen -t rsa -f ~/.ssh/id_rsa Generating public/private rsa key pair. Created directory '/home/xiaosi/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identifi

  • Hadoop MapReduce多输出详细介绍

    Hadoop MapReduce多输出 FileOutputFormat及其子类产生的文件放在输出目录下.每个reducer一个文件并且文件由分区号命名:part-r-00000,part-r-00001,等等.有时可能要对输出的文件名进行控制或让每个reducer输出多个文件.MapReduce为此提供了MultipleOutputFormat类. MultipleOutputFormat类可以将数据写到多个文件,这些文件的名称源于输出的键和值或者任意字符串.这允许每个reducer(或者只有

  • windows 32位eclipse远程hadoop开发环境搭建

    本文假设hadoop环境在远程机器(如linux服务器上),hadoop版本为2.5.2 注:本文eclipse/intellij idea 远程调试hadoop 2.6.0主要参考了并在其基础上有所调整 由于我喜欢在win7 64位上安装32位的软件,比如32位jdk,32位eclipse,所以虽然本文中的操作系统是win7 64位,但是所有的软件都是32位的. 软件版本: 操作系统:win7 64位 eclipse: eclipse-jee-mars-2-win32 java: 1.8.0_

  • 使用Maven搭建Hadoop开发环境

    关于Maven的使用就不再啰嗦了,网上很多,并且这么多年变化也不大,这里仅介绍怎么搭建Hadoop的开发环境. 1. 首先创建工程 复制代码 代码如下: mvn archetype:generate -DgroupId=my.hadoopstudy -DartifactId=hadoopstudy -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false 2. 然后在pom.xml文件里添加hadoop的依赖

  • Hadoop中的Python框架的使用指南

    最近,我加入了Cloudera,在这之前,我在计算生物学/基因组学上已经工作了差不多10年.我的分析工作主要是利用Python语言和它很棒的科学计算栈来进行的.但Apache Hadoop的生态系统大部分都是用Java来实现的,也是为Java准备的,这让我很恼火.所以,我的头等大事变成了寻找一些Python可以用的Hadoop框架. 在这篇文章里,我会把我个人对这些框架的一些无关科学的看法写下来,这些框架包括: Hadoop流 mrjob dumbo hadoopy pydoop 其它 最终,在

  • eclipse/intellij idea 远程调试hadoop 2.6.0

    很多hadoop初学者估计都我一样,由于没有足够的机器资源,只能在虚拟机里弄一个linux安装hadoop的伪分布,然后在host机上win7里使用eclipse或Intellj idea来写代码测试,那么问题来了,win7下的eclipse或intellij idea如何远程提交map/reduce任务到远程hadoop,并断点调试? 一.准备工作 1.1 在win7中,找一个目录,解压hadoop-2.6.0,本文中是D:\yangjm\Code\study\hadoop\hadoop-2.

  • Hadoop 2.x伪分布式环境搭建详细步骤

    本文以图文结合的方式详细介绍了Hadoop 2.x伪分布式环境搭建的全过程,供大家参考,具体内容如下 1.修改hadoop-env.sh.yarn-env.sh.mapred-env.sh 方法:使用notepad++(beifeng用户)打开这三个文件 添加代码:export JAVA_HOME=/opt/modules/jdk1.7.0_67 2.修改core-site.xml.hdfs-site.xml.yarn-site.xml.mapred-site.xml配置文件 1)修改core-

  • Hadoop streaming详细介绍

    Hadoop streaming Hadoop为MapReduce提供了不同的API,可以方便我们使用不同的编程语言来使用MapReduce框架,而不是只局限于Java.这里要介绍的就是Hadoop streaming API.Hadoop streaming 使用Unix的standard streams作为我们mapreduce程序和MapReduce框架之间的接口.所以你可以用任何语言来编写MapReduce程序,只要该语言可以往standard input/output上进行读写. st

  • 用python + hadoop streaming 分布式编程(一) -- 原理介绍,样例程序与本地调试

    MapReduce与HDFS简介 什么是Hadoop? Google为自己的业务需要提出了编程模型MapReduce和分布式文件系统Google File System,并发布了相关论文(可在Google Research的网站上获得: GFS . MapReduce). Doug Cutting和Mike Cafarella在开发搜索引擎Nutch时对这两篇论文做了自己的实现,即同名的MapReduce和HDFS,合起来就是Hadoop. MapReduce的Data flow如下图,原始数据

  • Android 开发音频组件(Vitamio FAQ)详细介绍

     一.Vitamio介绍 1.1 Vitamio是什么? Vitamio是Android平台视音频播放组件,支持播放几乎格式的视频以及主流网络视频流(http/rtsp/mms等),详细的中文介绍: 这里. Vitamio官网:http://vitamio.org/ Vitamio微博:http://weibo.com/vitamio VPlayer官网:http://vplayer.net Vitamio豆瓣:http://site.douban.com/145815/ 1.2 关于Vitam

  • AngularJS 执行流程详细介绍

    一.启动阶段 大家应该都知道,当浏览器加载一个HTML页面时,它会将HMTL页面先解析成DOM树,然后逐个加载DOM树中的每一个元素节点.我们可以把AngularJS当做一个类似jQuery的js库,我们通过<script>标签引入到HTML中,那么此时Angular就做为一个普通的DOM节点等待浏览器解析,当浏览器解析到这个节点时,发现它是一个js文件,那么浏览器会停止解析剩余的DOM节点,开始执行这个js(即angular.js),同时Angular会设置一个事件监听器来监听浏览器的DOM

  • Java探索之Hibernate主键生成策略详细介绍

    1.increment 由Hibernate从数据库中去除主键的最大值(每个session只取一次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库. <id name="id" column="id"> <generator class="increment" /> </id> Hibernate调用org.hibernate.id.IncrementGenerator类

  • python+mongodb数据抓取详细介绍

    分享点干货!!! Python数据抓取分析 编程模块:requests,lxml,pymongo,time,BeautifulSoup 首先获取所有产品的分类网址: def step(): try: headers = { ..... } r = requests.get(url,headers,timeout=30) html = r.content soup = BeautifulSoup(html,"lxml") url = soup.find_all(正则表达式) for i

  • VMware网络连接模式(桥接、NAT以及仅主机模式的详细介绍和区别)

    在使用VMware Workstation(以下简称:VMware)创建虚拟机的过程中,配置虚拟机的网络连接是非常重要的一环,当我们为虚拟机配置网络连接时,我们可以看到如下图所示的几种网络连接模式:桥接模式.NAT模式.仅主机模式.自定义网络连接模式.那么这几种网络连接模式都各自有什么主要用途,它们之间又有哪些区别呢? 磨刀不误砍柴工,为了更好地使用虚拟机,了解这几种连接模式的主要用途以及它们之间的区别是非常有必要的.在这里,我们就以下面的网络连接示意图为例来进行相关介绍. 在VMware中,虚

  • 正则表达式详细介绍(下)

    本文是前一片文章<正则表达式详细介绍(上)>的续篇,在本文中讲述了正则表达式中的组与向后引用,先前向后查看,条件测试,单词边界,选择符等表达式及例子,并分析了正则引擎在执行匹配时的内部机理. 9. 单词边界 元字符<<\b>>也是一种对位置进行匹配的"锚".这种匹配是0长度匹配. 有4种位置被认为是"单词边界": 1) 在字符串的第一个字符前的位置(如果字符串的第一个字符是一个"单词字符") 2) 在字符串的最

  • Python 通过pip安装Django详细介绍

    Python 通过pip安装Django详细介绍 经过前面的 Python 包管理工具的学习,接下来我们就要基于前面的知识,来配置 Django 的开发与运行环境. 首先是安装 Django(通过pip安装): pip install Django 输出的结果在我这里是这样的: Downloading/unpacking Django Downloading Django-1.5.2.tar.gz (8.0MB): 8.0MB downloaded Running setup.py egg_in

  • Hibernate 主清单文件配制的详细介绍

    Hibernate 主清单文件配制的详细介绍 1 Hiernate 清单配制文件 方式一 在工程src目录下创建 hibernate.cfg.xml 文件 Hiernate 开始加载时,会默认的方式去工程src目录下扫描 hibernate.cfg.xml文件,然后加载配制 public class H3Utils { private static SessionFactory factory = new Configuration().configure().buildSessionFacto

随机推荐