web-dev-qa-db-fra.com

Spark textFile vs wholeTextFiles

Je comprends la théorie de base de la partition de génération textFile pour chaque fichier, tandis que wholeTextFiles génère un RDD de valeurs de paires, où la clé est le chemin de chaque fichier, la valeur correspond au contenu de chaque fichier. 

Maintenant, d’un point de vue technique, quelle est la différence entre: 

val textFile = sc.textFile("my/path/*.csv", 8)
textFile.getNumPartitions

et 

val textFile = sc.wholeTextFiles("my/path/*.csv",8)
textFile.getNumPartitions

Dans les deux méthodes, je génère 8 partitions. Alors, pourquoi devrais-je utiliser wholeTextFiles en premier lieu, et quel est son bénéfice par rapport à textFile

5
Dan

Comme vous l'avez dit, la principale différence est que textFile renverra un RDD avec chaque ligne en tant qu'élément, tandis que wholeTextFiles renverra un PairRDD avec la clé correspondant au chemin du fichier. S'il n'est pas nécessaire de séparer les données en fonction du fichier, utilisez simplement textFile.

Lors de la lecture de fichiers non compressés avec textFile, les données seront divisées en tronçons de 32 Mo. Ceci est avantageux du point de vue de la mémoire. Cela signifie également que l'ordre des lignes est perdu. Si l'ordre doit être conservé, alors wholeTextFiles doit être utilisé.

wholeTextFiles lit l'intégralité du contenu d'un fichier à la fois, il ne sera ni partiellement déversé sur le disque ni partiellement nettoyé. Chaque fichier sera traité par un noyau et les données pour chaque fichier seront une seule machine, ce qui rendra plus difficile la répartition de la charge. 

13
Shaido

textFile générer une partition pour chaque fichier, alors que wholeTextFiles génère un RDD de valeurs de paires

Ce n'est pas exact:

  1. textFile charge un ou plusieurs fichiers, avec chaque line en tant que record dans le RDD résultant. Un fichier unique peut être divisé en plusieurs partitions s'il est suffisamment volumineux (dépend du nombre de partitions demandées, du nombre de partitions par défaut de Spark et du système de fichiers sous-jacent). Lors du chargement de plusieurs fichiers à la fois, cette opération "perd" la relation entre un enregistrement et le fichier qui le contient - c’est-à-dire qu’il n’ya aucun moyen de savoir quel fichier contient quelle ligne. L'ordre des enregistrements dans le RDD suivra l'ordre alphabétique des fichiers et l'ordre des enregistrements dans les fichiers (l'ordre n'est pas "perdu").

  2. wholeTextFiles préserve la relation entre les données et les fichiers qui les contiennent en chargeant les données dans une PairRDD avec un enregistrement par fichier d'entrée . L'enregistrement aura la forme (fileName, fileContent). Cela signifie que charger des fichiers volumineux est risqué (peut entraîner de mauvaises performances ou OutOfMemoryError car chaque fichier sera nécessairement stocké sur un seul nœud). Le partitionnement est effectué en fonction de la saisie de l'utilisateur ou de la configuration de Spark, avec plusieurs fichiers potentiellement chargés dans une seule partition.

De manière générale, textFile sert au cas d'utilisation courant consistant à simplement charger un grand nombre de données (quelle que soit la manière dont elles sont décomposées en fichiers). readWholeFiles ne devrait être utilisé que si vous avez réellement besoin de connaître le nom du fichier d'origine de chaque enregistrement, et si vous savez que tous les fichiers sont suffisamment petits. 

10
Tzach Zohar

A partir de Spark2.1.1, voici le code pour textFile.

def textFile(
  path: String,
  minPartitions: Int = defaultMinPartitions): RDD[String] = withScope {
assertNotStopped()

hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],
  minPartitions).map(pair => pair._2.toString).setName(path)  }

Qui utilise en interne hadoopFile pour lire les fichiers locaux, les fichiers HDFS et S3 en utilisant un modèle tel que file://, hdfs:// et s3a://

Où comme WholeTextFile la syntaxe est comme ci-dessous

def wholeTextFiles(
  path: String,
  minPartitions: Int = defaultMinPartitions): RDD[(String, String)] = withScope 

Si nous observons que la syntaxe des deux méthodes est la même, mais textfile est utile pour lire les fichiers, où wholeTextFiles est utilisé pour lire les répertoires des petits fichiers. Cependant, nous pouvons également utiliser des fichiers plus volumineux, mais les performances peuvent en pâtir.
Ainsi, lorsque vous voulez traiter des fichiers volumineux, textFile est la meilleure option, alors que si nous voulons traiter avec le répertoire des fichiers plus petits, wholeTextFile est préférable.

1
Sainagaraju Vaduka
  1. textfile () lit un fichier texte et retourne un RDD de chaînes. Par exemple, sc.textFile ("/ mydata.txt") créera un RDD dans lequel chaque ligne individuelle est un élément.

  2. wholeTextFile () lit un répertoire de fichiers texte et renvoie pairRDD . Par exemple, s'il y a peu de fichiers dans un répertoire, la méthode wholeTextFile () créera une paire RDD avec le nom de fichier et le chemin d'accès, et la valeur étant le fichier entier. en tant que chaîne.

0
KayV