Spark Strutured Streaming自动将时间戳转换为本地时间
我有UTC和ISO8601的时间戳,但使用结构化流,它会自动转换为本地时间。 有没有办法阻止这种转换? 我想在UTC中使用它。
我正在从Kafka读取json数据,然后使用from_json
Spark函数解析它们。
输入:
{"Timestamp":"2015-01-01T00:00:06.222Z"}
流:
SparkSession .builder() .master("local[*]") .appName("my-app") .getOrCreate() .readStream() .format("kafka") ... //some magic .writeStream() .format("console") .start() .awaitTermination();
架构:
StructType schema = DataTypes.createStructType(new StructField[] { DataTypes.createStructField("Timestamp", DataTypes.TimestampType, true),});
输出:
+--------------------+ | Timestamp| +--------------------+ |2015-01-01 01:00:...| |2015-01-01 01:00:...| +--------------------+
如您所见,小时数自行增加。
PS:我试着尝试使用from_utc_timestamp
Spark函数,但没有运气。
对我来说它起作用了:
spark.conf.set("spark.sql.session.timeZone", "UTC")
它告诉spark SQL使用UTC作为时间戳的默认时区。 我在spark SQL中使用它,例如:
select *, cast('2017-01-01 10:10:10' as timestamp) from someTable
我知道它在2.0.1中不起作用。 但适用于Spark 2.2。 我也在SQLTransformer
使用过它。
我不确定流媒体。
注意 :
这个答案主要用于Spark <2.2。 对于较新的Spark版本,请参阅astro-asz 的答案
TL; DR不幸的是,这就是Spark现在处理时间戳的方式,除了直接在纪元时间运行之外,没有使用日期/时间工具,实际上没有内置的替代方案。
您可以对Spark开发人员列表进行深入的讨论: SQL TIMESTAMP语义与SPARK-18350
到目前为止,我发现最干净的解决方法是将驱动程序和执行程序的-Duser.timezone
设置为UTC
。 例如,提交:
bin/spark-shell --conf "spark.driver.extraJavaOptions=-Duser.timezone=UTC" \ --conf "spark.executor.extraJavaOptions=-Duser.timezone=UTC"
或者通过调整配置文件( spark-defaults.conf
):
spark.driver.extraJavaOptions -Duser.timezone=UTC spark.executor.extraJavaOptions -Duser.timezone=UTC