¿Puedo leer varios archivos en un Spark Dataframe desde S3, pasando por los que no existen?

Me gustaría leer varios archivos de parquet en un dataframe desde S3. Actualmente, estoy usando el siguiente método para hacer esto:

files = ['s3a://dev/2017/01/03/data.parquet', 's3a://dev/2017/01/02/data.parquet'] df = session.read.parquet(*files) 

Esto funciona si todos los archivos existen en S3, pero me gustaría solicitar que se cargue una lista de archivos en un dataframe sin interrupciones cuando no existan algunos de los archivos de la lista. En otras palabras, me gustaría que sparkSql cargue tantos archivos como encuentre en el dataframe y devuelva este resultado sin quejarme. es posible?

Sí, es posible si cambia el método de especificar la entrada al patrón de hadoop glob, por ejemplo:

 files = 's3a://dev/2017/01/{02,03}/data.parquet' df = session.read.parquet(files) 

Puedes leer más sobre los patrones en Hadoop javadoc .

Pero, en mi opinión, esta no es una forma elegante de trabajar con datos particionados por tiempo (por día en su caso). Si puedes renombrar directorios como este:

  • s3a://dev/2017/01/03/data.parquet -> s3a://dev/day=2017-01-03/data.parquet
  • s3a://dev/2017/01/02/data.parquet -> s3a://dev/day=2017-01-02/data.parquet

luego puede aprovechar el esquema de partición de chispa y leer datos al:

 session.read.parquet('s3a://dev/') \ .where(col('day').between('2017-01-02', '2017-01-03') 

De esta manera también se omitirán los directorios vacíos / no existentes. El day columna Additionall aparecerá en su dataframe (será cadena en spark <2.1.0 y datetime en spark> = 2.1.0), por lo que sabrá en qué directorio existe cada registro.

¿Puedo observar que, como la coincidencia de patrón global incluye una caminata de árbol recursiva completa y la coincidencia de patrón de las rutas, es un asesino de rendimiento absoluto contra los almacenes de objetos, especialmente S3? Hay un atajo especial en la chispa para reconocer cuando su camino no tiene ningún carácter global, en cuyo caso hace una elección más eficiente.

De manera similar, un árbol de partición muy profundo, como en ese diseño de año / mes / día, significa muchos directorios escaneados, a un costo de cientos de milis (o peor) por directorio.

El diseño sugerido por Mariusz debería ser mucho más eficiente, ya que se trata de un árbol de directorios más plano: su conmutación debería tener un mayor impacto en el rendimiento en los almacenes de objetos que los sistemas de archivos reales.