impala两种方式同步hive元数据

基础知识


Impala采用多个impalad(impala的核心进程)同时提供服务的方式,并且它会由catalogd(元数据管理和元数据存储)缓存全部元数据,再通过statestored(状态管理进程)完成每一次的元数据的更新到impalad节点上,Impala集群会缓存全部的元数据

Impala在传统的MySQL或PostgreSQL数据库称为Metastore,Hive也在其相同的数据库上保存此类型的数据。因此,Impala可以访问由Hive定义或加载的表,也就是说impala的操作对于hive来说是透明的,hive对于impala的操作也是透明的。

这种缓存机制既有优点,也有缺点,优点在于:对于具有大量数据或多个分区的表,检索表内所有元数据可能会花费很长时间,在某些情况下需要几分钟,每 个Impala节点缓存所有这些数据,以便在未来对同一表进行查询时重复使用,这样就可以节省很多不必要的时间。缺点在于:会导致通过其他手段更新元数据或者数据对于Impala是无感知的,例如通过hive建表,直接拷贝新的数据到HDFS上等。

但是Impala提供了两种机制来实现元数据的更新,分别是INVALIDATE METADATA和REFRESH操作

INVALIDATE


原理

INVALIDATE METADATA翻译成中文就是“作废元数据”的意思。
对于INVALIDATE METADATA操作,由客户端将查询提交到某个impalad节点上,执行如下的操作:

  • 1.获取需要执行INVALIDATE METADATA的表,如果没指定表则表示全部表,也就是如下的命令讲解。
  • 2.请求catalogd执行resetMetadata操作,并将isFresh参数设置为false。
  • 3.catalogd接收到该请求之后执行invalidateTable操作,将该表的缓存清除,然后重新生成该表的缓存对象,新生成的对象只包含表名+库名的信息,然后为新生成的表对象生成一个新的catalog版本号(假设新的version=1),将这部分信息返回给调用方(impalad),然后异步执行元数据和数据的加载。
  • 4.impalad收到catalogd的返回值,返回值是更新之后的表缓存对象+版本号,但是这是一个不完整的表元数据,impalad将这个元数据应用到本地元数据缓存。
  • 5.INVALIDATE METADATA执行完成。

INVALIDATE METADATA操作带来的副作用是生成一个新的未完成的元数据对象,对于操作请求的impalad(称它为impalad-A),能够立马获取到该对象,对于其它的impalad必须通过statestored同步,执行完该操作,因此处理该操作的impalad对于该表的缓存是一个新的但是不完整的对象,其余的impalad保存的是旧的元数据。

对于后续的该表查询操作,分为如下四种情况:

  • 1.如果catalogd已经完成该表所有元数据加载,会对该表生成一个新的版本号(假设version=2),然后更新到statestored,由statestored广播到各个impalad节点上,此时所有的查询都查询到最新的元数据和数据。

  • 2.如果catalogd尚未完成表的元数据加载或者statestored未广播完成,并且接下来请求到impalad-A(之前执行INVALIDATE METADATA的节点),此时impalad在执行语义分析的时候能够检测到表的元数据不完整(因为当前只有表名和库名,没有任何其余的元数据),impalad会直接请求catalogd获取该表最新的元数据,如果catalogd尚未完成元数据加载,则该请求会等到直到catalogd加载完成并返回impalad最新的元数据。

  • 3.如果catalogd尚未完成表的元数据加载或statestored未广播完成,接下来请求到了其他的impalad节点,如果接受请求的impalad尚未通过statestored同步新的不完整的表元数据(version=1),则该impalad中缓存的关于该表的元数据是执行INVALIDATE METADATA之前的,因此根据旧的元数据处理该查询(可能因为文件被删除导致错误)。

  • 4.如果catalogd尚未完成表的元数据加载,接下来请求到了其他的impalad节点,如果接受请求的impalad已经通过statestored同步新的不完整的表元数据(version=1),那么接下来会像第二种情况一样处理。

从INVALIDATE METADATA的实现来看,该操作不仅仅会全量加载表的元数据和分区、文件元数据,还会影响后面关于该表的查询。因此、生产环境中的日常操作中尽量避免使用,或者是在资源充足的情况下。

使用方式

INVALIDATE METADATA是用于刷新全库或者某个表的元数据,包括表的元数据和表内的文件数据,它会首先清除表的缓存,然后从metastore中重新加载全部数据并缓存,该操作代价比较重,需要消耗大量的资源和时间,主要用于在hive中修改了表的元数据,需要同步到impalad,例如create table/drop table/alter table add columns等。

语法:

//重新加载所有库中的所有表
INVALIDATE METADATA
//重新加载指定的某个表
INVALIDATE METADATA [table]

例子:

[hadoop1:21000] > INVALIDATE METADATA ;
Query: invalidate METADATA
Query submitted at: 2017-08-23 14:02:18 (Coordinator: http://hadoop1:25000)
Query progress can be monitored at: http://hadoop1:25000/query_plan?query_id=c444a93cf1fdc74b:f5c0277900000000
Fetched 0 row(s) in 3.24s            

[hadoop1:21000] > INVALIDATE METADATA my_db.student_1;
Query: invalidate METADATA my_db.student_1
Query submitted at: 2017-08-23 14:00:40 (Coordinator: http://hadoop1:25000)
Query progress can be monitored at: http://hadoop1:25000/query_plan?query_id=9d46d92989df4809:76017dcf00000000
Fetched 0 row(s) in 0.01s    

REFRESH


原理

对于REFRESH操作,由客户端将查询提交到某个impalad节点上,执行如下的操作:

  • 1.获取需要执行REFRESH的表和分区信息。

  • 2.请求catalogd执行resetMetadata操作,并将isFresh参数设置为true。

  • 3.catalogd接收到该请求之后判断是否指定分区,如果指定了分区则执行reload partition操作,如果未指定则执行reload table操作,对于reloadPartition则从metastore中读取partition最新的元数据,然后刷新该partition拥有的所有文件的元数据(大小,权限,数据分布等);对于reloadTable则从metadata中读取全部的partition信息,然后和缓存中的partition进行比对判断是否有分区需要增加和删除,对于其余的分区则执行元数据的更新。

  • 4.impalad收到catalogd的返回值,返回值是更新之后该表的缓存数据,impalad会将该数据更新到自己的缓存中。因此接受请求的impalad能够将当前元数据缓存。

  • 5.REFRESH执行完成。

对于后续的查询,分为如下两种情况:

  • 1.如果查询提交到到执行REFRESH的impalad节点,那么查询能够使用最新的元数据。

  • 2.如果查询提交到其他impalad节点,需要依赖于该表更新后的缓存是否已经同步到impalad中,如果已经完成了同步则可以使用最新的元数据,如果未完成则使用旧的元数据。

可以看出REFRESH操作较之于INVALIDATE METADATA是轻量级的操作,如果更改只涉及到一个分区设置可以只刷新一个分区的元数据,并且它是同步的,对于之后查询的影响较小。

使用方式

REFRESH是用于刷新某个表或者某个分区的数据信息,它会重用之前的表元数据,仅仅执行文件刷新操作,它能够检测到表中分区的增加和减少,主要用于表中元数据未修改,数据的修改,例如INSERT INTO、LOAD DATA、ALTER TABLE ADD PARTITION、LLTER TABLE DROP PARTITION等,如果直接修改表的HDFS文件(增加、删除或者重命名)也需要指定REFRESH刷新数据信息。

语法:

//刷新某个表
REFRESH [table] 
//刷新某个表的某个分区
REFRESH [table] PARTITION [partition]

例子:

[hadoop1:21000] > refresh student_2;
Query: refresh student_2
Query submitted at: 2017-08-23 13:23:10 (Coordinator: http://hadoop1:25000)
Query progress can be monitored at: http://hadoop1:25000/query_plan?query_id=344e443a1a0da210:70b68a7200000000
Fetched 0 row(s) in 0.15s
[hadoop1:21000] > refresh student_2 partition date;

总结


1.hue中要使用Perform incremental metadata update,不要使用Invalidate all metadata and rebuild index,如果是invalidate metadata什么都不加,宁愿重新启动catalogd。
2.如果涉及到表的schema改变,使用invalidate metadata [table]
3.如果只是涉及到表的数据改变,使用refresh [table]
4.如果只是涉及到表的某一个分区数据改变,使用refresh [table] partition [partition]
5.invalidate metadata操作比refresh要重量级。

你可能感兴趣的:(impala)