我在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表吗?
4条答案
按热度按时间v8wbuo2f1#
以上答案要非常小心,因为https://issues.apache.org/jira/browse/impala-2716
目前,最好的解决方法是不使用时间戳数据类型,而是将时间戳存储为字符串。
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
vkc1a9a23#
另一方面,从hive v1.2开始,您还可以使用以下标志禁用时区转换行为:
Parquet地板的当前配置单元实现将时间戳存储到utc,此标志允许在从其他工具读取Parquet地板文件时跳过转换
这是作为https://issues.apache.org/jira/browse/hive-9482
最后,不是确切的时区,但是为了兼容spark(v1.3及更高版本)和parquet文件上的impala,有以下标志:
https://spark.apache.org/docs/1.3.1/sql-programming-guide.html#configuration
其他:https://issues.apache.org/jira/browse/spark-12297
ctzwtxfj4#
hive以不同的方式将时间戳写入Parquet地板。你可以使用impalad旗
-convert_legacy_hive_parquet_utc_timestamps
告诉 Impala 在阅读时做转换。有关更多详细信息,请参阅时间戳文档。这篇博文简要描述了这个问题:
当hive将时间戳值存储为parquet格式时,它将本地时间转换为utc时间,当它读出数据时,它将转换回本地时间。但另一方面,impala在读取timestamp字段时不进行转换,因此返回utc时间而不是本地时间。
impalad标志告诉impala在读取hive生成的Parquet地板中的时间戳时进行转换。它确实会产生一些小的成本,所以如果这对您来说是个问题,您应该考虑使用impala编写时间戳(尽管它可能是最小的)。