Hadoopへのインプットはふつう、ディレクトリかファイルの指定で行う。

しかし以下のような場合にどうするか。

  • 複数のディレクトリの下にあるファイルをhadoopに処理させたいとき。
  • 特定拡張子のファイルのみをhadoopに処理させたいとき。

実はワイルドカードが使えるので、それで解決。
以下、hadoop-1.0.0で確認。

ケース1:複数ディレクトリの下に処理対象ファイルがある場合。

top-+-dir1-file1
    |     -file2
    |     -file3
    |
    +-dir2-file4
          -file5
          -file6

以上のような状態でhadoopへのinputにtopを指定すると、hadoopはdir1をファイルとして処理しようとし、失敗する。
たとえばこのように。

13/11/13 22:26:03 ERROR security.UserGroupInformation: PriviledgedActionException as:hadoop cause:java.io.IOException: Not a file: hdfs://namenode/user/hadoop/top/dir1
13/11/13 22:26:03 ERROR streaming.StreamJob: Error Launching job : Not a file:
hdfs://namenode/user/hadoop/top/dir1
Streaming Job Failed!

このような場合には、top/*と指定してあげればよい。
たとえばこのように。

$ hadoop jar ${HADOOP_PREFIX}/contrib/streaming/hadoop-streaming-1.0.0.jar \
-D mapred.reduce.tasks=0 \
-input top/*  \
-output sampleoutput \
-mapper /home/hadoop/map.py \
-file /home/hadoop/map.py

ケース2:特定のファイルのみ処理したい場合

たとえば以下のdir3で.txtのみを処理したい場合。

-dir3-file1.txt
     -file2.bin
     -file3.txt

-input dir3/*.txtとすればよい。

ケース3:ケース1/2の複合ケース

top-+-dir4-file1.txt
    |     -file2.bin
    |     -file3.txt
    |
    +-dir5-file4.txt
          -file5.bin
          -file6.txt

合わせ技でtop/*/*.txtと指定すればよい。