我在一个项目中使用Scala和Spark处理存储在HDFS中的文件。这些文件每天早上都在HDFS登陆。我有一个工作,每天从HDFS读取该文件,处理它,然后将结果写入HDFS。将文件转换为Dataframe后,此作业将执行过滤器,以仅获取包含高于最后一个文件中处理的最高时间戳的时间戳的行。此过滤器仅在几天内具有未知行为。尽管新文件包含与该过滤器匹配的行,但有些日子按预期和其他日期工作,过滤结果为空。在TEST环境中执行同一文件时,这种情况会一直发生,但在我的本地工作中,使用具有相同HDFS连接的相同文件。
我尝试过以不同的方式进行过滤,但是在某些特定文件的环境中没有一个可以工作,但所有这些都可以在我的LOCAL中正常工作: 1)Spark sql
val diff = fp.spark.sql("select * from curr " +
s"where TO_DATE(CAST(UNIX_TIMESTAMP(substring(${updtDtCol},
${substrStart},${substrEnd}),'${dateFormat}') as TIMESTAMP))" +
s" > TO_DATE(CAST(UNIX_TIMESTAMP('${prevDate.substring(0,10)}'
,'${dateFormat}') as TIMESTAMP))")
2)火花过滤器功能
val diff = df.filter(date_format(unix_timestamp(substring(col(updtDtCol),0,10),dateFormat).cast("timestamp"),dateFormat).gt(date_format(unix_timestamp(substring(col("PrevDate"),0,10),dateFormat).cast("timestamp"),dateFormat)))
3)使用过滤器的结果添加额外的列,然后按此新列过滤
val test2 = df.withColumn("PrevDate", lit(prevDate.substring(0,10)))
.withColumn("DatePre", date_format(unix_timestamp(substring(col("PrevDate"),0,10),dateFormat).cast("timestamp"),dateFormat))
.withColumn("Result", date_format(unix_timestamp(substring(col(updtDtCol),0,10),dateFormat).cast("timestamp"),dateFormat).gt(date_format(unix_timestamp(substring(col("PrevDate"),0,10),dateFormat).cast("timestamp"),dateFormat)))
.withColumn("x", when(date_format(unix_timestamp(substring(col(updtDtCol),0,10),dateFormat).cast("timestamp"),dateFormat).gt(date_format(unix_timestamp(substring(col("PrevDate"),0,10),dateFormat).cast("timestamp"),dateFormat)), lit(1)).otherwise(lit(0)))
val diff = test2.filter("x == 1")
我认为问题不是由过滤器本身引起的,也可能不是由文件引起的,但我希望收到关于我应该检查什么或者是否有人在此之前遇到过这种情况的反馈。
请告诉我在此处发布哪些信息非常有用,以便收到一些反馈。
文件示例的一部分如下所示:
|TIMESTAMP |Result|x|
|2017-11-30-06.46.41.288395|true |1|
|2017-11-28-08.29.36.188395|false |0|
将TIMESTAMP值与previousDate进行比较(例如:2017-11-29),然后创建一个名为' Result'这种比较的结果总是适用于环境和另一个名为' x'结果相同。
正如我之前提到的,如果我在两个日期之间使用比较器功能,或者在结果列中使用结果'结果'或者' x'要过滤数据帧,有时结果是空数据帧,但在本地使用相同的HDFS和文件,结果包含数据。
答案 0 :(得分:0)
我怀疑它是数据/日期格式问题。您是否有机会验证转换的日期是否符合预期?
如果两列的日期字符串都包含时区,则行为是可预测的。
如果其中只有一个包含时区,则在本地和远程执行时结果会有所不同。这完全取决于集群的时区。
为了调试这个问题,我建议您使用其他列来捕获相应日期字符串的unix_timestamp(..)/ millis,并使用和附加列来捕获两列的差异。差异列应该有助于找出转换出错的地点和原因。希望这会有所帮助。
答案 1 :(得分:0)
如果有人想知道这个问题发生了什么,以及我最终如何找到错误的原因是解释。基本上它是由执行作业的机器的不同时区(LOCAL机器和TEST服务器)引起的。 unix_timestamp函数返回正确的值,同时考虑到服务器的时区。基本上最后我不必使用unix_timestamp函数,我不需要使用日期字段的完整内容。下次我会再仔细检查一下。