Amazon web services JDBC读/写中的spark时间戳时区

Amazon web services JDBC读/写中的spark时间戳时区,amazon-web-services,apache-spark,Amazon Web Services,Apache Spark,我正在通过从oracle读取数据来创建拼花地板文件 Oracle正在UTC中运行。我确认使用了 SELECT DBTIMEZONE FROM DUAL; 输出: DBTIMEZONE| ----------| +00:00 | UTC +-------------------+ | col1 | +-------------------+ |2012-11-11 05:00:00| |2013-11-25 05:00:00| |2013-11-11 05:0

我正在通过从oracle读取数据来创建拼花地板文件

Oracle正在UTC中运行。我确认使用了

SELECT DBTIMEZONE FROM DUAL;
输出:

DBTIMEZONE|
----------|
+00:00    |
UTC
+-------------------+
|             col1  |
+-------------------+
|2012-11-11 05:00:00|
|2013-11-25 05:00:00|
|2013-11-11 05:00:00|
|2014-12-25 05:00:00|
+-------------------+
从JDBC读取并作为拼花写入S3:

df = spark.read.format('jdbc').options(url=url,
                                           dbtable=query,
                                           user=user,
                                           password=password,
                                           fetchsize=2000).load()

df.write.parquet(s3_loc, mode="overwrite")
现在,我检查了
spark.sql.session.timeZone的值

print(spark.conf.get("spark.sql.session.timeZone"))
输出:

DBTIMEZONE|
----------|
+00:00    |
UTC
+-------------------+
|             col1  |
+-------------------+
|2012-11-11 05:00:00|
|2013-11-25 05:00:00|
|2013-11-11 05:00:00|
|2014-12-25 05:00:00|
+-------------------+
现在,我正在从S3位置读取数据:

df1 = spark.read.parquet(s3_loc)
df1.show()
输出:

DBTIMEZONE|
----------|
+00:00    |
UTC
+-------------------+
|             col1  |
+-------------------+
|2012-11-11 05:00:00|
|2013-11-25 05:00:00|
|2013-11-11 05:00:00|
|2014-12-25 05:00:00|
+-------------------+
col1
是oracle中的日期,在spark df中转换为时间戳

为什么在输出中添加5小时?数据库以UTC运行,而
spark.sql.session.timeZone
为UTC

注:
  • RDS和EMR均在AWS US-EAST-1中运行
  • 在所有spark节点上,我运行了
    TZ=UTC

  • 时区由JDBC驱动程序重新识别,它不知道Spark的时区设置,但依赖于JVM的默认时区。此外,它会忽略远程数据库会话的时区设置。您说您运行了
    TZ=UTC
    ——我不确定,但可能不起作用。检查
    时区。getDefault
    告诉您的信息

    如我所怀疑的,如果您的JVM时区是EDT(US-EAST-1是弗吉尼亚),那么JDBC从Oracle读取的
    2012-11-11 00:00:00
    将被解释为在EDT中。在Spark中显示的是UTC时间
    2012-11-11 05:00:00
    UTC,这是您得到的结果

    要修复此问题,请在运行spark submit时覆盖JVM默认时区:

    spark-submit \
    --conf "spark.driver.extraJavaOptions=-Duser.timezone=UTC" \
    --conf "spark.executor.extraJavaOptions=-Duser.timezone=UTC" \
    ...
    
    你救了我的命:-)谢谢!JDBC驱动程序动态地将输入Oracle的
    日期
    类型转换为UTC。现在我找到了一个优雅的方式告诉他“不要这样做”。