amazon-web-services - JDBC读/写中的火花时间戳时区
问题描述
我正在通过从 oracle 读取数据来创建镶木地板文件。
Oracle 以 UTC 运行。我确认使用,
SELECT DBTIMEZONE FROM DUAL;
输出:
DBTIMEZONE|
----------|
+00:00 |
从 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")
现在,我检查了spark.sql.session.timeZone
print(spark.conf.get("spark.sql.session.timeZone"))
输出:
UTC
现在,我正在从 S3 位置读取数据:
df1 = spark.read.parquet(s3_loc)
df1.show()
输出:
+-------------------+
| 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 中运行
- 在所有的火花节点上,我跑了
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:00
UTC,这就是你得到的结果。
要修复它,请在运行 spark-submit 时覆盖 JVM 默认时区:
spark-submit \
--conf "spark.driver.extraJavaOptions=-Duser.timezone=UTC" \
--conf "spark.executor.extraJavaOptions=-Duser.timezone=UTC" \
...
推荐阅读
- arduino - 如何使操纵杆在 Arduino 上立即工作
- postgresql - 如何回顾以前的同类型记录
- python-3.x - 如何根据数据框值和字典键向数据框添加行
- c++ - pugixml 包含设置为未从 pugixml 配置 cmake 文件中找到的目录
- java - 代理背后的 UnknownHostException
- macros - 如何用宏获取类方法的参数类型?
- ios - 如何在表格视图上显示信息
- java - 如何在 Android 中以编程方式在 Spinner 上设置重叠锚点?
- reactjs - 如何从 SharePoint 列表项中获取数组中的总数
- python - 在 groupby 之后切片组并在子图中绘图