使用Hadoop Streaming通过脚本运行二进制文件

时间:2012-11-30 20:55:16

标签: hadoop hadoop-streaming

我是Hadoop的新手,我正在尝试找到一种方法来执行以下操作:

  1. 我有多个输入图像文件。
  2. 我有处理这些文件的二进制可执行文件。
  3. 这些二进制可执行文件将文本文件写为输出。
  4. 我有一个包含所有这些可执行文件的文件夹。
  5. 我有一个脚本,它按特定顺序运行所有这些可执行文件,将图像位置作为参数传递。
  6. 我的问题是:我可以使用Hadoop流通过这些二进制文件处理这些图像,并从文本文件中吐出结果。

    我目前正在尝试这个。

    我的Hadoop集群正在运行。我通过二进制文件和我的图像上传到HDFS。

    我已经设置了一个脚本,当hadoop运行时,应该将目录更改为包含图像的文件夹,并执行另一个执行二进制文件的脚本。

    然后,脚本通过stdout吐出结果。

    但是,我无法弄清楚如何将我的地图脚本更改为HDFS上的图像文件夹,然后执行其他脚本。

    有人能给我一个暗示吗?

        sudo ./hadoop/bin/hadoop jar ../hduser/hadoop/contrib/streaming/hadoop-streaming-1.1.0.jar \
    -numReduceTasks 0 \
    -file /home/hduser/RunHadoopJob.sh \
    -input  /user/hduser/7posLarge \
    -output /user/hduser/output5 \
    -mapper RunHadoopJob.sh  \
    -verbose
    

    我的RunHadoopJob.sh:

    #!/bin/bash
    cd /user/hduser/7posLarge/;
    /user/hduser/RunSFM/RunSFM.sh;
    

    我的HDFS看起来像这样:

    hadoop fs -ls
    Warning: $HADOOP_HOME is deprecated.
    
    Found 4 items
    drwxr-xr-x   - hduser supergroup          0 2012-11-28 17:32 /user/hduser/7posLarge
    drwxr-xr-x   - hduser supergroup          0 2012-11-28 17:39 /user/hduser/RunSFM
    drwxr-xr-x   - root   supergroup          0 2012-11-30 14:32 /user/hduser/output5
    

    我知道这不是MapReduce的标准用法。我只是在寻找一种轻松的方法,而不需要在不同输入的同一程序的不同集群上编写多个工作。似乎可以查看Hadoop Streaming documentation

      

    “如何使用Hadoop Streaming运行任意一组   (半)独立任务?

         

    通常你不需要Map Reduce的全部功能,但只需要   运行同一程序的多个实例 - 在不同的部分   数据,或相同的数据,但具有不同的参数。您   可以使用Hadoop Streaming执行此操作。 “

    如果无法做到这一点,那么在AmazonAWS上还有另一个工具可以为我做这个吗?

    更新 看起来有类似的解决方案,但我无法遵循它们。它们是herehere

2 个答案:

答案 0 :(得分:0)

处理Hadoop-streaming和二进制文件时有几个问题:

  • Hadoop不了解如何处理图像文件
  • mappers逐行从stdin获取输入,因此您需要创建一个写入图像的中间shell脚本 从stdin到某个临时数据。然后传递的文件 到可执行文件。

将目录位置传递给可执行文件并不是很有效,因为在这种情况下,您将丢失数据局部性。我不想重复关于这个主题已经很好回答的问题,所以这里有链接:
Using Amazon MapReduce/Hadoop for Image Processing
Hadoop: how to access (many) photo images to be processed by map/reduce?

另一种方法是将图像文件转换为可拆分的SequenceFiles。即:每条记录都是SequenceFile中的一个图像。然后使用它作为输入格式,映射器将调用它们获得的每个记录上的可执行文件。请注意,您必须事先使用正确的文件权限将它们提供给TaskTracker节点,以便它们可以从Java代码中执行。
关于这个主题的更多信息:
Hadoop: Example process to generating a SequenceFile with image binaries to be processed in map/reduce

答案 1 :(得分:0)

我能够使用“hack”来获得变通方法的原型。

我仍在尝试这一点,我认为这不会在弹性集群上运行,因为您必须根据集群的操作系统架构重新编译二进制文件。但是,如果您有一个私有群集,这可能是一个解决方案。

使用hadoop流式传输,您可以将二进制文件打包到.jar文件中并将它们发送到节点,在脚本运行之前,它们将被解压缩。

我在pics.jar中有我的图像和我的程序,它处理在BinaryProgramFolder.jar中启动程序的目录中找到的所有图像。在文件夹里面,我有一个启动程序的脚本。

我的流媒体作业将图像和二进制程序+脚本发送到节点并启动它们。再一次,这是一个解决方法的黑客...而不是解决问题的“真正”解决方案。

所以,

sudo ./hadoop/bin/hadoop jar ../hduser/hadoop/contrib/streaming/hadoop-streaming-1.1.0.jar \
    -archives 'hdfs://master:54310/user/hduser/pics.jar#pics','hdfs://master:54310/user/hduser/BinaryProgramFolder.jar#BinaryProgramFolder' \
    -numReduceTasks 0 \
    -file /home/hduser/RunHadoopJob.sh \
    -input  /user/hduser/input.txt \
    -output /user/hduser/output \
    -mapper RunHadoopJob.sh  \
    -verbose

填充输入文件text.txt:

Filler text for streaming job.

RunHadoopJob.sh

cp -Hr BinaryProgramFolder ./pics; #copy a sym link to your unpacked program folder into your pics directory.
cd ./pics;
./BinaryProgramFolder/BinaryProgramLauncScript.sh <params>; #lunch your program following the symlink to the programs folder, I also used a script to launch my bin program which was in the same folder as the launch script.

注意:您必须先将程序和图像放入jar存档,然后将它们复制到HDFS。使用hadoop fs -copyFromLocal ./<file location> ./<hadoop fs location>