Hadoop Streaming排序

608 阅读2分钟

一次hadoop streaming排序的踩坑记录

工作需要,要对一个hadoop streaming任务加一个distribute by和sort by逻辑, 非sql就需要指定partitioner和comparator,便按照官网手册开发。

贴上地址: hadoop.apache.org/docs/curren…

  • MR任务都需要将数据分散到各个redece,hadoop streaming也不例外,默认是将map output按照'\t'分割,分割后的第一个字段做为key,如果没有'\t'便以整条记录做为key。

Hadoop Partitioner Class

mapred streaming \
  -D stream.map.output.field.separator=. \ --设置map output的分割符为'.'
  -D stream.num.map.output.key.fields=4 \  --分割后的前4个字段都做为key 
  -D map.output.key.field.separator=. \    --设置key的分隔符
  -D mapreduce.partition.keypartitioner.options=-k1,2 \ --取key的第一个和第二个字段做为partitioner
  -D mapreduce.job.reduces=12 \
  -input myInputDirs \
  -output myOutputDir \
  -mapper /bin/cat \
  -reducer /bin/cat \
  -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner  --开启自定义partitioner

给官网的demo必要的参数加了注释


Hadoop Comparator Class

mapred streaming \
  -D mapreduce.job.output.key.comparator.class=org.apache.hadoop.mapreduce.lib.partition.KeyFieldBasedComparator \  --开启自定义Comparator
  -D stream.map.output.field.separator=. \
  -D stream.num.map.output.key.fields=4 \
  -D mapreduce.map.output.key.field.separator=. \
  -D mapreduce.partition.keycomparator.options=-k2,2nr \  --取key的第二个字段数字序倒序 (n表示数字序,r表示倒序)
  -D mapreduce.job.reduces=1 \
  -input myInputDirs \
  -output myOutputDir \
  -mapper /bin/cat \
  -reducer /bin/cat

同时使用

mapred streaming \
 -D mapreduce.job.output.key.comparator.class=org.apache.hadoop.mapreduce.lib.partition.KeyFieldBasedComparator \  --开启自定义Comparator
 -D stream.map.output.field.separator=. \ --设置map output的分割符为'.'
 -D stream.num.map.output.key.fields=4 \  --分割后的前4个字段都做为key 
 -D map.output.key.field.separator=. \    --设置key的分隔符
 -D mapreduce.partition.keypartitioner.options=-k1,2 \ --取key的第一个和第二个字段做为partitioner
 -D mapreduce.partition.keycomparator.options=-k2,2nr \  --取key的第二个字段数字序倒序 (n表示数字序,r表示倒序)
 -D mapreduce.job.reduces=12 \
 -input myInputDirs \
 -output myOutputDir \
 -mapper /bin/cat \
 -reducer /bin/cat \
 -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner  --开启自定义partitioner

介绍完hadoop streaming的partitioner和comparator使用方法,记录下我遇到的坑。

mapper的代码是python写的,map output的连接字符是'\0'。

这个字符在python中是可处理的,但是整个MR是在linux中执行

reduce是cat

-reducer /bin/cat 

这时'\0'便是linux中不可见的字符

-D stream.map.output.field.separator=\0   --尝试过多种写法都失败了

最后把map output中的链接字符换成特定字符串,写了个reduce,在reduce中替换回'\0'解决。