impala 最大的坑(说impala慢,是因为你不知道怎么使用它)

接到任务,impala查询慢。坑比较多。。。。。。

可能大家看到许多博客写优化的比较多,但我这个坑,好像没有人遇到。


优化,我也能列出一些

比如:

1.分区不能超过1w多

2.要执行compute stats xxx 表

3.join时,把小表写前面,会把小表广播到其他节点。

4.选择parquert 格式存储。

5.xxx  

6.xxxxx  

       貌似以上这些都有用,但是在我这场景,没得用。我不是这些问题。





15:30, 我在查询时,秒出,突然刷新任务(15:40)来了,就查询不动了,基本是90秒左右,怀疑是元数据问题。

查看执行计划。

查询信息
查询 ID: a340b2e1956da5d7:f1b4ef43c875493
用户: brd
数据库: default
Coordinator: slave15
查询类型: DDL
查询状态: FINISHED
开始时间: 2017-7-12 16:43:39
结束时间: 2017-7-12 16:43:39
持续时间: 1.3分钟
Admission Result: Unknown
DDL 类型:  
Impala 版本: impalad version 2.5.0-cdh5.7.1 RELEASE (build 27a4325c18c2a01c7a8097681a0eccf6d4335ea1)
Out of Memory: false
会话 ID: 484098c860a3b8d1:5034e7cb74deceaa
会话类型: HIVESERVER2
客户端获取等待时间: 3毫秒
客户端获取等待时间百分比: 1
文件格式:
查询状态: OK
缺少统计数据: false
网络地址: ::ffff:132.225.168.70:50983
规划等待时间: 1.3分钟
规划等待时间百分比: 0
连接用户: brd



Planning finished 耗时长,其实它的前一步是 元数据信息刷新,对比,验证。


源码分析

  result.setQuery_exec_request(queryExecRequest);

    if (analysisResult.isQueryStmt()) {
      // fill in the metadata
      LOG.debug("create result set metadata");
      result.stmt_type = TStmtType.QUERY;
      result.query_exec_request.stmt_type = result.stmt_type;
      TResultSetMetadata metadata = new TResultSetMetadata();
      QueryStmt queryStmt = analysisResult.getQueryStmt();
      int colCnt = queryStmt.getColLabels().size();
      for (int i = 0; i < colCnt; ++i) {
        TColumn colDesc = new TColumn();
        colDesc.columnName = queryStmt.getColLabels().get(i);
        colDesc.columnType = queryStmt.getResultExprs().get(i).getType().toThrift();
        metadata.addToColumns(colDesc);
      }
      result.setResult_set_metadata(metadata);
    } else {
      Preconditions.checkState(analysisResult.isInsertStmt() ||
          analysisResult.isCreateTableAsSelectStmt());

      // For CTAS the overall TExecRequest statement type is DDL, but the
      // query_exec_request should be DML
      result.stmt_type =
          analysisResult.isCreateTableAsSelectStmt() ? TStmtType.DDL : TStmtType.DML;
      result.query_exec_request.stmt_type = TStmtType.DML;

      // create finalization params of insert stmt
      InsertStmt insertStmt = analysisResult.getInsertStmt();
      if (insertStmt.getTargetTable() instanceof HdfsTable) {
        TFinalizeParams finalizeParams = new TFinalizeParams();
        finalizeParams.setIs_overwrite(insertStmt.isOverwrite());
        finalizeParams.setTable_name(insertStmt.getTargetTableName().getTbl());
        finalizeParams.setTable_id(insertStmt.getTargetTable().getId().asInt());
        String db = insertStmt.getTargetTableName().getDb();
        finalizeParams.setTable_db(db == null ? queryCtx.session.database : db);
        HdfsTable hdfsTable = (HdfsTable) insertStmt.getTargetTable();
        finalizeParams.setHdfs_base_dir(hdfsTable.getHdfsBaseDir());
        finalizeParams.setStaging_dir(
            hdfsTable.getHdfsBaseDir() + "/_impala_insert_staging");
        queryExecRequest.setFinalize_params(finalizeParams);
      }
    }

    validateTableIds(analysisResult.getAnalyzer(), result);

    timeline.markEvent("Planning finished");
    result.setTimeline(analysisResult.getAnalyzer().getTimeline().toThrift());
    return result;
  }






Catalogd进程是Impala中用来传递Impala SQL导致的元数据变化的组件,它把这些变化传递给集群中所有的节点。一个集群中只需要一个节点上有这个守护进程,因为请求是通过Statestore传递的,因此Statestored和Catalogd 服务应当运行在同一节点上



所以后来查询问题,找到了,在刷新前查询很快,刷新后,查询不动了。

然后再看怎么刷新的,



问题找到了,每次执行都是invalidate metadata;


去掉后,查询秒出,问题解决。


总结:

       1.invalidate metadata 最好后面跟上表,禁止单独执行该语句(什么都不跟)。

       2. 外部表,如果是hive建立分区,那就需要刷新,刷新是在元数据中更新分区信息。更新过了,直接放入数据。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值