我有一个用Python编写的Spark作业,在检查数据中的错误时会出现奇怪的行为。简化版如下:
from pyspark.sql import SparkSession
from pyspark.sql.types import StringType, StructType, StructField, DoubleType
from pyspark.sql.functions import col, lit
spark = SparkSession.builder.master("local[3]").appName("pyspark-unittest").getOrCreate()
spark.conf.set("mapreduce.fileoutputcommitter.marksuccessfuljobs", "false")
SCHEMA = StructType([
StructField("headerDouble", DoubleType(), False),
StructField("ErrorField", StringType(), False)
])
dataframe = (
spark.read
.option("header", "true")
.option("mode", "PERMISSIVE")
.option("columnNameOfCorruptRecord", "ErrorField")
.schema(SCHEMA).csv("./x.csv")
)
total_row_count = dataframe.count()
print("total_row_count = " + str(total_row_count))
errors = dataframe.filter(col("ErrorField").isNotNull())
errors.show()
error_count = errors.count()
print("errors count = " + str(error_count))
它正在阅读的csv就是:
headerDouble
wrong
相关的输出是
total_row_count = 1
+------------+----------+
|headerDouble|ErrorField|
+------------+----------+
| null| wrong|
+------------+----------+
errors count = 0
现在这怎么可能发生?如果数据帧有记录,那么如何计算为0?这是Spark基础设施中的错误还是我错过了什么?
编辑:看起来这可能是Spark 2.2上已知的错误,已在Spark 2.3中修复 - https://issues.apache.org/jira/browse/SPARK-21610
答案 0 :(得分:3)
谢谢@ user6910411 - 似乎确实是一个错误。我在Spark项目的bug追踪器中提出了一个问题。
我推测Spark由于架构中存在ErrorField
而感到困惑,该架构也被指定为错误列并用于过滤数据帧。
与此同时,我认为我找到了一种以合理的速度计算数据帧行的解决方法:
def count_df_with_spark_bug_workaround(df):
return sum(1 for _ in df.toLocalIterator())
当.count()
无法正常工作时,不太清楚为什么这会给出正确答案。
我提出的Jira票: https://issues.apache.org/jira/browse/SPARK-24147