时区问题?

gstyhher  于 2021-06-26  发布在  Impala
关注(0)|答案(4)|浏览(419)

我在hdfs中有一些eventlog数据,其原始格式如下所示:

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 通过执行配置单元查询,将数据插入到配置单元/ Impala parquet 支持的表中: INSERT INTO TABLE log SELECT * FROM log_stage . 这是Parquet地板table的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表吗?

v8wbuo2f

v8wbuo2f1#

以上答案要非常小心,因为https://issues.apache.org/jira/browse/impala-2716
目前,最好的解决方法是不使用时间戳数据类型,而是将时间戳存储为字符串。

laawzig2

laawzig22#

如中所述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 以匹配配置单元结果。
第一种方法确保在使用任何datetime函数时它都转换为本地时区。您可以将其设置为本文档中提到的impala守护程序启动选项。
https://docs.cloudera.com/documentation/enterprise/5-6-x/topics/impala_config_options.html

vkc1a9a2

vkc1a9a23#

另一方面,从hive v1.2开始,您还可以使用以下标志禁用时区转换行为:

hive.parquet.timestamp.skip.conversion

Parquet地板的当前配置单元实现将时间戳存储到utc,此标志允许在从其他工具读取Parquet地板文件时跳过转换
这是作为https://issues.apache.org/jira/browse/hive-9482
最后,不是确切的时区,但是为了兼容spark(v1.3及更高版本)和parquet文件上的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

ctzwtxfj

ctzwtxfj4#

hive以不同的方式将时间戳写入Parquet地板。你可以使用impalad旗 -convert_legacy_hive_parquet_utc_timestamps 告诉 Impala 在阅读时做转换。有关更多详细信息,请参阅时间戳文档。
这篇博文简要描述了这个问题:
当hive将时间戳值存储为parquet格式时,它将本地时间转换为utc时间,当它读出数据时,它将转换回本地时间。但另一方面,impala在读取timestamp字段时不进行转换,因此返回utc时间而不是本地时间。
impalad标志告诉impala在读取hive生成的Parquet地板中的时间戳时进行转换。它确实会产生一些小的成本,所以如果这对您来说是个问题,您应该考虑使用impala编写时间戳(尽管它可能是最小的)。

相关问题