1

以前にこれと同様の質問をしましたが、いくつかの調査を行った後、何が起こっているのかをよりよく理解していますが、他の人が私のアプローチに代わる解決策を持っているかどうかを確認したいと思います.

問題

hdfs で大量の非常に大きなファイルを gzip する Hadoop ストリーミング ジョブを作成しようとしているとします。 Hadoop ストリーミング ガイドでは、ファイルを hdfs からローカル ノードにコピーするマッパーを作成し、作業を行ってから、ファイルを hdfs にコピーして戻すことを提案しています。これは、インラインで説明されているいくつかの追加コードを含む小さなスクリプトで、もう少し基本的なタスクを実行します:単にファイルの名前を変更するだけです

スクリプト

#!/bin/bash

# Remove "s from the environment variable to work around a stupid bug in hadoop.
export HADOOP_CLIENT_OPTS=`echo $HADOOP_CLIENT_OPTS | tr -d '"'`

# Get just the size of the file on the local disk.
function localSize() {
 ls -l $1 | awk '{ print $5 }'
}

# Get just the size of the file on HDFS.  Oddly, the first command includes a 
# new line at the start of the size, so we remove it by using a substring.
function hdfsSize() {
 s=`hadoop dfs -ls /some/other/path/$1 | awk '{ print $5 }'`
 echo ${s:1}
}

while read line
do
 ds=ourFile.dat
 # Copy the file from HDFS to local disk.
 hadoop dfs -copyToLocal /path/to/some/large/file/$ds $ds
 # Spin until the file is fully copied.
 while [ ! -f $ds ]
 do 
  echo "spin"
  sleep 1 
 done

 # Delete the renamed version of the file and copy it.
 hadoop dfs -rm /some/other/path/blah
 hadoop dfs -copyFromLocal $ds /some/other/path/blah
 # Print out the sizes of the file on local disk and hdfs, they *should* be equal
 localSize $ds
 hdfsSize blah
 # If they aren't equal, spin until they are.
 while [ "`localSize $ds`" != "`hdfsSize blah`" ]
 do
  echo "copy spin"
  sleep 1
 done
 # Print out the file size at the end, just for fun.
 hadoop dfs -ls /some/other/path/blah
done

出力

スクリプトを実行すると、この出力が得られます

spin
spin
spin
Deleted hdfs://kracken:54310/some/other/path/blah
200890778
67108864
copy spin
Found 1 items   
-rw-r--r--   3 hadoop supergroup  200890778 2011-10-06 16:00 /home/stevens35/blah

問題

との出力からわかるように、関連するファイルの転送が完了する前に と が戻ってきているように見えhadoop dfs -copyToLocalます。私の推測では、Hadoop ストリーミング jvm はコマンドによって作成されたスレッドを採用しているため、ファイル転送スレッドは終了しても実行され続けますが、これは単なる推測です。これは、ファイルが大きく、最後のファイルのコピーが完了する前に Hadoop ストリーミングが終了する場合に特に厄介です。ファイル転送が途中で終了し、HDFS に部分的なファイルが残っているようです。私のこのハックは、少なくともファイルのコピーが完了することを保証するようです。hadoop dfs -copyFromLocalspincopy spinhadoop dfshadoop dfs

Cloudera の Hadoop バージョン 0.20.2+737 を使用していることに注意してください。

誰かがこの問題に遭遇しましたか? どのような代替回避策を見つけましたか? また、この問題は Hadoop の新しいリリースで修正されていますか?

4

0 に答える 0