美文网首页
正确使用Impala的invalidate metadata与r

正确使用Impala的invalidate metadata与r

作者: LittleMagic | 来源:发表于2019-10-06 23:18 被阅读0次

    在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                |
    | COMPACTION_QUEUE          |
    | COMPLETED_TXN_COMPONENTS  |
    | DATABASE_PARAMS           |
    | DBS                       |
    | DB_PRIVS                  |
    | DELEGATION_TOKENS         |
    | FUNCS                     |
    | FUNC_RU                   |
    | GLOBAL_PRIVS              |
    | HIVE_LOCKS                |
    | IDXS                      |
    | INDEX_PARAMS              |
    | MASTER_KEYS               |
    | METASTORE_DB_PROPERTIES   |
    | NEXT_COMPACTION_QUEUE_ID  |
    | NEXT_LOCK_ID              |
    | NEXT_TXN_ID               |
    | NOTIFICATION_LOG          |
    | NOTIFICATION_SEQUENCE     |
    | NUCLEUS_TABLES            |
    | PARTITIONS                |
    | PARTITION_EVENTS          |
    | PARTITION_KEYS            |
    | PARTITION_KEY_VALS        |
    | PARTITION_PARAMS          |
    | PART_COL_PRIVS            |
    | PART_COL_STATS            |
    | PART_PRIVS                |
    | ROLES                     |
    | ROLE_MAP                  |
    | SDS                       |
    | SD_PARAMS                 |
    | SEQUENCE_TABLE            |
    | SERDES                    |
    | SERDE_PARAMS              |
    | SKEWED_COL_NAMES          |
    | SKEWED_COL_VALUE_LOC_MAP  |
    | SKEWED_STRING_LIST        |
    | SKEWED_STRING_LIST_VALUES |
    | SKEWED_VALUES             |
    | SORT_COLS                 |
    | TABLE_PARAMS              |
    | TAB_COL_STATS             |
    | TBLS                      |
    | TBL_COL_PRIVS             |
    | TBL_PRIVS                 |
    | TXNS                      |
    | TXN_COMPONENTS            |
    | TYPES                     |
    | TYPE_FIELDS               |
    | VERSION                   |
    +---------------------------+
    54 rows in set (0.00 sec)
    

    它的组织方式与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. I获取到表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 tabledrop tablealter table add column等,就使用invalidate metadata [table]语句。
    • 如果数仓中某表加入了新数据,或者有分区的改动,如load dataalter table add partition等,就使用refresh [table] (partition [partition])语句。
    • invalidate metadata比起refresh而言要重量级得多,并且它造成impalad之间查询不一致也会更严重。因此,也几乎禁止使用不带表名的invalidate metadata语句。
    • 如果数仓中涉及到非常大批量的元数据更改,那么建议直接重启catalogd和statestored,这总比使用不带表名的invalidate metadata来得高效一些。

    相关文章

      网友评论

        本文标题:正确使用Impala的invalidate metadata与r

        本文链接:https://www.haomeiwen.com/subject/egeppctx.html