在 AWS Glue 3.0 中使用 1900 之前的时间戳编写镶木地板时出现问题

Posted

技术标签:

【中文标题】在 AWS Glue 3.0 中使用 1900 之前的时间戳编写镶木地板时出现问题【英文标题】:Problems when writing parquet with timestamps prior to 1900 in AWS Glue 3.0 【发布时间】:2021-10-23 17:28:19 【问题描述】:

从 Glue 2.0 切换到 3.0 时,也意味着从 Spark 2.4 切换到 3.1.1, 在处理 1900 年之前的时间戳时,我的工作开始失败并出现此错误:

An error occurred while calling z:org.apache.spark.api.python.PythonRDD.runJob.
You may get a different result due to the upgrading of Spark 3.0: reading dates before 1582-10-15 or timestamps before 1900-01-01T00:00:00Z from Parquet INT96 files can be ambiguous, 
as the files may be written by Spark 2.x or legacy versions of Hive, which uses a legacy hybrid calendar that is different from Spark 3.0+s Proleptic Gregorian calendar.
See more details in SPARK-31404.
You can set spark.sql.legacy.parquet.int96RebaseModeInRead to 'LEGACY' to rebase the datetime values w.r.t. the calendar difference during reading. 
Or set spark.sql.legacy.parquet.int96RebaseModeInRead to 'CORRECTED' to read the datetime values as it is.

我尝试了一切在 Glue 中设置 int96RebaseModeInRead 配置,甚至联系了支持,但目前 Glue 似乎正在覆盖该标志,您无法自行设置。

如果有人知道解决方法,那就太好了。否则我将继续使用 Glue 2.0。并等待 Glue 开发团队解决此问题。

【问题讨论】:

你有没有试过在创建sparkSession的时候直接设置conf? 是的,不幸的是这不起作用,通过环境变量设置也不起作用。 你能展示一下你到目前为止所尝试的吗? 试试 --conf 就像docs.aws.amazon.com/glue/latest/dg/… 正如我所说,将其设置为环境变量也不起作用 【参考方案1】:

我通过将--conf 设置为spark.sql.legacy.parquet.int96RebaseModeInRead=CORRECTED --conf spark.sql.legacy.parquet.int96RebaseModeInWrite=CORRECTED --conf spark.sql.legacy.parquet.datetimeRebaseModeInRead=CORRECTED --conf spark.sql.legacy.parquet.datetimeRebaseModeInWrite=CORRECTED 使其工作。

虽然没有 ETA,但这是一种解决方法,Glue 开发团队正在努力修复。

此外,这仍然是非常错误的。例如,您不能在DynamicFrame 上调用.show(),您需要在DataFrame 上调用它。我打电话给data_frame.rdd.isEmpty()时,我所有的工作都失败了,别问我为什么。

24.11.2021 更新: 我联系了 Glue 开发团队,他们告诉我这是修复它的预期方法。不过,有一个解决方法可以在脚本内部完成:

sc = SparkContext()
# Get current sparkconf which is set by glue
conf = sc.getConf()
# add additional spark configurations
conf.set("spark.sql.legacy.parquet.int96RebaseModeInRead", "CORRECTED")
conf.set("spark.sql.legacy.parquet.int96RebaseModeInWrite", "CORRECTED")
conf.set("spark.sql.legacy.parquet.datetimeRebaseModeInRead", "CORRECTED")
conf.set("spark.sql.legacy.parquet.datetimeRebaseModeInWrite", "CORRECTED")
# Restart spark context
sc.stop()
sc = SparkContext.getOrCreate(conf=conf)
# create glue context with the restarted sc
glueContext = GlueContext(sc)

【讨论】:

仍然不适合我。尝试编写数据帧,但无论配置如何,都会失败。我尝试了所有可能的组合 - 在脚本中设置 conf,在作业中设置 conf,在脚本和作业中设置 conf。我使它起作用的唯一方法是忽略glueContext并改用SparkSession,这非常令人失望,因为我在所有脚本中都有Spark 3,不包括我使用某些glueContext功能(书签,read_from_catalogue等)的脚本跨度> 这很奇怪,通过在作业中设置 --conf 键,它适用于 > 200 个作业。 是的,你是对的。它终于奏效了!很可能是小故障或什么 - 根本没有改变,只是按下“运行作业”【参考方案2】:

官方 Glue 开发人员指南中解决的问题

Migrating from AWS Glue 2.0 to AWS Glue 3.0 最后一个项目符号。

【讨论】:

以上是关于在 AWS Glue 3.0 中使用 1900 之前的时间戳编写镶木地板时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

aws glue / pyspark - 如何使用 Glue 以编程方式创建 Athena 表

AWS Glue 布尔转换

AWS Python Shell - 如何使用 Glue 目录连接

如何在 AWS-Glue 脚本中编写用户定义的函数?

使用 Python 在 AWS Glue 中打开和读取文件

如何在 AWS Glue 中使用 Spark 包?