提问人:Sam 提问时间:1/30/2023 最后编辑:Sam 更新时间:5/30/2023 访问量:39
为什么 PySpark 代码挂起一段时间,然后在访问数据帧时突然终止
Why PySpark code hangs for a while and then terminates abruptly while accessing a dataframe
问:
问题陈述: 当 PySpark 程序根据特定字段不为 NULL 的条件从数据帧中读取记录时,程序将挂起。此字段是一个字符串字段,其中可能包含字符串值,也可能不包含字符串值。对此字符串字段的任何操作,例如检查 NULL、计算字段的长度,都将导致代码挂起,然后终止。
描述: 例如,在我们的例子中,PySpark 程序从文件中读取数据并加载到数据帧中。名为“ErDesc”的新列将添加到数据帧中。当任何字段的记录数据验证失败时,此字段将动态填充逗号分隔的错误说明。在所有检查结束时,当读取数据帧以识别“ErDesc”字段为 NULL(有效记录)的记录时,有时活动成功完成,有时程序挂起然后终止。
到目前为止,我们做了什么: 我们试图通过将“ErDesc”的初始值定义为“”或“”而不是“NULL”来解决这个问题。但是,在通过所有数据验证处理记录后,每当我们检查数据帧是否为“ErDesc”或“”或NULL时,该过程就会挂起并终止。令人困惑的是,记录是通过多次迭代处理的,对于最初的 2 次迭代,对“ErDesc”的检查工作正常,但在下一次迭代中,它会挂起然后终止。我们修改了代码以跳过此迭代并继续下一次迭代。代码再次成功完成前两次迭代,跳过第三次迭代,成功执行第四次迭代,并在第五次迭代中再次挂起并终止。代码的行为是完全不合理的。 更令人困惑的是,错误数据帧是通过检查 ErDesc 为 NOT NULL 来检查父数据帧中的错误记录来创建的。但是,代码在使用错误数据帧将数据加载到数据库的阶段挂起。我们最初认为这可能是数据库级别的问题,但最终发现这是由于 pyspark 中的延迟计算,错误数据帧仅在访问它以加载到数据库表中时执行。
答:
溶液:为了解决这个问题,我们定义了一个名为“ErInt”的整数列以及“ErDesc”列,如下所示。
.withColumn(“ErDesc”, lit(“”)) .withColumn(“ErInt”,lit(0))
每当在 ErDesc 列的记录中发现错误时,我们将字段 ErInt 更改为 1,并继续填充具有相关错误描述值的 ErDesc 列。然后,在识别数据帧中的错误记录时,我们检查了“ErInt == 1”,而不是检查 ErDesc 是否不等于 NULL 或 '' 或 “”。使用这种方法,所有迭代都成功执行,代码挂起问题得到解决。
结论:因此,总而言之,如果您的 pyspark 代码正在检查 NULL 值的字符串字段,并且代码挂起并终止,请尽可能改用 interger 值。这将解决问题。
评论