以下是常见的元数据相关的问题,基本都跟元数据的生命周期有关:
- 同样的查询,为什么第一次运行比后面几次运行都要慢很多?
- 在 Hive 中建了个新表,但在 Impala 中不可见,如何解决?
- 在 Hive 中建了个新的函数,但在 Impala 中不可见,如何解决?
- HUE中使用 Impala Editor 时,为什么有些 View 被显示成了表?
- Invalidate metadata 和 Refresh语句有什么区别?各有什么应用场景?
FAQ
1 同样的查询,为什么第一次运行比后面几次运行都要慢很多?
第一次运行时表的元数据未加载,Impalad在编译查询时向Catalogd发送PrioritizedLoad请求,等待Catalogd加载需要额外的时间。而第二次第三次再运行查询时,这部分的时间就不需要了,因此会更快。
另外如果表的元数据被 INVALIDATE METADATA 清空,查询的编译也会因为元数据加载而突然变慢。如果遇到全局的(即不加表名的)INVALIDATE METADATA,则集群里所有新提交的查询都会突然变慢。
2 在Hive中建了个新表,但在Impala中不可见,如何解决?
执行 INVALIDATE METADATA table_name 让 Impala 感知到新表的存在。
类似的,如果在 Hive 中建了个新库,也只有通过 INVALIDATE METADATA db_name.table_name 才能让 Impala 感知到这个新库的存在。由于 INVALIDATE METADATA 目前不支持只指定库名(IMPALA-1763),如果这个数据库里没有任何表,那就只能用不带表名的 INVALIDATE METADATA 了…… 这种场景还是建议直接在 Impala 里建库,或者在 Hive 中再建个表来对它执行 INVALIDATE METADATA table_name。
3 在Hive中建了个新的函数,但在Impala中不可见,如何解决?
乍一看好像只能用不带表名的 INVALIDATE METADATA,因为没有函数级别的 INVALIDATE METADATA。但其实有个语句专门为这个场景而生:REFRESH FUNCTIONS db_name,用它就可以了。
4 HUE 中使用 Impala Editor 时,为什么有些 View 被显示成了表?
元数据未加载时,Impala 只知道库名和表名,因此不知道一个表是否是View。因此在返回给HUE的元数据中,凡是元数据未加载的表统一都当作表来返回。解决办法是在 HUE 中执行 DESCRIBE table_name 触发这个表元数据的加载,然后再点击 "Clear Cache" 模式的 Refresh 让HUE重新从Impala获取元数据。
相关源码可参考:
5 Invalidate metadata 和 Refresh语句有什么区别?各有什么应用场景?
Invalidate metadata 用来清空(重置)元数据,执行完后元数据处于未加载状态。Refresh 用来增量更新元数据,执行完后元数据处于已加载状态。
大部分情况我们推荐用 REFRESH 语句来解决元数据过时的问题,只有以下两种情况需要使用 INVALIDATE METADATA:
- Hive 中创建的新表在 Impala 中找不到,使用 REFRESH 语句会报错。
- HDFS Rebalance 挪动了文件的 block 位置,此时 partition、文件的 mtime 都不变,REFRESH 语句只看 mtime,因此感知不到 block 位置过时了,并不会更新 block 位置。这种情况的后果是查询分片(PlanFragment)会被调度到错误的 Impalad 去执行,导致查询性能变差(Impala以为是本地读,其实变成了远程读)
这个kudu表底层存储是在kudu里面还是hdfs里面?
是保存到kudu里面的,得为kudu专门配置磁盘目录。
补充:
Kudu的存储是不基于HDFS的,构建集群时,kudu很有可能和HDFS共同占用物理磁盘或者云磁盘,理想情况是独立空间。
\