dev*_*v ツ 4 amazon-web-services apache-spark
我正在通过从 Oracle 读取数据来创建镶木地板文件。
Oracle 以 UTC 运行。我确认使用,
SELECT DBTIMEZONE FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
输出:
DBTIMEZONE|
----------|
+00:00 |
Run Code Online (Sandbox Code Playgroud)
从 JDBC 读取并以 parquet 形式写入 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")
Run Code Online (Sandbox Code Playgroud)
现在,我检查了spark.sql.session.timeZone
print(spark.conf.get("spark.sql.session.timeZone"))
Run Code Online (Sandbox Code Playgroud)
输出:
UTC
Run Code Online (Sandbox Code Playgroud)
现在,我正在从 S3 位置读取数据:
df1 = spark.read.parquet(s3_loc)
df1.show()
Run Code Online (Sandbox Code Playgroud)
输出:
+-------------------+
| 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|
+-------------------+
Run Code Online (Sandbox Code Playgroud)
col1是oracle中的日期并转换为spark df中的时间戳。
为什么输出中要添加 5 小时?数据库以 UTC 运行,并且spark.sql.session.timeZone是 UTC。
TZ=UTC时区由 JDBC 驱动程序识别,它不知道 Spark 的时区设置,而是依赖于 JVM 的默认时区。此外,它忽略远程数据库会话的时区设置。你说你跑了TZ=UTC——我不确定,但可能没用。检查TimeZone.getDefault告诉你什么。
正如我怀疑的那样,如果您的 JVM 时区是 EDT(US-EAST-1 是弗吉尼亚州),那么2012-11-11 00:00:00通过 JDBC 从 Oracle 读取的数据将被解释为 EDT。Spark 中显示的是2012-11-11 05:00:00UTC,这就是您得到的结果。
要修复此问题,请在运行 Spark-submit 时覆盖 JVM 默认时区:
spark-submit \
--conf "spark.driver.extraJavaOptions=-Duser.timezone=UTC" \
--conf "spark.executor.extraJavaOptions=-Duser.timezone=UTC" \
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3147 次 |
| 最近记录: |