私はClouderaのhadoop(0.20.2)を使用しています。このバージョンでは、ファイルシステムにファイルを配置したが、ディレクトリ構造が存在しない場合、親ディレクトリが自動的に作成されました。
たとえば、hdfsにディレクトリがなく、次のように入力した場合:
hadoop fs -put myfile.txt /some/non/existing/path/myfile.txt
すべてのディレクトリを作成します:some、non、existingおよびpathそしてそこにファイルを置きます。
現在、hadoop(2.2.0)の新しい製品では、このディレクトリの自動作成は行われていません。上記と同じコマンドを実行すると:
put: `/ some/non/existing/path/':そのようなファイルまたはディレクトリはありません
hadoop fs -mkdir最初に、putごとに回避する方法がありますが、これはうまく機能しません。
これは構成可能ですか?何かアドバイス?
hadoop fs -mkdir -p <path>
を使用する必要があります
hadoop fs ...
は推奨されていません。代わりにhdfs dfs -mkdir ....
を使用してください
ファイルをhdfsの非拡張ディレクトリに配置するには、2段階のプロセスが必要です。 @ rt-vyborが述べたように、mkdirに '-p'オプションを使用して、欠落している複数のパス要素を作成します。ただし、OPがファイルをhdfsに配置する方法を尋ねたため、次の例もhdfs putを実行し、(オプションで)putが成功したことを確認し、条件付きでローカルコピーを削除できることに注意してください。
まず、hdfsに関連するディレクトリパスを作成してから、ファイルをhdfsに配置します。 hdfsに配置する前に、ファイルが存在することを確認する必要があります。また、ファイルがhdfsに正常に配置されたことを記録/表示することもできます。以下は、すべてのステップを組み合わせたものです。
fn=myfile.txt
if [ -f $fn ] ; then
bfn=`basename $fn` #trim path from filename
hdfs dfs -mkdir -p /here/is/some/non/existant/path/in/hdfs/
hdfs dfs -put $fn /here/is/some/non/existant/path/in/hdfs/$bfn
hdfs dfs -ls /here/is/some/non/existant/path/in/hdfs/$bfn
success=$? #check whether file landed in hdfs
if [ $success ] ; then
echo "remove local copy of file $fn"
#rm -f $fn #uncomment if you want to remove file
fi
fi
これをシェルスクリプトに変換し、Hadoopパスとファイルのリストを取得できます(パスを1回だけ作成します)。
#!/bin/bash
hdfsp=${1}
shift;
hdfs dfs -mkdir -p /here/is/some/non/existant/path/in/hdfs/
for fn in $*; do
if [ -f $fn ] ; then
bfn=`basename $fn` #trim path from filename
hdfs dfs -put $fn /here/is/some/non/existant/path/in/hdfs/$bfn
hdfs dfs -ls /here/is/some/non/existant/path/in/hdfs/$bfn >/dev/null
success=$? #check whether file landed in hdfs
if [ $success ] ; then
echo "remove local copy of file $fn"
#rm -f $fn #uncomment if you want to remove file
fi
fi
done