我们在使用hadoop streaming的时候默认streaming的map和reduce的separator不指定的话,map和reduce会根据它们默认的分隔符来进行排序

map、reduce:默认的分隔符是\t(读入数据)

得到的结果都是按第一个分隔符排序去重后的结果

假设我们的有这么一列数据:USER IP DIR

我们想得到某一个用户的某一个ip的一系列dir,那我们应该怎么办呢?

这里我们就会用到streaming map和reduce的separator来指定key来进行排序和去重

1.默认情况

在hadoop streaming的默认情况下,是以”\t”作为分隔符的。对于标准输入来说,每行的第一个”\t” 以前的部分为key,其他部分为对应的value。如果一个”\t”字符没有,则整行都被当做key。这个

2.map阶段的sort与partition

map阶段很重要的阶段包括sort与partition。排序是按照key来进行的。咱们之前讲了默认的key是由”\t”分隔得到的。我们能不能自己控制相关的sort与partition呢?答案是可以的。

先看以下几个参数:

map.output.key.field.separator: map中key内部的分隔符

num.key.fields.for.partition: 分桶时,key按前面指定的分隔符分隔之后,用于分桶的key占的列数。通俗地讲,就是partition时候按照key中的前几列进行划分,相同的key会被打到同一个reduce里。

-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner 前两个参数,要配合partitioner选项使用!

stream.map.output.field.separator: map中的key与value分隔符

stream.num.map.output.key.fields: map中分隔符的位置

stream.reduce.output.field.separator: reduce中key与value的分隔符

stream.num.reduce.output.key.fields: reduce中分隔符的位置

3.分桶测试实例

准备数据:

$ cat tmp

1,2,1,1,1

1,2,2,1,1

1,3,1,1,1

1,3,2,1,1

1,3,3,1,1

1,2,3,1,1

1,3,1,1,1

1,3,2,1,1

1,3,3,1,1

上传到hdfs中。

cat mapper.sh

#!/bin/bash

cat

$ cat reducer.sh

#!/bin/bash

sort

#!/bin/bash

streaming=/usr/lib/hadoop-mapreduce/hadoop-streaming-2.5.0-cdh5.2.0.jar

output=/tmp/wanglei/part_out

if hadoop fs -test -d $output

then

hadoop fs -rm -r $output

fi

hadoop jar $streaming \

-D map.output.key.field.separator=, \

-D num.key.fields.for.partition=2 \

-D stream.reduce.output.field.separator=, \

-D stream.num.reduce.output.key.fields=4 \

-D mapred.reduce.tasks=2 \

-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \

-input /tmp/wanglei/partition \

-output $output \

-mapper "sh mapper.sh" \

-reducer "sh reducer.sh" \

-file mapper.sh \

-file reducer.sh

代码最后的运行结果:

$ hadoop fs -cat /tmp/wanglei/part_out/part-00000

1,3,1,1 1

1,3,1,1 1

1,3,2,1 1

1,3,2,1 1

1,3,3,1 1

1,3,3,1 1

$ hadoop fs -cat /tmp/wanglei/part_out/part-00001

1,2,1,1 1

1,2,2,1 1

1,2,3,1 1

稍微解释一下输出:

1.map阶段,key是按逗号分隔的,partition的阶段取前两个字段,所以前两个字段相同的key都被打到同一个reduce里。这一点从reduce的两个文件结果中就能看出来。

2.reduce阶段通过stream.reduce.output.field.separator指定分隔符为”,”,通过stream.num.reduce.output.key.fields指定前4个字段为key,所以才会有最终的结果。

需要注意的几个小点:

1.之前写的代码,当分发的文件有多个的时候,可以用-files指定。但是加了上面的参数以后,再用-files会报错。具体原因未知。

2.-file 参数必须写在最后面。如果写在-input前面,代码也会报错。具体原因暂时也未知。

3.-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner参数必须指定,否则代码没法输出预期结果。

4.map阶段输出测试实例

stream.map.output.field.separator与stream.num.map.output.key.fields与上面partition一组参数指定map输出格式是一致的。不一样的地方在stream这组参数是真正用于map端的输出,而partition那组参数是用于分桶!

看下测试代码就清楚了:

#!/bin/bash

streaming=/usr/lib/hadoop-mapreduce/hadoop-streaming-2.5.0-cdh5.2.0.jar

output=/tmp/wanglei/part_out_map

if hadoop fs -test -d $output

then

hadoop fs -rm -r $output

fi

hadoop jar $streaming \

-D stream.map.output.field.separator=, \

-D stream.num.map.output.key.fields=2 \

-input /tmp/wanglei/partition \

-output $output \

-mapper "sh mapper.sh" \

-file mapper.sh

$ hadoop fs -cat /tmp/wanglei/part_out_map/*

1,2 3,1,1

1,2 2,1,1

1,2 1,1,1

1,3 3,1,1

1,3 2,1,1

1,3 1,1,1

1,3 3,1,1

1,3 2,1,1

1,3 1,1,1

将reducer部分去掉,只输出mapper的结果。可以看出:

1.mapper阶段输出的k,v以”\t”分隔(框架默认)

2.mapper阶段以”,”分隔,key占了两个字段。

3.mapper阶段按key排序,所以1,2开头的数据在前,1,3开头的数据在后!

hadoop streaming字段排序介绍的更多相关文章

  1. Hadoop streaming 排序、分桶参数设置

    编写hadoop任务经常需要用到partition和排序.这里记录一下几个参数. 1. 概念 Partition:分桶过程,用户输出的key经过partition分发到不同的reduce里,因而par ...

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

    相关随笔: Hadoop-1.0.4集群搭建笔记 用python + hadoop streaming 编写分布式程序(二) -- 在集群上运行与监控 用python + hadoop streami ...

  3. hadoop streaming 编程

    概况 Hadoop Streaming 是一个工具, 代替编写Java的实现类,而利用可执行程序来完成map-reduce过程.一个最简单的程序 $HADOOP_HOME/bin/hadoop jar ...

  4. hadoop streaming编程小demo(python版)

    大数据团队搞数据质量评测.自动化质检和监控平台是用django,MR也是通过python实现的.(后来发现有orc压缩问题,python不知道怎么解决,正在改成java版本) 这里展示一个python ...

  5. Hadoop Streaming详解

    一: Hadoop Streaming详解 1.Streaming的作用 Hadoop Streaming框架,最大的好处是,让任何语言编写的map, reduce程序能够在hadoop集群上运行:m ...

  6. 用python + hadoop streaming 编写分布式程序(三) -- 自定义功能

    又是期末又是实训TA的事耽搁了好久……先把写好的放上博客吧 相关随笔: Hadoop-1.0.4集群搭建笔记 用python + hadoop streaming 编写分布式程序(一) -- 原理介绍 ...

  7. Hadoop Streaming框架使用(二)

    上一篇文章介绍了Streaming的各种参数,本文具体介绍使用方法. 提交hadoop任务示例: $HADOOP_HOME/bin/hadoop streaming \ -input /user/te ...

  8. Hadoop Streaming

    原文地址:http://hadoop.apache.org/docs/r1.0.4/cn/streaming.html Hadoop Streaming Streaming工作原理 将文件打包到提交的 ...

  9. Hadoop Streaming框架使用(一)

      Streaming简介 link:http://www.cnblogs.com/luchen927/archive/2012/01/16/2323448.html Streaming框架允许任何程 ...

随机推荐

  1. Go 嵌入类型

    文章转载地址:https://www.flysnow.org/2017/04/06/go-in-action-go-embedded-type.html 嵌入类型或嵌套类型,这是一种可以把已有类型的声 ...

  2. Vue小项目二手书商城:(四)详情页和购物车(emit、prop、computed)

    实现效果: 点击对应商品,对应的商品详情页出现,详情页里面还有“Add to cart”按钮和“×”退出按钮. 点击“Add to cart”可以将商品加入购物车,每件商品只能添加一次,如果把购物车的 ...

  3. 忽略 iconv 转码错误导致输出中断

    在遇到一些特殊字符时候,使用iconv转码会提示报错,导致整段文字输出为空,解决的方法是增加TRANSLIT//IGNORE $str = iconv("UTF-8", " ...

  4. android studio出现offline情况

    1.检查是否打开开发者选项 2.检查手机是否处于传输文件模式

  5. web.xml 设置字符编码

    个人理解  就是为了防止在前端输入的数据到了后台发生乱码 直接复制到web.xml里面就可以使用 亲测 能用!!! <!-- 前端过滤器设置字符编码 --> <filter> ...

  6. mysql 表关联批量更新

    项目中最近遇到了需要手动修改某个表的某个字段的数据,但是这个数据是来自别的表,需要关联,所以需要用到关联的批量更新,特此记录一下. UPDATE t_account_trans_info AS iiI ...

  7. mpvue开发项目总结(从0到上线)

    1.简言 为期一个半月的小程序开发,其中夹杂其他项目的功能迭代,跌跌撞撞的将项目完成了,今天中秋节放假前一天,以此来记录下此次打怪升级的心得与分享其中遇到花费时间的问题. 因为此次开发的是一个类电商项 ...

  8. Node.js 8 中的 util.promisify的详解

    Node.js 8带来了 很多新特性 .其中比较值得注意的,便有 util.promisify() 这个方法. util.promisify() 虽然 Promise 已经普及,但是 Node.js ...

  9. java无锁化编程一:目录

    假设我们用netty做服务,当接受到网络传输的码流,我们通过某种手段将这种传输数据解析成了熟悉的pojo,那这些pojo该如何进一步处理? 比如游戏中的抢购.场景业务等,对处理那种高并发的业务场景,如 ...

  10. Delphi 带星期几的日期格式化

    把日期按日期+星期几的格式输出 方法1:DatetoStr + DayOfWeek计算 ,这种办法灵活,但计算量大,不再祥叙. 方法2:FormatDateTime 具体代码如下://这里需要用For ...