zoukankan      html  css  js  c++  java
  • Hadoop Streaming框架使用(三)

    前两篇文章介绍了Hadoop Streaming框架的使用方法。由于篇幅所限,并没有介绍其中的高级使用方法,但是有一些用法还是相当常见的。今天对一些高级用法进行一个简单的说明,希望能给大家一些启发。

      1 使用cacheFile分发文件

      如果文件(如字典文件)存放在HDFS中,希望计算时在每个计算节点上将文件当作本地文件处理,,可以使用-cacheFile hdfs://host:port/path/to/file#linkname选项在计算节点缓存文件,Streaming程序通过./linkname访问文件。

      例如:

       hadoop = `which hadoop`

       $hadoop streaming \

       -input /user/test/input -output /user/test/output \

    -mapper mymapper.sh -reducer myreducer.sh \

       -file /home/work/mymapper.sh \ 

    -file /home/work/myreducer.sh \

    -cacheFile hdfs://namenode:port/user/test/dict.data#dictlink \

    -jobconf mapred.job.name=”cache-file-demo”

      mymapper.sh和myreducer.sh可以通过./dictlink直接访问字典文件hdfs://user/test/dict.data,而且是从本地读取文件。

     

      2 用cacheArchive分发压缩包

      有时要分发的文件有一定的目录结构,可以先将整个目录打包,然后整体进行上传。使用-cacheArchive hdfs://host:port/path/to/archivefile#linkname分发压缩包。

    例如在本地有一个目录为app,里面有mapper.pl, reducer.pl, dict/dict.txt这些子目录和文件,mapper.pl和reducer.pl要读取./dict/dict.txt文件,希望在任务执行时不需要修改程序和目录结构, 可以按照下面的方式分发app目录:

       $ tar app.tar.gz –C app .  #本地打包

       $ $HADOOP_HOME/bin/hadoop fs –put app.tar.gz /user/test/app.tar.gz   #包上传到HDFS

    $ $HADOOP_HOME/bin/hadoop streaming \

    -input /user/test/input -output /user/test/output \

    -mapper “perl app/mapper.pl” -reducer “perl app/reducer.pl” \

    -cacheArchive hdfs://namenode:port/user/test/ app.tar.gz #app \

    -jobconf mapred.job.name=”cache-archive-demo”

    首先将本地app目录中的所有文件和目录打包压缩,然后上传到HDFS的/user/test/app.tar.gz,启动streaming任务时使用-cacheArchive选项将app.tar.gz分发到计算节点并解压到app目录,然后在当前工作目录创建到app目录的链接,-mapper选项指定app/mapper.pl为mapper程序,-reducer选项指定app/reducer.pl为reducer程序,它们都可以读取./dict/dict.txt文件。本地打包时要进入目录app而不是在app的上层目录打包,否则要通过app/app/mapper.pl才能访问到mapper.pl文件。

    hadoop支持zip, jar, tar.gz格式的压缩包,由于Java解压zip压缩包时会丢失文件权限信息而且遇到中文文件名会出错,所见建议采用tar.gz压缩包。

    三种文件分发方式的区别:-file将客户端本地文件打成jar包上传到HDFS然后分发到计算节点,-cacheFile将HDFS文件分发到计算节点,-cacheArchive将HDFS压缩文件分发到计算节点并解压。

     

    3输出数据分割

    默认情况下Streaming框架将map输出的每一行第一个”\t”之前的部分作为key,之后的部分作为value,key\tvalue又作为reduce的输入。可以用-D stream.map.output.field.separator改变map输出中key和value的分隔符,用-D stream.num.map.output.key.fields设置分隔符的位置,该位置之前的部分作为key,之后的部分作为value。如下所示,其中-D stream.map. output.field.separator=:指定使用冒号”:”将map输出的一行分隔为key/value,-D stream.num.map.output.key.fields=2指定在第二个冒号处进行分隔,也就是第二个冒号之前的作为key,之后的作为value。如果没有冒号或冒号少于两个,则key为整行,value为空。 

       $HADOOP_HOME/bin/hadoop streaming \

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

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

    -input /user/test/input -output /user/test/output \

    -mapper mymapper.sh -reducer myreducer.sh \

    -file /home/work/mymapper.sh \

    -file /home/work/myreducer.sh \

    -jobconf mapred.job.name=”output-sep-demo”

    与map类似,对于reduce的输出,同样也可以用-D stream.reduce.output.field.separator和-D stream.num.reduce.output.key.fields定制key/value分隔方式。

    4 二次排序

      KeyFieldBasedPartitioner是Hadoop库中的一个实用Partitioner,配置相应的参数就可以使用,通过KeyFieldBasedPartitioner可以方便地实现二次排序。 

       $HADOOP_HOME/bin/hadoop streaming \

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

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

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

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

       -input /user/test/input -output /user/test/output \

       -mapper “mymapper.sh” -reducer “ myreducer.sh” \

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

    -file /home/work/mymapper.sh \

    -file /home/work/myreducer.sh \

    -jobconf mapred.job.name=”key-partition-demo”

      其中-Dstream.map.output.field.separator=.和-D stream.num.map.output.key.fields=4与上面的定制输出数据分隔方式意义相同,指定map的输出行第4个英文句号”.”之前为key,后面为value。-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner指定使用KeyFieldBasedPartitioner,-D map.output.key.field.separator=.指定key的内部用英文句号”.”分隔,-D num.key.fields.for.partition=2指定将key分隔出来的前两个部分而不是整个key用于Partitioner做partition。

      以上就是我个人认为hadoop streaming中比较常用的技巧,希望对大家有所帮助,同时也多多补充。

  • 相关阅读:
    iframeUpload
    获取当前文件路径。
    ie6 overflow 失效
    ie8 vml不显示
    json转换
    nodejs for windows
    模块化管理组件(2012/05/09)
    模块化管理组件v0.1
    Firefox和IE之间7个JavaScript的差异
    c输入函数细节
  • 原文地址:https://www.cnblogs.com/xupeizhi/p/2943364.html
Copyright © 2011-2022 走看看