正确使用Impala的invalidate metadata与refresh语句


在Impala中,invalidate metadata与refresh语句都可以用来刷新表,但它们本质上还是不同的。本文简要分析一下,并说明它们应该在什么情况下使用。

Impala on Hive介绍


我们一般会采用传统的MySQL或PostgreSQL数据库作为Hive的Metastore(元数据存储)组件。在CDH中默认是MySQL,我们可以通过show tables in hive语句清晰地看到Hive Metastore中的各个表。

mysql> show tables in hive;
+---------------------------+
| Tables_in_hive            |
+---------------------------+
| BUCKETING_COLS            |
| CDS                       |
| COLUMNS_V2                |


它的组织方式与MySQL中的information_schema类似。如TBLS保存有所有表的元数据,COLUMNS保存有所有列的元数据,PARTITIONS存储分区信息,SDS存储表及分区对应的HDFS目录映射,等等。

Impala作为一个MPP查询引擎,经常会配合Hive一同使用,我们的业务中也是如此。下图示出Impala及周边组件的大体结构。


Impala的核心组件是impalad,它负责提供所有查询服务。另外,还有catalogd负责获取与缓存表元数据,statestored则负责表元数据到每个impalad的更新。

这种方案完美解决了每次查询都要获取表元数据的问题,因为一旦表结构非常复杂或者数据很多,获取元数据会造成很大的延迟。如果将它们缓存下来,元数据就可以重用,节省时间。

但是,它又带来了一个新的问题:由于缓存不会即时刷新,当在Hive本身进行元数据甚至数据的更改时,Impala无法感知到。常见的情境如在Hive中新建了一张表,或者直接在Hive表对应的HDFS目录中新增文件等。所以,Impala才提供了invalidate metadata与refresh两条语句来打补丁。

invalidate metadata


invalidate的意思是“使无效、使作废”,因此invalidate metadata的含义就是“废除(缓存的)元数据”。它的语法是:

invalidate metadata;           -- 废除所有表的元数据
invalidate metadata [table];   -- 废除表table的元数据


如果在某个impalad(简称为I)上执行了invalidate metadata table语句,会发生如下的动作:

  1. 获取到表table,对catalogd发起resetMetadata请求;
  2. catalogd收到该请求,执行invalidateTable操作,清除所有与table相关的元数据缓存,重新读取Metastore中的所有元数据,并生成新的缓存。但是此时生成的缓存只包含库名和表名,是不完整的;
  3. catalogd再生成一个标记缓存的版本号,将这个不完整的缓存和版本号一起返回给I,然后继续异步加载其余的元数据;
  4. I收到catalogd返回的不完整缓存和版本号,用它来更新本地缓存。

invalidate metadata的特点就是异步性和全量性。从上面可以看出,在刚执行完时,除了I之外的其他impalad仍然保有旧的元数据缓存,就算I保有的新元数据也是残缺的。只有当catalogd异步加载完了table对应的所有元数据,才会生成一个更新的版本号,并将完整的元数据通过statestored广播给所有impalad,整个Impala集群的元数据感知才会达到一致。

refresh


refresh的意思比较简单,“刷新”。它的语法是:

refresh [table];                           -- 刷新表table的元数据
refresh [table] partition [partition];     -- 刷新表table的partition分区元数据


在I上执行refresh table语句会发生如下的动作:

  1. I获取到表table,对catalogd发起resetMetadata请求;
  2. catalogd收到该请求:对指定了partition的请求,执行reloadPartition操作,获取该分区最新的元数据并刷新;对未指定partition的请求,执行reloadTable操作,获取全部分区最新的元数据并刷新。这里的“刷新”是指Metastore中与缓存对比如果没有变化,就保持原状;如果有增删改,才会发生改变;
  3. I收到catalogd返回的完整缓存,用它来更新本地缓存。

当然,statestored仍会负责广播新的元数据到其他节点。在广播完之前,除了I之外的其他impalad也保有旧的缓存。

由此可见,与invalidate metadata不同,refresh的特点是同步性和增量性。并且,它的执行是围绕单表以及单表的分区进行的,因此它更轻量级,也更适合分区元数据或数据文件更改之后的刷新。

如何正确使用


通过上面的简单分析,容易做出以下总结:

  • 如果数仓中发生了增删表或改变表结构的行为,如create table、drop table、alter table add column等,就使用invalidate metadata [table]语句。
  • 如果数仓中某表加入了新数据,或者有分区的改动,如load data、alter table add partition等,就使用refresh [table] (partition [partition])语句。
  • invalidate metadata比起refresh而言要重量级得多,并且它造成impalad之间查询不一致也会更严重。因此,也几乎禁止使用不带表名的invalidate metadata语句。
  • 如果数仓中涉及到非常大批量的元数据更改,那么建议直接重启catalogd和statestored,这总比使用不带表名的invalidate metadata来得高效一些。
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值