scala apache-spark file-io

scala - Spark textFile vs wholeTextFiles



apache-spark file-io (4)

textFile genera partición para cada archivo, mientras que wholeTextFiles genera un RDD de valores de par

Eso no es exacto:

  1. textFile carga uno o más archivos, con cada línea como un registro en el RDD resultante. Un solo archivo podría dividirse en varias particiones si el archivo es lo suficientemente grande (depende de la cantidad de particiones solicitadas, la cantidad predeterminada de particiones de Spark y el sistema de archivos subyacente). Al cargar varios archivos a la vez, esta operación "pierde" la relación entre un registro y el archivo que lo contenía, es decir, no hay forma de saber qué archivo contenía qué línea. El orden de los registros en el RDD seguirá el orden alfabético de los archivos y el orden de los registros dentro de los archivos (el orden no se "pierde").

  2. wholeTextFiles preserva la relación entre los datos y los archivos que los contienen, cargando los datos en un PairRDD con un registro por archivo de entrada . El registro tendrá la forma (fileName, fileContent) . Esto significa que cargar archivos grandes es arriesgado (podría causar un mal rendimiento o OutOfMemoryError ya que cada archivo se almacenará necesariamente en un solo nodo). El particionamiento se realiza según la entrada del usuario o la configuración de Spark, con múltiples archivos potencialmente cargados en una sola partición.

En términos generales, textFile sirve para el caso de uso común de solo cargar una gran cantidad de datos (independientemente de cómo se desglosen en archivos). readWholeFiles solo debe usarse si realmente necesita conocer el nombre del archivo de origen de cada registro, y si sabe que todos los archivos son lo suficientemente pequeños.

Entiendo la teoría básica de la partición de generación de textFile de textFile para cada archivo, mientras que wholeTextFiles genera un RDD de valores de par, donde la clave es la ruta de cada archivo, el valor es el contenido de cada archivo.

Ahora, desde un punto de vista técnico, ¿cuál es la diferencia entre:

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

y

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

En ambos métodos estoy generando 8 particiones. Entonces, ¿por qué debería usar wholeTextFiles en primer lugar, y cuál es su beneficio sobre textFile ?


  1. archivo de texto () lee un archivo de texto y devuelve un RDD de cadenas. Por ejemplo, sc.textFile ("/ mydata.txt") creará RDD en el que cada línea individual es un elemento.

  2. wholeTextFile () lee un directorio de archivos de texto y devuelve pairRDD. Por ejemplo, si hay pocos archivos en un directorio, el método wholeTextFile () creará un par RDD con nombre de archivo y ruta como clave, y el valor será el archivo completo como cadena.


A partir de Spark2.1.1, a continuación se encuentra el código para 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) }

Que internamente usa hadoopFile para leer archivos locales, archivos HDFS y S3 usando el patrón como file:// , hdfs:// y s3a://

Donde como WholeTextFile la sintaxis es la siguiente

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

Si observamos que la sintaxis para ambos métodos es igual, pero el archivo de texto es útil para leer los archivos, mientras que en su totalidad se utilizan TextText para leer los directorios de archivos pequeños . Sin embargo, también podemos usar archivos más grandes, pero el rendimiento puede afectar.
Entonces, cuando desea tratar con archivos grandes, textFile es una mejor opción, mientras que si queremos tratar con el directorio de archivos más pequeños, wholeTextFile es mejor


La principal diferencia, como mencionó, es que textFile devolverá un RDD con cada línea como un elemento, mientras que wholeTextFiles devuelve un PairRDD con la clave como la ruta del archivo. Si no es necesario separar los datos según el archivo, simplemente use textFile .

Al leer archivos sin comprimir con textFile , dividirá los datos en fragmentos de 32 MB. Esto es ventajoso desde una perspectiva de memoria. Esto también significa que se pierde el orden de las líneas, si el orden se debe preservar, se debe utilizar wholeTextFiles .

wholeTextFiles leerá el contenido completo de un archivo a la vez, no se derramará parcialmente en el disco ni se recolectará basura en parte. Cada archivo será manejado por un núcleo y los datos para cada archivo serán una sola máquina, lo que dificultará la distribución de la carga.