scala - Spark textFile vs wholeTextFiles
apache-spark file-io (4)
textFile
genera partición para cada archivo, mientras quewholeTextFiles
genera un RDD de valores de par
Eso no es exacto:
-
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"). -
wholeTextFiles
preserva la relación entre los datos y los archivos que los contienen, cargando los datos en unPairRDD
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 oOutOfMemoryError
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
?
-
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.
-
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.