Impala - 解决查询到的数据不是最新的问题(refresh命令)
作者:hangge | 2024-10-21 08:51
1,问题描述
(1)首先我们创建一张名为 external_t1 的外部表:
create external table external_t1( id int, name string, age int, birthday timestamp )row format delimited fields terminated by '\t' lines terminated by '\n' location '/external_t1';
(2)表需要加载的数据文件为 external_t1.dat,字段分隔符使用制表符,文件内容如下:
(3)然后直接使用 hdfs 的 put 命令将数据文件上传到指定目录中:
hdfs dfs -put external_t1.dat /external_t1
(4)接着查询外部表中的数据,可以发现数据正常,一共 3 条:
select * from external_t1;
(5)然后在这个表对应的数据目录中再添加一个数据文件:
hdfs dfs -put external_t1.dat /external_t1/external_t1_2.dat
(6)接下来再查询一下这个表中的数据,此时发现查询出的数据还是之前的 3 条,现在其实应该是 6 条数据的。
select * from external_t1;
(7)而到 Hive 中查询一下,会发现在 Hive 中是没有问题的,可以正常识别到最新的 6 条数据。
2,问题原因
(1)正常情况下,我们在 Impala 中对表执行的操作都是通过 Catalog 服务管理的,表的元数据信息都是会实时更新的,不会导致元数据信息不准确。
(2)但是针对一些特殊情况,会导致 Impala 无法自动感知到最新的元数据变化:
- 当 Impala 中的表对应的 HDFS 目录中的数据文件发生了变化的时候,也就是我们使用 hdfs 的 put 命令向表的数据目录中添加了新的文件,或者删除了老的文件,此时 Impala 中维护的元数据信息是感知不到这些数据文件变化的,这样会导致在 impala 中查询时获取的还是之前的老数据。
- 当我们在 Hive 中对 Impala 的表或者是 Hive 自己的表执行了 alter table、insert、load data 以及其他对表产生修改的 SQL 语句时,也会出现这种问题,这也就意味着 Impala 是无法自动识别到 Hive 中元数据的变化情况。
3,解决办法
(1)我们可以使用 refresh 命令刷新下指定表的元数据,refresh 的主要功能是负责重新加载指定表的最新元数据信息,以及增量加载表中新的数据文件的位置信息。
refresh external_t1;
(2)使用 refresh 刷新后,就可以查询到最新的数据了。
select * from external_t1;
附:refresh 命令与 invalidate metadata 命令对比
1,性能比较
(1)refresh 命令负责重新加载指定表的最新元数据信息,以及增量加载表中新的数据文件的位置信息,这个操作可以认为是增量更新,所以说他是轻量级的,性能开销较小。
(2)invalidate metadata 命令可以将表的元数据标记为过期,它会重新加载这个表的所有元数据信息,属于全量更新,性能开销较大。
invalidate metadata 命令后面可以指定表名,也可以不指定表名:
- 如果不指定表名,则 Impala 中缓存的所有表的元数据信息都会被标记为过期。
- 如果指定了表名,则只会将指定的表的元数据信息标记为过期。
2,使用建议
(1)针对单张表而言,invalidate metadata 的性能开销也比 refresh 要高。在向表中添加了数据文件之后,建议优先使用 refresh。
(2)如果不确定哪个表的元数据发送了变化,想要全量更新表的元数据信息,建议使用 invalidate metadata,这样比较方便,此时就不考虑性能开销了。
全部评论(0)