【问题标题】:Impala timestamps don't match Hive - a timezone issue?Impala 时间戳与 Hive 不匹配 - 时区问题?
【发布时间】:2016-02-06 23:26:00
【问题描述】:

我在 HDFS 中有一些事件日志数据,其原始格式如下所示:

2015-11-05 19:36:25.764 INFO    [...etc...]

一个外部表指向这个 HDFS 位置:

CREATE EXTERNAL TABLE `log_stage`(
  `event_time` timestamp, 
  [...])
ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY '\t' 
  LINES TERMINATED BY '\n' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'

为了性能,我们想在 Impala 中查询这个。 log_stage 数据通过执行 Hive 查询插入到 Hive/Impala Parquet 支持的表中:INSERT INTO TABLE log SELECT * FROM log_stage。这是 Parquet 表的 DDL:

CREATE TABLE `log`(
  `event_time` timestamp,
  [...])
ROW FORMAT SERDE
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'

问题:在 Impala 中查询时,时间戳提前 7 小时:

Hive time:   2015-11-05 19:36:25.764
Impala time: 2015-11-06 02:36:25.764

> as.POSIXct("2015-11-06 02:36:25") - as.POSIXct("2015-11-05 19:36:25")
Time difference of 7 hours

注意:服务器的时区(来自/etc/sysconfig/clock)都设置为“美国/丹佛”,目前比 UTC 晚 7 小时。

Impala 似乎正在处理已经在 UTC 中的事件,错误地假设它们是在美国/丹佛时间,并增加了另外 7 个小时。

您知道如何同步时间以使 Impala 表与 Hive 表匹配吗?

【问题讨论】:

    标签: timezone hive impala


    【解决方案1】:

    Hive 以不同的方式将时间戳写入 Parquet。您可以使用 impalad 标志 -convert_legacy_hive_parquet_utc_timestamps 告诉 Impala 在读取时进行转换。有关详细信息,请参阅TIMESTAMP documentation

    This blog post 有问题的简要说明:

    当 Hive 将时间戳值存储为 Parquet 格式时,它将本地时间转换为 UTC 时间,当它读出数据时,它又转换回本地时间。而另一方面,Impala 在读取时间戳字段时不会进行转换,因此返回的是 UTC 时间而不是本地时间。

    impalad 标志告诉 Impala 在读取 Parquet 中的时间戳时进行转换由 Hive 生成​​。它确实会产生一些小成本,因此如果这对您来说是个问题(尽管它可能很小),您应该考虑使用 Impala 编写您的时间戳。

    【讨论】:

    • 这是一个绝妙的答案。谢谢马特!
    【解决方案2】:

    在相关说明中,从 Hive v1.2 开始,您还可以使用此标志禁用时区转换行为:

    hive.parquet.timestamp.skip.conversion
    

    parquet 的当前 Hive 实现将时间戳存储为 UTC,此标志允许跳过从其他工具读取 parquet 文件时的转换。

    这是作为https://issues.apache.org/jira/browse/HIVE-9482的一部分添加的

    最后,不是确切的时区,而是为了在 Parquet 文件上兼容 Spark(v1.3 及更高版本)和 Impala,有这个标志:

    spark.sql.parquet.int96AsTimestamp
    

    https://spark.apache.org/docs/1.3.1/sql-programming-guide.html#configuration

    其他:https://issues.apache.org/jira/browse/SPARK-12297

    【讨论】:

    • hive.parquet.timestamp.skip.conversion 仅适用于读取 parquet 文件。写入 parquet 文件时仍会发生转换。
    • 你好 xgMz,Benitok 的回答是真的吗?
    【解决方案3】:

    由于https://issues.apache.org/jira/browse/IMPALA-2716,请务必小心上述答案

    就目前而言,最好的解决方法是不使用 TIMESTAMP 数据类型并将时间戳存储为字符串。

    【讨论】:

    【解决方案4】:

    如中所述 https://docs.cloudera.com/documentation/enterprise/latest/topics/impala_timestamp.html

    您可以使用----use_local_tz_for_unix_timestamp_conversions=true--convert_legacy_hive_parquet_utc_timestamps=true 来匹配Hive 结果。

    当您使用任何日期时间函数时,第一个确保它转换为本地时区。您可以将其设置为本文档中提到的 Impala Daemon 启动选项。

    https://docs.cloudera.com/documentation/enterprise/5-6-x/topics/impala_config_options.html

    【讨论】:

      猜你喜欢
      • 2016-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      相关资源
      最近更新 更多