我们在使用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开头的数据在后!

最新文章

  1. coding.net就这么横空出世
  2. nginx反向代理后getRequestURL会出现问题
  3. ssl_error_rx_record_too_long
  4. CentOS6.5+nginx+tomcat负载均衡集群
  5. How To Install Linux, Nginx, MySQL, PHP (LEMP) Stack on Debian 7
  6. 转载cocos2dx的各种动作用法
  7. POJ 1422
  8. MyBatis的学习总结四:实现关联表查询【参考】
  9. SVN trunk、branch、tag的用法
  10. 【c语言】推断一个数是不是2的n次方
  11. C/C++中char* 与char []定义的区别
  12. 新版本chrome浏览器控制台怎么设置成独立的窗口
  13. 华为CloudIDE免费公测,带你出坑带你飞
  14. 拖拽模块move2
  15. Django+Bootstrap+Mysql 搭建个人博客(四)
  16. Thread.Abort 方法
  17. 43-2-CAN协议
  18. SSM-网站后台管理系统制作(2)---SSM基本工作原理
  19. 20181226 PL/SQL批量生产处理语句
  20. PHP的数组合并

热门文章

  1. 剑指offer 11:二进制中 1 的个数
  2. ZJOI2019游记
  3. 网球pt站 T3nnis 情况说明
  4. The threat to world
  5. (转)如何在maven的pom.xml中添加本地jar包
  6. 使用vue实现自定义搜索功能
  7. [Web Service] Java Web Services Tutorial
  8. Windows下安装和卸载MangoDB服务 --MangoDB
  9. Lab 9-3
  10. 关于隐式创建vue实例实现简化弹出框组件显示步骤