J'utilise le hadoop de Cloudera (0.20.2). Avec cette version, si je mets un fichier dans le système de fichiers mais que la structure de répertoires n’existait pas, les répertoires parents étaient automatiquement créés:
Donc, par exemple, si je n'avais pas de répertoires dans hdfs et si je tapais:
hadoop fs -put myfile.txt /some/non/existing/path/myfile.txt
Il créerait tous les répertoires: certains, non, existants et chemin et y placerait le fichier.
Maintenant, avec une nouvelle offre de hadoop (2.2.0), cette création automatique de répertoires n’est plus en cours . La même commande ci-dessus donne:
put: `/ some/non/existing/path/': Aucun fichier ou répertoire de ce type
J'ai une solution de contournement à faire hadoop fs -mkdir premier, pour chaque put, mais cela ne va pas bien performer.
Est-ce configurable? Un conseil?
Maintenant, vous devriez utiliser hadoop fs -mkdir -p <path>
hadoop fs ...
est obsolète, utilisez plutôt: hdfs dfs -mkdir ....
Placer un fichier dans un répertoire non existant dans hdfs nécessite un processus en deux étapes. Comme @ rt-vybor a déclaré, utilisez l'option '-p' de mkdir pour créer plusieurs éléments de chemin manquants. Mais puisque l'OP a demandé comment placer le fichier dans des fichiers hdfs, les opérations suivantes effectuent également la commande hdfs et notez que vous pouvez également (éventuellement) vérifier que la vente a réussi et supprimer conditionnellement la copie locale.
Commencez par créer le chemin de répertoire approprié dans hdfs, puis placez le fichier dans hdfs. Vous voulez vérifier que le fichier existe avant de le placer dans hdfs. Et vous voudrez peut-être vous connecter/montrer que le fichier a bien été placé dans hdfs. Ce qui suit combine toutes les étapes.
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
Et vous pouvez transformer cela en un script Shell, en prenant un chemin d'accès hadoop et une liste de fichiers (ne créez qu'un seul chemin),
#!/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