JP

5 de fev de 20234 min

Diferenças entre os modes FAILFAST, PERMISSIVE e DROPMALFORMED em Spark Dataframes

Atualizado: 11 de mar de 2023

Existem algumas diferenças entre eles e vamos descobrir neste post. O parâmetro mode permite passar como valor, formas de validar Dataframes visando a qualidade dos dados.

Neste post vamos criar um Dataframe utilizando PySpark e comparar as diferenças entre esses três tipos de mode, são eles:

  • PERMISSIVE

  • DROPMALFORMED

  • FAILFAST

Conteúdo do arquivo CSV

Para este post, usaremos como exemplo um arquivo CSV contendo alguns registros variados, dentre eles, registros corrompidos. A definição de registros corrompidos para este contexto é que, para a coluna engines adicionamos alguns registros com tipos diferentes do que serão definidos no esquema.

Neste caso, no esquema, a coluna engines será definida como Integer mas no conteúdo abaixo, temos alguns registro com valores do tipo String.

"type","country","city","engines","first_flight","number_built"
 
"Airbus A220","Canada","Calgary",2,2013-03-02,179
 
"Airbus A220","Canada","Calgary","two",2013-03-02,179
 
"Airbus A220","Canada","Calgary",2,2013-03-02,179
 
"Airbus A320","France","Lyon","two",1986-06-10,10066
 
"Airbus A330","France","Lyon","two",1992-01-02,1521
 
"Boeing 737","USA","New York","two",1967-08-03,10636
 
"Boeing 737","USA","New York","two",1967-08-03,10636
 
"Boeing 737","USA","New York",2,1967-08-03,10636
 
"Airbus A220","Canada","Calgary",2,2013-03-02,179

Vamos começar criando um Dataframe simples que irá carregar dados do arquivo CSV contendo os registros acima, vamos supor que o conteúdo acima seja de um arquivo chamado avioes.csv. Para modelar o conteúdo, também estamos criando um esquema que nos permitirá validar os dados.

Criando um Dataframe usando o mode PERMISSIVE

O mode PERMISSIVE define valores de campos como nulos quando registros corrompidos são detectados para aquela coluna. Por padrão, se você não especificar nenhum valor para o parâmetro mode, Spark definirá o valor PERMISSIVE.

from pyspark.sql import SparkSession
 
from pyspark.sql.types import StructType, StructField, StringType, IntegerType
 

 
if __name__ == "__main__":
 

 
spark = SparkSession.builder \
 
.master("local[1]") \
 
.appName("spark-app") \
 
.getOrCreate()
 

 
schema = StructType([
 
StructField("TYPE", StringType()),
 
StructField("COUNTRY", StringType()),
 
StructField("CITY", StringType()),
 
StructField("ENGINES", IntegerType()),
 
StructField("FIRST_FLIGHT", StringType()),
 
StructField("NUMBER_BUILT", IntegerType())
 
])
 

 
read_df = spark.read \
 
.option("header", "true") \
 
.option("mode", "PERMISSIVE") \
 
.format("csv") \
 
.schema(schema) \
 
.load("airplanes.csv")
 

 
read_df.show(10)

Resultado utilizando PERMISSIVE mode

Perceba que para a colune ENGINES que possui registros que não seguem o padrão de tipagem definido, foram convertidas para o valor null.


Criando um Dataframe usando o mode DROPMALFORMED

O mode DROPMALFORMED ignora registros corrompidos. O que significa que, se você escolher este tipo de mode, os registros corrompidos não serão listados.

from pyspark.sql import SparkSession
 
from pyspark.sql.types import StructType, StructField, StringType, IntegerType
 

 
if __name__ == "__main__":
 

 
spark = SparkSession.builder \
 
.master("local[1]") \
 
.appName("spark-app") \
 
.getOrCreate()
 

 
schema = StructType([
 
StructField("TYPE", StringType()),
 
StructField("COUNTRY", StringType()),
 
StructField("CITY", StringType()),
 
StructField("ENGINES", IntegerType()),
 
StructField("FIRST_FLIGHT", StringType()),
 
StructField("NUMBER_BUILT", IntegerType())
 
])
 

 
read_df = spark.read \
 
.option("header", "true") \
 
.option("mode", "DROPMALFORMED") \
 
.format("csv") \
 
.schema(schema) \
 
.load("airplanes.csv")
 

 
read_df.show(10)

Resultado utilizando DROPMALFORMED mode

Após definirmos o valor do mode como DROPMALFORMED, perceba que ao listar o registros do Dataframe, os registros corrompidos foram ignorados, não sendo apresentados no Dataframe.


Criando um Dataframe usando o mode FAILFAST

Diferente do mode DROPMALFORMED e PERMISSIVE, FAILFAST lança uma exceção quando detecta registros corrompidos.

from pyspark.sql import SparkSession
 
from pyspark.sql.types import StructType, StructField, StringType, IntegerType
 

 
if __name__ == "__main__":
 

 
spark = SparkSession.builder \
 
.master("local[1]") \
 
.appName("spark-app") \
 
.getOrCreate()
 

 
schema = StructType([
 
StructField("TYPE", StringType()),
 
StructField("COUNTRY", StringType()),
 
StructField("CITY", StringType()),
 
StructField("ENGINES", IntegerType()),
 
StructField("FIRST_FLIGHT", StringType()),
 
StructField("NUMBER_BUILT", IntegerType())
 
])
 

 
read_df = spark.read \
 
.option("header", "true") \
 
.option("mode", "FAILFAST") \
 
.format("csv") \
 
.schema(schema) \
 
.load("airplanes.csv")
 

 
read_df.show(10)

Resultado utilizando FAILFAST mode

ERROR Executor: Exception in task 0.0 in stage 0.0 (TID 0)

org.apache.spark.SparkException: Malformed records are detected in record parsing. Parse Mode: FAILFAST. To process malformed records as null result, try setting the option 'mode' as 'PERMISSIVE'.


Material de estudo

Se quer aprender mais sobre o assunto e alcançar um alto nível de conhecimento, recomendo fortemente a leitura do(s) seguinte(s) livro(s):

Spark: The Definitive Guide: Big Data Processing Made Simple (Versão Inglês) é uma referência completa para quem quer aprender o Spark e sobre as suas principais funcionalidades. Lendo esse livro, você vai aprender sobre DataFrames, Spark SQL através de exemplos práticos. O autor mergulha nas APIs de baixo nível do Spark, RDDs e também sobre como o Spark é executado em um cluster e como depurar e monitorar os aplicativos de clusters do Spark. Os exemplos práticos estão em Scala e Python.

Beginning Apache Spark 3: With Dataframe, Spark SQL, Structured Streaming, and Spark Machine Library (Versão Inglês) com a nova versão do Spark, este livro explora os principais recursos do Spark, como o uso de Dataframes, Spark SQL no qual você pode usar SQL para manipular dados e Structured Streaming para processar dados em tempo real. Este livro contém exemplos práticos e trechos de código para facilitar a leitura.

High Performance Spark: Best Practices for Scaling and Optimizing Apache Spark (Versão Inglês) é um livro que explora as melhores práticas usando a linguagem Spark e Scala para lidar com aplicações de dados em larga escala, técnicas para transformações utilizando RDD, e também mostra como as novas interfaces do Spark SQL melhoram o desempenho sobre a estrutura de dados RDD do SQL, exemplos de Spark MLlib e o uso de bibliotecas de aprendizado de máquina de ML e muito mais.

Python Crash Course, 2nd Edition: A Hands-On, Project-Based Introduction to Programming (Versão Inglês)

abrange os conceitos básicos do Python por meio de exemplos interativos e práticas recomendadas.

Learning Scala: Practical Functional Programming for the Jvm (Versão Inglês) é um excelente livro que aborda a linguagem Scala através de exemplos e exercícios práticos. Lendo este livro, você aprenderá sobre os principais tipos de dados, literais, valores e variáveis. Construir classes que compõem uma ou mais características para total reutilização, criar novas funcionalidades misturando-as na instanciação e muito mais. Scala é uma das principais linguagens em projetos de Big Data em todo o mundo, com grande uso em grandes empresas de tecnologia como o Twitter e também a linguagem principal do Spark.

Bom é isso, espero que tenham gostado!

    0