java - يقوم Spark Strutured Streaming تلقائيًا بتحويل الطابع الزمني إلى التوقيت المحلي




scala apache-spark (2)

لديّ الطابع الزمني الخاص بي في UTC و ISO8601 ، لكن باستخدام "التدفق المهيكل" ، يتم تحويله تلقائيًا إلى التوقيت المحلي. هل هناك طريقة لإيقاف هذا التحويل؟ أود الحصول عليها بالتوقيت العالمي المنسق.

أقرأ بيانات json من Kafka ومن ثم from_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:...|
+--------------------+

كما ترون ، ازدادت الساعة من تلقاء نفسها.

ملاحظة: حاولت تجربة وظيفة سبارك from_utc_timestamp ، لكن لم يحالفني الحظ.


بالنسبة لي عملت على استخدام:

spark.conf.set("spark.sql.session.timeZone", "UTC")

يخبر الشرارة SQL لاستخدام التوقيت العالمي المتفق عليه (UTC) كنقطة زمنية افتراضية للطوابع الزمنية. أنا استخدمه في شرارة SQL على سبيل المثال:

select *, cast('2017-01-01 10:10:10' as timestamp) from someTable

وأنا أعلم أنه لا يعمل في 2.0.1. لكنه يعمل في سبارك 2.2. اعتدت في SQLTransformer أيضا وأنها عملت.

لست متأكدا من التدفق رغم ذلك.


ملاحظة :

هذه الإجابة مفيدة بشكل أساسي في Spark <2.2. للحصول على الإصدار الأحدث من Spark ، راجع إجابة

ومع ذلك ، تجدر الإشارة إلى أنه اعتبارًا من اليوم (Spark 2.4.0) ، لا يقوم user.timezone بتعيين user.timezone ( java.util.TimeZone.getDefault ). لذلك يمكن أن يؤدي ضبط `` spark.sql.session.timeZone` وحده إلى موقف محرج إلى حد ما حيث تستخدم مكونات SQL وغير SQL إعدادات مناطق زمنية مختلفة.

لذلك ، ما زلت أوصي بتعيين user.timezone بشكل صريح ، حتى إذا تم تعيين spark.sql.session.timeZone .

TL ؛ DR للأسف هذه هي الطريقة التي يتعامل بها Spark مع الطوابع الزمنية في الوقت الحالي ولا يوجد بالفعل بديل مدمج ، بخلاف العمل في وقت العصر مباشرة ، دون استخدام أدوات التاريخ / الوقت.

يمكنك مناقشة دقيقة حول قائمة مطوري Spark: دلالات SQL TIMESTAMP مقابل SPARK-18350

أنظف الحل الذي وجدته حتى الآن هو ضبط -Duser.timezone على UTC عليه ( 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




spark-structured-streaming