首先了解一下:Impala如何融入Hadoop生态系统
Impala使用了Hadoop生态系统中许多熟悉的组件。Impala可以作为消费者和生产者与其他Hadoop组件交换数据,因此它可以以灵活的方式适合您的ETL和ELT管道。
How Impala Works with Hive
Impala的一个主要目标是使SQL-on-Hadoop操作足够快速和高效,以吸引新的用户类别,并向新的用例类型开放Hadoop。在实用的情况下,它利用现有的Apache Hive基础设施(许多Hadoop用户已经拥有这些基础设施)来执行长时间运行的、面向批处理的SQL查询。
特别是,Impala将它的表定义保存在传统的MySQL或PostgreSQL数据库(称为metastore)中,Hive将这类数据保存在这个数据库中。因此,只要所有列都使用Impala支持的数据类型、文件格式和压缩编解码器,Impala就可以访问Hive定义或加载的表。
最初关注查询特性和性能意味着Impala可以用SELECT语句读取比用INSERT语句写入更多类型的数据。要使用Avro、RCFile或SequenceFile文件格式查询数据,可以使用Hive加载数据。
Impala查询优化器还可以使用表统计信息和列统计信息。最初,您使用Hive中的analysis TABLE语句收集这些信息;在Impala 1.2.2或更高版本中,使用Impala COMPUTE STATS语句。计算统计需要更少的设置,更可靠,不需要在impala-shell和Hive shell之间来回切换
Overview of Impala Metadata and the Metastore
正如在《Impala如何与Hive一起工作》中讨论的,Impala在名为metastore的*数据库中维护关于表定义的信息。Impala还跟踪数据文件低层特征的其他元数据:
HDFS中块的物理位置。对于具有大量数据或多个分区的表,检索表的所有元数据可能非常耗时,在某些情况下需要几分钟。因此,每个Impala节点缓存所有这些元数据,以便将来对同一个表进行查询时重用。
如果更新了表定义或表中的数据,则集群中的所有其他Impala守护进程必须在对该表发出查询之前接收最新的元数据,替换已过期的缓存元数据。
在Impala 1.2及更高版本中,对于通过Impala发出的所有DDL和DML语句,元数据更新是自动的,通过catalogd守护进程进行协调。
通过hive中DDL和DML发行,或手动更改在HDFS文件,你仍然使用REFRESH语句(当新的数据文件被添加到现有表)或失效元数据语句(全新的表,或删除一个表后,执行一个HDFS平衡操作,或删除数据文件)。发出INVALIDATE METADATA本身将检索由metastore跟踪的所有表的元数据。如果您知道只有特定的表在Impala之外被更改,那么您可以为每个受影响的表发出REFRESH table_name,以仅检索这些表的最新元数据
How Impala Uses HDFS
Impala使用分布式文件系统HDFS作为它的主要数据存储介质。Impala依靠HDFS提供的冗余来防止单个节点上的硬件或网络中断。Impala表数据使用熟悉的HDFS文件格式和压缩编解码器在HDFS中物理地表示为数据文件。当新表的目录中出现数据文件时,Impala将读取所有文件,而不考虑文件名。新数据被添加到由Impala控制名称的文件中
INVALIDATE METADATA Statement
将一个或所有表的元数据标记为陈旧的。在通过Hive shell创建表之后,在该表可用于Impala查询之前,都是必需的。下次当前Impala节点对元数据无效的表执行查询时,Impala将在查询继续之前重新加载相关的元数据。与REFRESH语句执行的增量元数据更新相比,这是一个相对昂贵的操作,因此在向现有表添加新数据文件的常见场景中,最好使用REFRESH而不是使元数据失效。
语法:INVALIDATE METADATA [[db_name.]table_name]
默认情况下,所有表的缓存元数据都被刷新。如果指定表名,则只刷新该表的元数据。即使对于单个表,INVALIDATE METADATA也比REFRESH更昂贵,所以在为现有表添加新数据文件的常见情况下,请选择REFRESH。
INVALIDATE METADATA 和REFRESH是对应的:INVALIDATE METADATA 在后续查询需要时等待重新加载元数据,但是会重新加载表的所有元数据,这可能是一项昂贵的操作,尤其是对于有很多分区的大型表。REFRESH会立即重新加载元数据,但只加载新添加数据文件的块位置数据,从而降低了整体操作的开销。如果数据被以更广泛的方式更改,例如由HDFS平衡器重新组织,则使用INVALIDATE元数据来避免由于减少本地读取而导致的性能损失。Impala 1.1 REFRESH针对向现有表添加新数据文件的常见用例进行了优化,因此现在需要表名参数。
使用注意:
INVALIDATE METADATA是用于刷新全库或者某个表的元数据,包括表的元数据和表内的文件数据,它会首先清楚表的缓存,然后从metastore中重新加载全部数据并缓存,该操作代价比较重,主要用于在hive中修改了表的元数据,需要同步到impalad,例如create table/drop table/alter table add columns等。
语法:REFRESH [table] PARTITION [partition]
REFRESH是用于刷新某个表或者某个分区的数据信息,它会重用之前的表元数据,仅仅执行文件刷新操作,它能够检测到表中分区的增加和减少,主要用于表中元数据未修改,数据的修改,例如INSERT INTO、LOAD DATA、ALTER TABLE ADD PARTITION、LLTER TABLE DROP PARTITION等,如果直接修改表的HDFS文件(增加、删除或者重命名)也需要指定REFRESH刷新数据信息。
使用原则
如果在使用过程中涉及到了元数据或者数据的更新,则需要使用这两者中的一个操作完成,具体如何选择需要根据如下原则:
1)invalidate metadata操作比refresh要重量级
2)如果涉及到表的schema改变,使用invalidate metadata [table]
3)如果只是涉及到表的数据改变,使用refresh [table]
4)如果只是涉及到表的某一个分区数据改变,使用refresh [table] partition [partition]
5)禁止使用invalidate metadata什么都不加,宁愿重启catalogd。(注:项目中可以使用这种)
总结
REFRESH和INVALIDATE METADATA对于impala而言是比较重要的两个操作,分别处理数据和元数据的修改,其中REFRESH操作是同步的,INVALIDATE METADATA是异步的,本文详细介绍了两种语句的适用场景和执行原理,以及可能造成的影响,最重要的是,需要谨记这两种查询使用场景。
参考文档:https://www.cloudera.com/documentation/enterprise/5-11-x/topics/impala_langref_sql.html#langref_sql