web-dev-qa-db-fra.com

Comment obtenir hadoop pour créer des répertoires s'ils n'existent pas

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?

18
owly

Maintenant, vous devriez utiliser hadoop fs -mkdir -p <path>

24
art-vybor

hadoop fs ... est obsolète, utilisez plutôt: hdfs dfs -mkdir .... 

3
aName

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
0
ChuckCottrill