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



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

    Impala on Hive介绍


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

    1. mysql> show tables in hive;
    2. +---------------------------+
    3. | Tables_in_hive            |
    4. +---------------------------+
    5. | BUCKETING_COLS            |
    6. | CDS                       |
    7. | 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的含义就是“废除(缓存的)元数据”。它的语法是:

    1. invalidate metadata;           -- 废除所有表的元数据
    2. 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的意思比较简单,“刷新”。它的语法是:

    1. refresh [table];                           -- 刷新表table的元数据
    2. 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来得高效一些。
       
  • 相关阅读:
    前端常见vue面试题合集
    不同版本Ubuntu安装Docker及Docker desktop
    SQL中通过QUALIFY语法过滤窗口函数简化代码
    17-CSS3过渡
    输入支付密码加密流程,技术层面
    【校招VIP】“推推”产品项目课程:产品的脑图分析
    vue学习之v-if/v-else/v-else-if
    长期戴耳机的危害有哪些?有哪些耳机不伤听力吗?
    PyCharm 2022.2 发布了,支持最新 Python 3.11 和 PyScript 框架!
    centos7.6 MySQL 5.5 主从同步配置
  • 原文地址:https://blog.csdn.net/javastart/article/details/126154190