web-dev-qa-db-fra.com

Comment lire plusieurs fichiers texte dans un seul RDD?

Je veux lire un tas de fichiers texte depuis un emplacement hdfs et effectuer un mappage dessus en une itération à l'aide de spark.

JavaRDD<String> records = ctx.textFile(args[1], 1); est capable de lire un seul fichier à la fois.

Je veux lire plus d'un fichier et les traiter comme un seul RDD. Comment? 

154
user3705662

Vous pouvez spécifier des répertoires entiers, utiliser des caractères génériques et même des fichiers CSV de répertoires et de caractères génériques. Par exemple.:

sc.textFile("/my/dir1,/my/paths/part-00[0-5]*,/another/dir,/a/specific/file")

Comme Nick Chammas le fait remarquer, ceci est une exposition de FileInputFormat de Hadoop et cela fonctionne donc également avec Hadoop (et Scalding).

266
samthebest

Utilisez union comme suit:

val sc = new SparkContext(...)
val r1 = sc.textFile("xxx1")
val r2 = sc.textFile("xxx2")
...
val rdds = Seq(r1, r2, ...)
val bigRdd = sc.union(rdds)

Alors la bigRdd est le RDD avec tous les fichiers.

29
cloud

Vous pouvez utiliser un seul appel textFile pour lire plusieurs fichiers. Scala:

sc.textFile(','.join(files)) 
26
Joseph

Vous pouvez utiliser ceci 

Vous pouvez d’abord obtenir un tampon/une liste de chemins S3: 

import scala.collection.JavaConverters._
import Java.util.ArrayList
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.model.ObjectListing
import com.amazonaws.services.s3.model.S3ObjectSummary
import com.amazonaws.services.s3.model.ListObjectsRequest

def listFiles(s3_bucket:String, base_prefix : String) = {
    var files = new ArrayList[String]

    //S3 Client and List Object Request
    var s3Client = new AmazonS3Client();
    var objectListing: ObjectListing = null;
    var listObjectsRequest = new ListObjectsRequest();

    //Your S3 Bucket
    listObjectsRequest.setBucketName(s3_bucket)

    //Your Folder path or Prefix
    listObjectsRequest.setPrefix(base_prefix)

    //Adding s3:// to the paths and adding to a list
    do {
      objectListing = s3Client.listObjects(listObjectsRequest);
      for (objectSummary <- objectListing.getObjectSummaries().asScala) {
        files.add("s3://" + s3_bucket + "/" + objectSummary.getKey());
      }
      listObjectsRequest.setMarker(objectListing.getNextMarker());
    } while (objectListing.isTruncated());

    //Removing Base Directory Name
    files.remove(0)

    //Creating a Scala List for same
    files.asScala
  }

Maintenant, passez cet objet List au code suivant, remarque: sc est un objet de SQLContext

var df: DataFrame = null;
  for (file <- files) {
    val fileDf= sc.textFile(file)
    if (df!= null) {
      df= df.unionAll(fileDf)
    } else {
      df= fileDf
    }
  }

Maintenant, vous avez un dernier RDD unifié, à savoir df

Facultatif, et vous pouvez également le repartitionner dans un seul BigRDD 

val files = sc.textFile(filename, 1).repartition(1)

Le repartitionnement fonctionne toujours: D

8
Murtaza Kanchwala

vous pouvez utiliser 

JavaRDD<String , String> records = sc.wholeTextFiles("path of your directory")

ici, vous obtiendrez le chemin de votre fichier et le contenu de ce fichier. afin que vous puissiez effectuer toute action d'un fichier entier à un moment qui enregistre les frais généraux 

3
Shubham Agrawal

Toutes les réponses sont correctes avec sc.textFile

Je me demandais pourquoi pas wholeTextFiles Par exemple, dans ce cas ...

val minPartitions = 2
val path = "/pathtohdfs"
    sc.wholeTextFiles(path,minPartitions)
      .flatMap{case (path, text) 
    ...

une des limites est que nous devons charger de petits fichiers, sans quoi les performances seront mauvaises et risquent d’entraîner un MOO.

Remarque : 

  • Le fichier entier doit correspondre à la mémoire
  • Bon pour les formats de fichiers qui ne sont PAS divisibles par ligne ... tels que les fichiers XML

Référence supplémentaire à visiter

2
Ram Ghadiyaram

Il existe une solution propre simple disponible. Utilisez la méthode wholeTextFiles (). Cela prendra un répertoire et forme une paire clé-valeur. Le RDD retourné sera une paire RDD. Retrouvez ci-dessous la description de Spark docs :

SparkContext.wholeTextFiles vous permet de lire un répertoire contenant plusieurs petits fichiers texte et les renvoie sous forme de paires (nom de fichier, contenu). Ceci est en contraste avec textFile, qui renverrait un enregistrement par ligne dans chaque fichier

1
Harikrishnan Ck

TRY THIS Interface utilisée pour écrire un DataFrame sur des systèmes de stockage externes (tels que des systèmes de fichiers, des magasins de valeurs-clés, etc.). Utilisez DataFrame.write () pour y accéder.

Nouveau dans la version 1.4.

csv (chemin d'accès, mode = None, compression = None, sep = None, quote = None, escape = None, en-tête = None, nullValue = None, escapeQuotes = None, quoteAll = None, dateFormat = None, timestampFormat = None). .Enregistre le contenu du DataFrame au format CSV dans le chemin spécifié.

Paramètres: Path - chemin de tout système de fichiers pris en charge par Hadoop Mode – Spécifie le comportement de l'opération de sauvegarde lorsque des données existent déjà.

append: ajoute le contenu de ce DataFrame à des données existantes . écrase: écrase des données existantes .. ignore: ignore cette opération si les données existent déjà . erreur (cas par défaut): déclenche une exception si les données existent déjà . compression - codec de compression à utiliser lors de la sauvegarde dans un fichier. Cela peut être l’un des noms abrégés connus et insensibles à la casse (aucun, bzip2, gzip, lz4, snappy et deflate) . Sep - définit le caractère unique comme séparateur pour chaque champ et valeur. Si aucun est défini, il utilise la valeur par défaut, . Quote - définit le caractère unique utilisé pour échapper les valeurs entre guillemets où le séparateur peut faire partie de la valeur. Si la valeur par défaut est Aucun, il utilise la valeur par défaut, ". Si vous souhaitez désactiver les devis, vous devez définir une chaîne vide . Escape - définit le seul caractère utilisé pour échapper les guillemets dans une valeur déjà citée. Si Aucune n'est définie, elle utilise la valeur par défaut,\ EscapeQuotes - Indique si les valeurs contenant des guillemets doivent toujours être placées entre guillemets. Si aucune est définie, elle utilise la valeur par défaut, true, en échappant à toutes les valeurs contenant un caractère de guillemet. quoteAll - Indicateur signalant si toutes les valeurs doivent toujours être placées entre guillemets. Si la valeur est définie sur None, la valeur par défaut est false, mais uniquement les valeurs d'échappement contenant un caractère de citation header - écrit les noms des colonnes sous la forme Première ligne. Si aucun est défini, il utilise la valeur par défaut, false . nullValue - définit la représentation sous forme de chaîne d'une valeur null. Si aucun est défini, il utilise la valeur par défaut, chaîne vide . dateFormat - définit la chaîne qui indique un format de date.Les formats de date personnalisés suivent les formats de Ja va.text.SimpleDateFormat. Ceci s'applique au type de date. Si aucun n'est défini, il utilise la valeur par défaut, aaaa-MM-jj . TimestampFormat - définit la chaîne qui indique un format d'horodatage. Les formats de date personnalisés suivent les formats disponibles sur Java.text.SimpleDateFormat. Ceci s'applique au type d'horodatage. Si aucun n'est défini, il utilise la valeur par défaut, aaaa-MM-jj'T'HH: mm: ss.SSSZZ.

0
K Rakesh patra