在对损坏的记录字段

时间:2018-05-01 18:33:44

标签: apache-spark pyspark apache-spark-sql

我有一个用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

1 个答案:

答案 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

这结果是: https://issues.apache.org/jira/browse/SPARK-21610