Comment charger un fichier local dans sc.textFile, au lieu de HDFS


100

Je suis le grand tutoriel sur les étincelles

donc j'essaye à 46m: 00s de charger le README.mdmais échoue à ce que je fais est ceci:

$ sudo docker run -i -t -h sandbox sequenceiq/spark:1.1.0 /etc/bootstrap.sh -bash
bash-4.1# cd /usr/local/spark-1.1.0-bin-hadoop2.4
bash-4.1# ls README.md
README.md
bash-4.1# ./bin/spark-shell
scala> val f = sc.textFile("README.md")
14/12/04 12:11:14 INFO storage.MemoryStore: ensureFreeSpace(164073) called with curMem=0, maxMem=278302556
14/12/04 12:11:14 INFO storage.MemoryStore: Block broadcast_0 stored as values in memory (estimated size 160.2 KB, free 265.3 MB)
f: org.apache.spark.rdd.RDD[String] = README.md MappedRDD[1] at textFile at <console>:12
scala> val wc = f.flatMap(l => l.split(" ")).map(word => (word, 1)).reduceByKey(_ + _)
org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: hdfs://sandbox:9000/user/root/README.md
    at org.apache.hadoop.mapred.FileInputFormat.singleThreadedListStatus(FileInputFormat.java:285)

comment puis-je charger ça README.md?

Réponses:


177

Essayez de spécifier explicitement sc.textFile("file:///path to the file/"). L'erreur se produit lorsque l'environnement Hadoop est défini.

SparkContext.textFile appelle en interne org.apache.hadoop.mapred.FileInputFormat.getSplits, qui à son tour utilise org.apache.hadoop.fs.getDefaultUrisi le schéma est absent. Cette méthode lit le paramètre "fs.defaultFS" de la configuration Hadoop. Si vous définissez la variable d'environnement HADOOP_CONF_DIR, le paramètre est généralement défini comme "hdfs: // ..."; sinon "fichier: //".


Savez-vous comment faire cela avec Java? Je ne vois pas de méthode. Je trouve très frustrant qu'il n'y ait pas de moyen facile de donner un chemin pour charger un fichier à partir d'un système de fichiers simple.
Brad Ellis

me répondre. Il existe un commutateur --file que vous passez avec le spark-submit. Ainsi, le chemin du fichier peut être codé en dur ou votre configuration est configurée pour l'application, mais vous signalez également ce chemin. lorsque vous soumettez afin que les exécuteurs puissent voir le chemin.
Brad Ellis

24

La réponse de gonbe est excellente. Mais je veux quand même mentionner que file:///= ~/../../, non $SPARK_HOME. J'espère que cela pourrait faire gagner du temps aux novices comme moi.


4
file:///est le dossier racine du système de fichiers vu par la machine virtuelle Java en cours d'exécution, et non deux niveaux au-dessus du dossier de base. Le format URI tel que spécifié dans la RFC 8089 est file://hostname/absolute/path. Dans le cas local, le hostnamecomposant (autorité) est vide.
Hristo Iliev

17

Bien que Spark prenne en charge le chargement de fichiers à partir du système de fichiers local, il nécessite que les fichiers soient disponibles sur le même chemin sur tous les nœuds de votre cluster.

Certains systèmes de fichiers réseau, comme NFS, AFS et la couche NFS de MapR, sont exposés à l'utilisateur comme un système de fichiers normal.

Si vos données sont déjà dans l'un de ces systèmes, vous pouvez les utiliser comme entrée en spécifiant simplement un fichier: // chemin; Spark le gérera tant que le système de fichiers est monté sur le même chemin sur chaque nœud. Chaque nœud doit avoir le même chemin

 rdd = sc.textFile("file:///path/to/file")

Si votre fichier n'est pas déjà sur tous les nœuds du cluster, vous pouvez le charger localement sur le pilote sans passer par Spark, puis appeler parallelize pour distribuer le contenu aux nœuds de calcul

Veillez à mettre file: // devant et à utiliser "/" ou "\" selon OS.


1
Existe-t-il un moyen pour Spark de copier automatiquement les données de son répertoire $ SPARK_HOME vers tous les nœuds informatiques. Ou avez-vous besoin de le faire manuellement?
Matthias

où le code source Spark gère-t-il différents formats de système de fichiers?
Saher Ahwal

12

Il vous suffit de spécifier le chemin du fichier comme "fichier: /// répertoire / fichier"

exemple:

val textFile = sc.textFile("file:///usr/local/spark/README.md")

12

Attention:

Assurez-vous que vous exécutez spark en mode local lorsque vous chargez des données à partir de local ( sc.textFile("file:///path to the file/")) ou vous obtiendrez une erreur comme celle-ci Caused by: java.io.FileNotFoundException: File file:/data/sparkjob/config2.properties does not exist. Parce que les exécuteurs exécutés sur différents workers ne trouveront pas ce fichier dans son chemin local.


11

Si le fichier se trouve dans votre nœud maître Spark (par exemple, en cas d'utilisation d'AWS EMR), lancez d'abord le spark-shell en mode local.

$ spark-shell --master=local
scala> val df = spark.read.json("file:///usr/lib/spark/examples/src/main/resources/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

scala> df.show()
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+

Sinon, vous pouvez d'abord copier le fichier sur HDFS à partir du système de fichiers local, puis lancer Spark dans son mode par défaut (par exemple, YARN en cas d'utilisation d'AWS EMR) pour lire le fichier directement.

$ hdfs dfs -mkdir -p /hdfs/spark/examples
$ hadoop fs -put /usr/lib/spark/examples/src/main/resources/people.json /hdfs/spark/examples
$ hadoop fs -ls /hdfs/spark/examples
Found 1 items
-rw-r--r--   1 hadoop hadoop         73 2017-05-01 00:49 /hdfs/spark/examples/people.json

$ spark-shell
scala> val df = spark.read.json("/hdfs/spark/examples/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

scala> df.show()
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+

9

J'ai un fichier appelé NewsArticle.txt sur mon bureau.

Dans Spark, j'ai tapé:

val textFile= sc.textFile(“file:///C:/Users/582767/Desktop/NewsArticle.txt”)

J'avais besoin de changer tous les caractères \ à / pour le chemin du fichier.

Pour tester si cela fonctionnait, j'ai tapé:

textFile.foreach(println)

J'utilise Windows 7 et je n'ai pas installé Hadoop.


5

Cela a été discuté dans la liste de diffusion Spark, et veuillez vous référer à ce courrier .

Vous devez utiliser hadoop fs -put <localsrc> ... <dst>copier le fichier dans hdfs:

${HADOOP_COMMON_HOME}/bin/hadoop fs -put /path/to/README.md README.md

5

Cela m'est arrivé avec Spark 2.3 avec Hadoop également installé dans le répertoire de base de l'utilisateur commun "hadoop". Puisque Spark et Hadoop ont été installés dans le même répertoire commun, Spark considère par défaut le schéma comme hdfs, et commence à rechercher les fichiers d'entrée sous hdfs comme spécifié par fs.defaultFSdans Hadoop core-site.xml. Dans de tels cas, nous devons spécifier explicitement le schéma comme file:///<absoloute path to file>.


0

Voici la solution pour cette erreur que j'obtenais sur le cluster Spark qui est hébergé dans Azure sur un cluster Windows:

Chargez le fichier brut HVAC.csv, analysez-le à l'aide de la fonction

data = sc.textFile("wasb:///HdiSamples/SensorSampleData/hvac/HVAC.csv")

Nous utilisons (wasb: ///) pour permettre à Hadoop d'accéder au fichier de stockage du blog Azure et les trois barres obliques sont une référence relative au dossier du conteneur de nœud en cours d'exécution.

Par exemple: Si le chemin d'accès à votre fichier dans l'Explorateur de fichiers dans le tableau de bord du cluster Spark est:

sflcc1 \ sflccspark1 \ HdiSamples \ SensorSampleData \ hvac

Donc, pour décrire le chemin, c'est comme suit: sflcc1: est le nom du compte de stockage. sflccspark: est le nom du nœud du cluster.

Nous nous référons donc au nom du nœud de cluster actuel avec les trois barres obliques relatives.

J'espère que cela t'aides.


0

Si vous essayez de lire le fichier sous forme HDFS. essayer de définir le chemin dans SparkConf

 val conf = new SparkConf().setMaster("local[*]").setAppName("HDFSFileReader")
 conf.set("fs.defaultFS", "hdfs://hostname:9000")

Veuillez ajouter une indentation de 4 espaces / tabulation à votre code afin qu'il soit formaté en tant que code. Meilleures salutations
YakovL

0

Vous n'avez pas besoin d'utiliser sc.textFile (...) pour convertir des fichiers locaux en dataframes. L'une des options est de lire un fichier local ligne par ligne, puis de le transformer en ensemble de données Spark. Voici un exemple de machine Windows en Java:

StructType schemata = DataTypes.createStructType(
            new StructField[]{
                    createStructField("COL1", StringType, false),
                    createStructField("COL2", StringType, false),
                    ...
            }
    );

String separator = ";";
String filePath = "C:\\work\\myProj\\myFile.csv";
SparkContext sparkContext = new SparkContext(new SparkConf().setAppName("MyApp").setMaster("local"));
JavaSparkContext jsc = new JavaSparkContext (sparkContext );
SQLContext sqlContext = SQLContext.getOrCreate(sparkContext );

List<String[]> result = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
    String line;
    while ((line = br.readLine()) != null) {
      String[] vals = line.split(separator);
      result.add(vals);
    }
 } catch (Exception ex) {
       System.out.println(ex.getMessage());
       throw new RuntimeException(ex);
  }
  JavaRDD<String[]> jRdd = jsc.parallelize(result);
  JavaRDD<Row> jRowRdd = jRdd .map(RowFactory::create);
  Dataset<Row> data = sqlContext.createDataFrame(jRowRdd, schemata);

Vous pouvez maintenant utiliser dataframe datadans votre code.


0

J'ai essayé ce qui suit et cela a fonctionné à partir de mon système de fichiers local. Fondamentalement, Spark peut lire à partir du chemin local, HDFS et AWS S3

listrdd=sc.textFile("file:////home/cloudera/Downloads/master-data/retail_db/products")

-6

essayer

val f = sc.textFile("./README.md")

scala> val f = sc.textFile("./README.md") 14/12/04 12:54:33 INFO storage.MemoryStore: ensureFreeSpace(81443) called with curMem=164073, maxMem=278302556 14/12/04 12:54:33 INFO storage.MemoryStore: Block broadcast_1 stored as values in memory (estimated size 79.5 KB, free 265.2 MB) f: org.apache.spark.rdd.RDD[String] = ./README.md MappedRDD[5] at textFile at <console>:12 scala> val wc = f.flatMap(l => l.split(" ")).map(word => (word, 1)).reduceByKey(_ + _) org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: hdfs://sandbox:9000/user/root/README.md at
Jas

Can you do a pwdon the bash shellbash-4.1#
Soumya Simanta

bash-4.1 # pwd /usr/local/spark-1.1.0-bin-hadoop2.4
Jas

Cela fonctionne pour moi sur spark sans hadoop / hdfs. Cependant, cela ne semble pas fonctionner pour l'OP, car il leur a donné un vidage d'erreur.
Paul
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.