java - Spark Strutured Streaming convierte automáticamente la marca de tiempo a la hora local
scala apache-spark (2)
Para mí funcionó usar:
spark.conf.set("spark.sql.session.timeZone", "UTC")
Le dice a la chispa SQL que use UTC como zona horaria predeterminada para las marcas de tiempo. Lo usé en spark SQL, por ejemplo:
select *, cast(''2017-01-01 10:10:10'' as timestamp) from someTable
Sé que no funciona en 2.0.1.
pero funciona en Spark 2.2.
También utilicé en
SQLTransformer
y funcionó.
Sin embargo, no estoy seguro acerca de la transmisión.
Tengo mi marca de tiempo en UTC e ISO8601, pero usando Structured Streaming, se convierte automáticamente a la hora local. ¿Hay alguna manera de detener esta conversión? Me gustaría tenerlo en UTC.
Estoy leyendo datos json de Kafka y luego los
from_json
usando la función
from_json
Spark.
Entrada:
{"Timestamp":"2015-01-01T00:00:06.222Z"}
Fluir:
SparkSession
.builder()
.master("local[*]")
.appName("my-app")
.getOrCreate()
.readStream()
.format("kafka")
... //some magic
.writeStream()
.format("console")
.start()
.awaitTermination();
Esquema:
StructType schema = DataTypes.createStructType(new StructField[] {
DataTypes.createStructField("Timestamp", DataTypes.TimestampType, true),});
Salida:
+--------------------+
| Timestamp|
+--------------------+
|2015-01-01 01:00:...|
|2015-01-01 01:00:...|
+--------------------+
Como puede ver, la hora se ha incrementado por sí misma.
PD: Traté de experimentar con la función
from_utc_timestamp
Spark, pero no
from_utc_timestamp
suerte.
Nota :
Esta respuesta es útil principalmente en Spark <2.2. Para la versión más nueva de Spark, vea la respuesta de
Sin embargo, debemos tener en cuenta que a partir de hoy (Spark 2.4.0),
spark.sql.session.timeZone
no establece
user.timezone
(
java.util.TimeZone.getDefault
).
Por lo tanto, configurar solo `` spark.sql.session.timeZone` ''puede resultar en una situación bastante incómoda en la que los componentes SQL y no SQL usan diferentes configuraciones de zona horaria.
Por lo tanto, todavía recomiendo configurar
user.timezone
explícitamente, incluso si
spark.sql.session.timeZone
está configurado.
TL; DR Desafortunadamente, así es como Spark maneja las marcas de tiempo en este momento y realmente no hay una alternativa incorporada, aparte de operar directamente en tiempo de época, sin usar utilidades de fecha / hora.
Puede una discusión perspicaz sobre la lista de desarrolladores de Spark: semántica SQL TIMESTAMP vs. SPARK-18350
La solución más limpia que he encontrado hasta ahora es establecer
-Duser.timezone
en
UTC
tanto para el controlador como para los ejecutores.
Por ejemplo con submit:
bin/spark-shell --conf "spark.driver.extraJavaOptions=-Duser.timezone=UTC" /
--conf "spark.executor.extraJavaOptions=-Duser.timezone=UTC"
o ajustando los archivos de configuración (
spark-defaults.conf
):
spark.driver.extraJavaOptions -Duser.timezone=UTC
spark.executor.extraJavaOptions -Duser.timezone=UTC