查询加速(MCQA2.0)beta版本

本文为您介绍MaxCompute查询加速升级MCQA2.0(MaxCompute Query Acceleration 2.0)引擎功能,并帮助您了解该功能的系统架构、应用场景、使用限制和使用方法。

功能介绍

MaxCompute MCQA2.0功能提供如下能力:

  • 支持对中小数据量(百GB规模内)查询作业、数据插入作业进行加速优化,最快执行时间为亚秒级。

  • 完全兼容MaxCompute的SQL功能,包括UDF、Delta Table、增量物化视图特性等。

  • 支持隔离的查询加速资源池,独享服务于本租户,稳定性更高。

  • 支持自定义查询加速资源池和批处理资源池的分时资源分配规则,提高资源整体利用率。

  • 支持全链路Cache,作业会自动将多个环节的执行结果写入临时缓存,后续执行的作业在全链路的多个环节都可能命中Cache,加快执行速度。

产品架构

MCQA2.0架构图如下所示。

image

应用场景

MCQA2.0功能的应用场景如下。

场景

说明

场景特点

即席查询(Ad Hoc)

您可以通过MCQA2.0优化中小规模数据集的查询性能,直接对MaxCompute表进行低时延的查询操作,以便快速完成数据开发及数据分析。

您可以根据实际需求,灵活选择查询条件,快速获取查询结果并调整查询逻辑。对查询时延的要求在几十秒内。使用者通常为掌握SQL技能的数据开发或数据分析师,希望使用熟悉的客户端工具开展查询分析。

商业智能(BI)

利用MaxCompute搭建企业级数据仓库时,ETL会将数据加工处理为面向业务可消费的聚合数据。借助MCQA2.0的低延时、资源隔离、弹性并发、数据缓存等特性,结合MaxCompute表分区、分桶等优化设计,可以低成本满足多并发、快速响应的报告生成、统计分析及固定报表分析需求。

查询的数据对象通常为聚合后的结果数据,适用于数据量较小、多维查询、固定查询、高频查询场景。查询延时要求高,秒级返回(例如大部分查询不超过5秒,不同查询作业由于数据规模和查询复杂度不同,查询时间有较大差异)。

海量数据明细查询分析

MCQA2.0可以自动识别查询作业特征,既能快速响应,处理小规模作业,同时还可以自动匹配大规模作业资源需求,满足分析人员分析不同规模和复杂度的查询作业的需求。

需要探索的历史数据量大、真正需要的有效数据量不大、查询延时要求适中。使用者通常为业务分析人员,往往需要从明细数据中探寻业务规律,发现业务机会,验证业务假设。

使用限制

  • 不支持非DDL、DML、DQL类的语句(例如授权操作、Tunnel操作等)在交互式Quota组执行。

  • 交互式Quota组中支持运行UDF,但会涉及UDF隔离环境的现场拉起,为了防止造成性能剧烈波动,对能同时运行UDF的CU数做了限制,最多只有30%的CU能同时运行UDF。

  • 默认最大查询100万行数据,可通过在SQL语句中增加Limit关键字突破此限制。

说明

如果因使用限制导致MCQA2.0作业失败,需要您手动重试或尝试将作业提交到批处理配额组中。

不同CU规格对应的系统参数说明

CU数

最大并行作业数

作业超时时间(min)

单作业并发度上限

< 512CU

200

30

CU 数 * 30

512CU-1024CU

400

60

CU 数 * 30

1024CU-1536CU

600

90

CU 数 * 30

1536CU-2048CU

800

120

CU 数 * 30

2048CU-2560CU

1000

150

CU 数 * 30

2560CU-3072CU

1200

180

CU 数 * 30

3072CU-3584CU

1400

210

CU 数 * 30

3584CU-4096CU

1600

240

CU 数 * 30

4096CU-4608CU

1800

270

CU 数 * 30

4608CU-5120CU

2000

300

CU 数 * 30

5120CU-5632CU

2200

330

CU 数 * 30

5632CU-6144CU

2400

360

CU 数 * 30

操作步骤

说明
  • MCQA2.0功能处于邀测阶段,申请试用请发起工单。

  • 目前仅支持在包年包月MaxCompute实例中使用查询加速升级功能。

  • 整体使用方法为:新建交互式配额组,并在提交作业时指定交互式配额组。该作业只会被调度到对应配额组中执行。

  1. 登录MaxCompute控制台,在左上角选择地域。

  2. 在左侧导航栏,选择工作区 > 配额(Quota)管理

  3. Quota管理页面,单击需要配置的一级Quota操作列的Quota配置

  4. 配置基础配置。

    1. Quota配置页面的基础配置页签,单击编辑基础配置

    2. 单击+新建二级Quota后,自定义填写Quota名称,并选择类型交互式

    3. 配置最小CU量(minCU)和最大CU量(maxCU)。

      说明
      • 最小CU量(minCU)需要等于最大CU量(maxCU),且需要为32的倍数。

      • 如果不需要交互式资源,设置为0

      • 交互式类型的Quota不支持弹性预留CU。

    4. 单击确定,完成新增交互式配额组。

      对应交互式配额组的最后部分会出现状态展示为启动中,等待5分钟左右,当状态变为运行中以后,即可正常使用。

  5. (可选)配置伸缩配置。

  6. (可选)配置时间计划。

    配置时间计划设置每日不同时间点启用不同的Quota计划,以此实现对Quota配置的分时逻辑,配置详情请参见计算资源-Quota管理

说明
  • 若希望对交互式配额组进行扩、缩容,可以在基础配置中调大或调小CU量。

  • 若需删除交互式配额组,可直接单击删除,后台会自动完成相关销毁动作。

提交作业

使用MCQA2.0功能进行DataWorksIDE临时查询或数据开发

在DataWorks数据开发(新版)页面新建MaxCompute SQL节点后,在右侧的调试配置面板中可以选择计算配额,选择交互式配额组以后,数据开发(新版)页面执行的作业将会被调度到交互式配额组执行。如果返回结果的InstanceId带有_mcqa的后缀,则代表成功运行到了MCQA2.0模式。

使用MCQA2.0功能进行MaxCompute控制台TopConsolo-SQL分析

MaxCompute控制台SQL分析页面右侧的运行参数可以选择计算配额,选择交互式配额组以后,SQL分析页面执行的作业将会被调度到交互式配额组执行。如果返回结果的InstanceId带有_mcqa的后缀,则代表成功运行到了MCQA2.0模式。

通过JDBC使用MCQA2.0功能

您可以通过以下操作开启MCQA2.0功能,并使用JDBC连接MaxCompute,详情请参见使用说明

  1. 下载支持MCQA2.0功能的JDBC JAR包或可编译的源代码

  2. 通过Maven方式配置Pom依赖。

    说明

    此处以3.8.0-rc0版本为例配置Pom依赖,您可根据实际自行选择3.8.0-rc0或以上版本,推荐使用最新版本。

    <dependency>
        <groupId>com.aliyun.odps</groupId>
        <artifactId>odps-jdbc</artifactId>
        <version>3.8.0-rc0</version>
    </dependency>
  3. 基于源代码创建Java程序,适配实际信息,详情请参见MaxCompute JDBC,示例如下。

    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户
    // 此处以把AccessKey 和 AccessKeySecret 保存在环境变量为例说明。您也可以根据业务需要,保存到配置文件里
    // 强烈建议不要把 AccessKey 和 AccessKeySecret 保存到代码里,会存在密钥泄漏风险
    private static String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
    private static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
    //your_project_name为需要使用MCQA功能的项目名称。
    //your_quota_nick_name为期望使用的交互式Quota组的名字
    String conn = "jdbc:odps:http://service.<regionid>.maxcompute.aliyun.com/api?project=<YOUR_PROJECT_NAME>"&accessId&accessKey&charset=UTF-8&interactiveMode=true&quotaName=<your_quota_nick_name>&autoSelectLimit=1000000000";
    Statement stmt = conn.createStatement();
    Connection conn = DriverManager.getConnection(conn, accessId, accessKey);
    Statement stmt = conn.createStatement();
    String tableName = "testOdpsDriverTable";
    stmt.execute("DROP TABLE IF EXISTS " + tableName);
    stmt.execute("CREATE TABLE " + tableName + " (key int, value string)");

    您也可以在连接串中配置如下参数,完善处理逻辑。

    参数

    说明

    enableOdpsLogger

    用于打印日志。未配置SLF4J时,建议您将此参数配置为True。

使用示例

以下为您展示在Tableau和SQLWorkbench中使用MCQA2.0时的服务器配置方法。

  • 示例1:Tableau使用MCQA2.0

    服务器增加interactiveMode=truequotaName=your_quota_nick_name属性,用于开启MCQA2.0功能。建议您同步增加enableOdpsLogger=true属性,用于打印日志。配置操作详情请参见配置JDBC使用Tableau

    完整的服务器配置示例如下。

    // <your_quota_nick_name>为期望使用的交互式Quota组的名字
    http://service.cn-beijing.maxcompute.aliyun.com/api?
    project=****_beijing&interactiveMode=true&quotaName=<your_quota_nick_name>&enableOdpsLogger=true&autoSelectLimit=1000000000"

    如果只对项目空间中的部分表进行Tableau操作,您可以在服务器参数中增加table_list=table_name1, table_name2属性选择需要的表,多表之间用半角逗号(,)分隔。如果表过多,会导致Tableau打开缓慢,强烈建议使用此方式只载入需要的表。

    示例如下,对于有大量分区的表不建议将所有分区的数据都设置成数据源,可以筛选需要的分区或通过自定义SQL获取需要的数据。

    //your_quota_nick_name为期望使用的交互式 Quota 组的名字
    http://service.cn-beijing.maxcompute.aliyun.com/api?project=****_beijing
    &interactiveMode=true&alwaysFallback=true&quotaName=<YOUR_QUOTA_NICK_NAME>&enableOdpsLogger=true&autoSelectLimit=1000000000"
    &table_list=orders,customers
  • 示例2:SQLWorkBench使用MCQA2.0

    完成JDBC驱动配置后,在Profile配置界面修改已填写的JDBC URL,支持SQLWorkbench使用MCQA2.0功能。Profile配置操作详情请参见配置JDBC使用SQL Workbench/J

    需要配置的URL格式如下所示:

    //your_quota_nick_name为期望使用的交互式 Quota 组的名字
    jdbc:odps:<MaxCompute_endpoint>?
    project=<MaxCompute_project_name>&accessId=<AccessKey ID>&accessKey=<AccessKey Secret>
    &charset=UTF-8&interactiveMode=true&quotaName=<YOUR_QUOTA_NICK_NAME>&autoSelectLimit=1000000000"

    参数说明如下。

    参数

    说明

    MaxCompute_endpoint

    MaxCompute服务所在区域的Endpoint,详情请参见Endpoint

    MaxCompute_project_name

    MaxCompute项目空间名称。

    AccessKey ID

    有访问指定项目空间权限的AccessKey ID。

    您可以进入AccessKey管理页面获取AccessKey ID。

    AccessKey Secret

    AccessKey ID对应的AccessKey Secret。

    您可以进入AccessKey管理页面获取AccessKey Secret。

    your_quota_nick_name

    期望使用的交互式Quota组的名称。

    charset=UTF-8

    字符集编码格式。

    interactiveMode

    MCQA2.0功能开关,true表示开启MCQA功能。

    quotaName

    期望使用的交互式 Quota 组名字

    autoSelectLimit

    数据量超过100万限制时,需要配置此参数。

基于Java SDK启用MCQA2.0功能

Java SDK详情请参见Java SDK介绍。您需要通过Maven配置Pom依赖,配置示例如下。

说明

此处以0.50.0-rc1版本为例配置Pom依赖,您可根据实际自行选择0.50.0-rc1或以上版本,推荐使用最新版本。

<dependency>
    <groupId>com.aliyun.odps</groupId>
    <artifactId>odps-sdk-core</artifactId>
    <version>0.50.0-rc1</version>
</dependency>

创建Java程序,命令示例如下。

import ...;

public class SQLExecutorExample {

  public static void main(String args[]) {
    // 设置账号和项目信息。
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户
    // 此处以把AccessKey 和 AccessKeySecret 保存在环境变量为例说明。您也可以根据业务需要,保存到配置文件里
    // 强烈建议不要把 AccessKey 和 AccessKeySecret 保存到代码里,会存在密钥泄漏风险
    Account
        account =
        new AliyunAccount(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                          System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
    Odps odps = new Odps(account);
    odps.setDefaultProject("<YOUR_PROJECT_NAME>");
    odps.setEndpoint("http://service.<regionid>.maxcompute.aliyun.com/api");

    // 准备构建SQLExecutor。
    SQLExecutorBuilder builder = SQLExecutorBuilder.builder();

    SQLExecutor sqlExecutor = null;
    try {
      // 创建一个默认使用 MCQA2.0 模式的Executor。
      sqlExecutor = builder.odps(odps)
          .executeMode(ExecuteMode.INTERACTIVE)
          .quotaName("<YOUR_INTERACTIVE_QUOTA_NICKNAME>")
          .enableMcqaV2(true)
          .build();

      // 如果需要的话可以传入查询的特殊设置。
      Map<String, String> queryHint = new HashMap<>();
      queryHint.put("odps.sql.mapper.split.size", "128");
      // 提交一个查询作业,支持传入Hint。
      sqlExecutor.run("select count(1) from test_table;", queryHint);
      
      // 当前查询作业的logview。
      System.out.println("Logview:" + sqlExecutor.getLogView());
      // 当前查询作业的InstanceId
      System.out.println("InstanceId:" + sqlExecutor.getQueryId());
      
      ResultSet resultSet = sqlExecutor.getResultSet();
      while (resultSet.hasNext()) {
        System.out.println(resultSet.next());
      }
      // run another query
      sqlExecutor.run("select * from test_table;", new HashMap<>());

      // 获取查询结果的迭代器ResultSet,同步接口,可能会占用本线程直到查询成功或失败。
      // 获取大量结果数据时推荐使用,分次读取查询结果。
      ResultSet resultSet = sqlExecutor.getResultSet();
      while (resultSet.hasNext()) {
        System.out.println(resultSet.next());
      }

    } catch (OdpsException | IOException e) {
      e.printStackTrace();
    } finally {
      if (sqlExecutor != null) {
        // 关闭Executor释放相关资源。
        sqlExecutor.close();
      }
    }
  }
}