本文为您介绍如何通过阿里云性能测试PTS对Hologres的性能进行压测,帮助您快速验证Hologres的性能。

背景信息

Hologres是兼容PostgreSQL协议的实时交互式分析引擎,可以使用pgbench工具对其进行性能测试,详情请参见测试方案介绍。但测试过程可能会受到网络、测试参数配置等多方面因素的干扰,导致测试结果受到影响。测试环境的搭建也需要花费较多精力。

阿里云性能测试PTS(Performance Testing Service)是一个具备分布式压测能力的SaaS压测平台,可以模拟复杂的测试场景,并快速精准地调度不同规模的流量,同时提供压测过程中多维度的监控指标和日志记录。您无需准备资源,即可按需发起压测任务、监控压测指标和获取压测报告,进而高效率、全方位地验证产品性能。关于性能测试PTS的详细信息请参见什么是性能测试PTS

本实践通过性能测试PTS使用TPC-H(商业智能计算测试)对Hologres在OLAP查询场景、Key/Value点查场景和数据更新场景的性能进行测试。
说明 本文的TPC-H的实现基于TPC-H的基准测试,并不能与已发布的TPC-H基准测试结果相比较,本文中的测试并不符合TPC-H基准测试的所有要求。

前提条件

  • 已购买并开通Hologres实例,开通方法请参见购买Hologres
  • 已开通性能测试PTS,详情请参见开通方式。推荐使用按量抵扣(预付费)-内网专享版,使用阿里云VPC内网进行压测,可以提高测试结果准确性、降低测试成本,详情请参见按量抵扣(预付费)

场景说明

本实践压测场景主要包含如下场景,场景详情请参见测试方案介绍
  • OLAP查询场景:主要使用列存表,使用TPC-H测试中的22条查询语句进行测试。
  • Key/Value点查场景:主要使用行存表,针对ORDERS使用行存表后,进行主键过滤的点查。
  • 数据更新场景:主要用于测试OLAP引擎在有主键的情况下数据更新的性能。
说明 如果PTS采用按量抵扣模式,费用根据计费项VUM消耗量进行计算。VUM消耗量=施压机数×单机并发数×压测时长(分钟),其中单机并发数为固定值500。以本文的测试场景为例,VUM消耗量分别为:
  • OLAP查询场景:1(使用资源IP数,即施压机数)×500×110(分钟)=55000 (VUM)
  • Key/Value点查场景:25(使用资源IP数,即施压机数)×500×5(分钟)=62500 (VUM)
  • 数据更新场景:与Key/Value点查场景一致。
如果选择按量抵扣(预付费)-内网专享版模式,仅需花费58元,购买20万VUM额度,即可完成一轮上述场景测试。

本文中的价格信息仅为示例值,实际使用过程中请以产品购买页价格为准。

准备工作

通过使用PTS进行性能压测,您无需准备测试所需的基础环境,但您仍需针对不同的测试场景准备相应数据及测试语句。
  • OLAP查询场景:需要创建列存表,从数据源中同步数据,设计OLAP查询测试语句。
  • Key/Value点查场景:需要创建行存表,从数据源中同步数据,设计Key/Value点查测试语句。
  • 数据更新场景:需要创建表,写入原始数据,并准备需要进行更新的数据。
    说明
    • Hologres支持多种数据源的数据同步,包括MaxCompute数据同步、OSS数据湖同步、通过Copy命令导入本地文件、通过DataWorks同步MySQL等数据库数据等,详情参见数据同步概述
    • 创建Hologres内部表的同时,需要为其设置合适的索引,以获得最优的查询性能。关于索引的创建,详情请参见建表概述
本实践以MaxCompute数据源为例,将MaxCompute公共空间MAXCOMPUTE_PUBLIC_DATA中的TPC-H 100 GB数据写入Hologres,作为本实践的测试数据。

OLAP查询场景

  • 测试数据准备
    Hologres支持连接多种开发工具,您可以使用HoloWeb登录Hologres实例,创建数据库并在SQL编辑器中执行如下语句,完成内部表、外部表的创建和写入测试数据。关于HoloWeb的简介与使用方法,请参见HoloWeb简介
    • 创建外部表。
      DROP FOREIGN TABLE IF EXISTS odps_customer_100g;
      DROP FOREIGN TABLE IF EXISTS odps_lineitem_100g;
      DROP FOREIGN TABLE IF EXISTS odps_nation_100g;
      DROP FOREIGN TABLE IF EXISTS odps_orders_100g;
      DROP FOREIGN TABLE IF EXISTS odps_part_100g;
      DROP FOREIGN TABLE IF EXISTS odps_partsupp_100g;
      DROP FOREIGN TABLE IF EXISTS odps_region_100g;
      DROP FOREIGN TABLE IF EXISTS odps_supplier_100g;
      
      IMPORT FOREIGN SCHEMA "MAXCOMPUTE_PUBLIC_DATA#default" LIMIT to
      (
          odps_customer_100g,
          odps_lineitem_100g,
          odps_nation_100g,
          odps_orders_100g,
          odps_part_100g,
          odps_partsupp_100g,
          odps_region_100g,
          odps_supplier_100g
      )
      FROM SERVER odps_server INTO public OPTIONS(if_table_exist 'error',if_unsupported_type 'error');
    • 创建内部表。
      OLAP场景测试需要使用列存表(默认即为列存),还需要创建合适的索引以达到更优的查询性能。更多关于表属性的信息请参见建表概述
      DROP TABLE IF EXISTS LINEITEM;
      
      BEGIN;
      CREATE TABLE LINEITEM
      (
          L_ORDERKEY      BIGINT      NOT NULL,
          L_PARTKEY       INT         NOT NULL,
          L_SUPPKEY       INT         NOT NULL,
          L_LINENUMBER    INT         NOT NULL,
          L_QUANTITY      DECIMAL(15,2) NOT NULL,
          L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
          L_DISCOUNT      DECIMAL(15,2) NOT NULL,
          L_TAX           DECIMAL(15,2) NOT NULL,
          L_RETURNFLAG    TEXT        NOT NULL,
          L_LINESTATUS    TEXT        NOT NULL,
          L_SHIPDATE      TIMESTAMPTZ NOT NULL,
          L_COMMITDATE    TIMESTAMPTZ NOT NULL,
          L_RECEIPTDATE   TIMESTAMPTZ NOT NULL,
          L_SHIPINSTRUCT  TEXT        NOT NULL,
          L_SHIPMODE      TEXT        NOT NULL,
          L_COMMENT       TEXT        NOT NULL,
          PRIMARY KEY (L_ORDERKEY,L_LINENUMBER)
      );
      CALL set_table_property('LINEITEM', 'clustering_key', 'L_SHIPDATE,L_ORDERKEY');
      CALL set_table_property('LINEITEM', 'segment_key', 'L_SHIPDATE');
      CALL set_table_property('LINEITEM', 'distribution_key', 'L_ORDERKEY');
      CALL set_table_property('LINEITEM', 'bitmap_columns', 'L_ORDERKEY,L_PARTKEY,L_SUPPKEY,L_LINENUMBER,L_RETURNFLAG,L_LINESTATUS,L_SHIPINSTRUCT,L_SHIPMODE,L_COMMENT');
      CALL set_table_property('LINEITEM', 'dictionary_encoding_columns', 'L_RETURNFLAG,L_LINESTATUS,L_SHIPINSTRUCT,L_SHIPMODE,L_COMMENT');
      COMMIT;
      
      DROP TABLE IF EXISTS ORDERS;
      
      BEGIN;
      CREATE TABLE ORDERS
      (
          O_ORDERKEY      BIGINT      NOT NULL PRIMARY KEY,
          O_CUSTKEY       INT         NOT NULL,
          O_ORDERSTATUS   TEXT        NOT NULL,
          O_TOTALPRICE    DECIMAL(15,2) NOT NULL,
          O_ORDERDATE     timestamptz NOT NULL,
          O_ORDERPRIORITY TEXT        NOT NULL,
          O_CLERK         TEXT        NOT NULL,
          O_SHIPPRIORITY  INT         NOT NULL,
          O_COMMENT       TEXT        NOT NULL
      );
      CALL set_table_property('ORDERS', 'segment_key', 'O_ORDERDATE');
      CALL set_table_property('ORDERS', 'distribution_key', 'O_ORDERKEY');
      CALL set_table_property('ORDERS', 'bitmap_columns', 'O_ORDERKEY,O_CUSTKEY,O_ORDERSTATUS,O_ORDERPRIORITY,O_CLERK,O_SHIPPRIORITY,O_COMMENT');
      CALL set_table_property('ORDERS', 'dictionary_encoding_columns', 'O_ORDERSTATUS,O_ORDERPRIORITY,O_CLERK,O_COMMENT');
      COMMIT;
      
      DROP TABLE IF EXISTS PARTSUPP;
      
      BEGIN;
      CREATE TABLE PARTSUPP
      (
          PS_PARTKEY    INT    NOT NULL,
          PS_SUPPKEY    INT    NOT NULL,
          PS_AVAILQTY   INT    NOT NULL,
          PS_SUPPLYCOST DECIMAL(15,2) NOT NULL,
          PS_COMMENT    TEXT   NOT NULL,
          PRIMARY KEY(PS_PARTKEY,PS_SUPPKEY)
      );
      CALL set_table_property('PARTSUPP', 'distribution_key', 'PS_PARTKEY');
      CALL set_table_property('PARTSUPP', 'bitmap_columns', 'PS_PARTKEY,PS_SUPPKEY,PS_AVAILQTY,PS_COMMENT');
      CALL set_table_property('PARTSUPP', 'dictionary_encoding_columns', 'PS_COMMENT');
      COMMIT;
      
      DROP TABLE IF EXISTS PART;
      
      BEGIN;
      CREATE TABLE PART
      (
          P_PARTKEY     INT    NOT NULL PRIMARY KEY,
          P_NAME        TEXT   NOT NULL,
          P_MFGR        TEXT   NOT NULL,
          P_BRAND       TEXT   NOT NULL,
          P_TYPE        TEXT   NOT NULL,
          P_SIZE        INT    NOT NULL,
          P_CONTAINER   TEXT   NOT NULL,
          P_RETAILPRICE DECIMAL(15,2) NOT NULL,
          P_COMMENT     TEXT   NOT NULL
      );
      CALL set_table_property('PART', 'distribution_key', 'P_PARTKEY');
      CALL set_table_property('PART', 'bitmap_columns', 'P_PARTKEY,P_SIZE,P_NAME,P_MFGR,P_BRAND,P_TYPE,P_CONTAINER,P_COMMENT');
      CALL set_table_property('PART', 'dictionary_encoding_columns', 'P_NAME,P_MFGR,P_BRAND,P_TYPE,P_CONTAINER,P_COMMENT');
      COMMIT;
      
      DROP TABLE IF EXISTS CUSTOMER;
      
      BEGIN;
      CREATE TABLE CUSTOMER
      (
          C_CUSTKEY    INT    NOT NULL PRIMARY KEY,
          C_NAME       TEXT   NOT NULL,
          C_ADDRESS    TEXT   NOT NULL,
          C_NATIONKEY  INT    NOT NULL,
          C_PHONE      TEXT   NOT NULL,
          C_ACCTBAL    DECIMAL(15,2) NOT NULL,
          C_MKTSEGMENT TEXT   NOT NULL,
          C_COMMENT    TEXT   NOT NULL
      );
      CALL set_table_property('CUSTOMER', 'distribution_key', 'C_CUSTKEY');
      CALL set_table_property('CUSTOMER', 'bitmap_columns', 'C_CUSTKEY,C_NATIONKEY,C_NAME,C_ADDRESS,C_PHONE,C_MKTSEGMENT,C_COMMENT');
      CALL set_table_property('CUSTOMER', 'dictionary_encoding_columns', 'C_NAME,C_ADDRESS,C_PHONE,C_MKTSEGMENT,C_COMMENT');
      COMMIT;
      
      DROP TABLE IF EXISTS SUPPLIER;
      
      BEGIN;
      CREATE TABLE SUPPLIER
      (
          S_SUPPKEY   INT    NOT NULL PRIMARY KEY,
          S_NAME      TEXT   NOT NULL,
          S_ADDRESS   TEXT   NOT NULL,
          S_NATIONKEY INT    NOT NULL,
          S_PHONE     TEXT   NOT NULL,
          S_ACCTBAL   DECIMAL(15,2) NOT NULL,
          S_COMMENT   TEXT   NOT NULL
      );
      CALL set_table_property('SUPPLIER', 'distribution_key', 'S_SUPPKEY');
      CALL set_table_property('SUPPLIER', 'bitmap_columns', 'S_SUPPKEY,S_NAME,S_ADDRESS,S_NATIONKEY,S_PHONE,S_COMMENT');
      CALL set_table_property('SUPPLIER', 'dictionary_encoding_columns', 'S_NAME,S_ADDRESS,S_PHONE,S_COMMENT');
      COMMIT;
      
      DROP TABLE IF EXISTS NATION;
      
      BEGIN;
      CREATE TABLE NATION(
        N_NATIONKEY INT NOT NULL PRIMARY KEY,
        N_NAME text NOT NULL,
        N_REGIONKEY INT NOT NULL,
        N_COMMENT text NOT NULL
      );
      CALL set_table_property('NATION', 'distribution_key', 'N_NATIONKEY');
      CALL set_table_property('NATION', 'bitmap_columns', 'N_NATIONKEY,N_NAME,N_REGIONKEY,N_COMMENT');
      CALL set_table_property('NATION', 'dictionary_encoding_columns', 'N_NAME,N_COMMENT');
      COMMIT;
      
      DROP TABLE IF EXISTS REGION;
      
      BEGIN;
      CREATE TABLE REGION
      (
          R_REGIONKEY INT  NOT NULL PRIMARY KEY,
          R_NAME      TEXT NOT NULL,
          R_COMMENT   TEXT
      );
      CALL set_table_property('REGION', 'distribution_key', 'R_REGIONKEY');
      CALL set_table_property('REGION', 'bitmap_columns', 'R_REGIONKEY,R_NAME,R_COMMENT');
      CALL set_table_property('REGION', 'dictionary_encoding_columns', 'R_NAME,R_COMMENT');
      COMMIT;
    • 测试数据写入并收集统计信息。
      INSERT INTO public.customer SELECT * FROM public.odps_customer_100g ;
      INSERT INTO public.lineitem SELECT * FROM public.odps_lineitem_100g ;
      INSERT INTO public.nation SELECT * FROM public.odps_nation_100g ;
      INSERT INTO public.orders SELECT * FROM public.odps_orders_100g ;
      INSERT INTO public.part SELECT * FROM public.odps_part_100g ;
      INSERT INTO public.partsupp SELECT * FROM public.odps_partsupp_100g ;
      INSERT INTO public.region SELECT * FROM public.odps_region_100g ;
      INSERT INTO public.supplier SELECT * FROM public.odps_supplier_100g ;
      
      -- 清理写入文件
      vacuum  nation;
      vacuum  region;
      vacuum  supplier;
      vacuum  customer;
      vacuum  part;
      vacuum  partsupp;
      vacuum  orders;
      vacuum  lineitem;
      -- 收集表的统计信息
      analyze nation;
      analyze region;
      analyze lineitem;
      analyze orders;
      analyze customer;
      analyze part;
      analyze partsupp;
      analyze supplier;
      -- 针对非主键的JOIN KEY收集统计信息
      analyze lineitem (l_orderkey,l_partkey,l_suppkey);
      analyze orders (o_custkey);
      analyze partsupp(ps_partkey,ps_suppkey);
  • 性能测试
    1. 登录PTS控制台,在左侧导航栏选择性能测试 > 创建场景,然后单击PTS压测
    2. 场景配置页签单击HTTP压测节点后的删除图标图标删除HTTP压测节点。
      说明 PTS压测场景中的串联链路指一组压测节点的有序集合。在实际测试过程中,一个串联链路内的压测节点顺序执行,不同串联链路间并行执行。在本文的测试场景中,只需保留一个串联链路,通过配置后续的并发数来模拟并行场景。
    3. 场景配置页签单击添加压测节点右侧的下拉框,并在下拉列表单击JDBC压测节点,然后在目标串联链路右侧单击tyu图标,并在展开区域配置压测API的基本请求信息和连接池配置。
      分类参数说明
      基本请求信息API名称自定义API名称。
      数据库类型选择PostgreSQL。
      数据库URL格式为:{ENDPOINT}:{PORT}/{DBNAME}

      通过Hologres管理控制台查看实例配置,建议使用VPC网络,详情请参见实例配置

      示例:hgpostcn-cn-i7**********-cn-hangzhou-vpc.hologres.aliyuncs.com:80/db_name

      用户名当前账号的AccessKey ID。

      您可以单击AccessKey 管理,获取AccessKey ID。

      密码当前账号的AccessKey Secret。

      您可以单击AccessKey 管理,获取AccessKey Secret。

      SQL待执行的SQL语句,本文使用TPC-H 22条查询语句,SQL语句详情请参见TPC-H 22条查询语句
      超时时间需要结合待压测接口的情况配置单接口的响应超时时间,本示例取默认值。
      limit结果集最大读取行数(仅针对Select开头的SQL),最大为1000000,本示例取默认值。
      连接池配置初始化连接数初始化时建立物理连接的个数,本示例设置为1
      获取连接最大等待时间从连接池中获取空闲连接的等待时间,单位毫秒,本示例设置为4000
      最大连接数最大活跃连接数量,本示例设置为15,以匹配单并发与多并发多种测试场景。
      最小连接数池中最小空闲连接数量,本示例设置为1
      针对此OLAP查询场景测试,TPC-H包含22条查询语句。可以在同一条串联链路下创建22个JDBC节点,如下图所示代表22条查询语句。在压测过程中,PTS会依次循环执行这22条查询语句。tpc-22
    4. 施压配置页签,配置如下参数,更多施压配置相关内容请参见压力来源(公网和VPC)
      参数说明
      压力来源本示例选择阿里云VPC内网,可以提高测试结果准确性。选择阿里云VPC内网后,选择地域
      VPC信息请您根据实际情况继续选择VPC安全组虚拟交换机
      压力模式本示例选择并发模式
      其他施压配置参数需要根据测试目的的不同进行调整。
      • 使用TPC-H数据进行OLAP场景测试,主要关注的是单条Query的执行时长,参数配置如下。
        参数说明
        最大并发本示例设置为1,以确保每条query执行时有充足的资源。
        递增模式由于此处不涉及并发数的变化,因此只需保证并发数始终为1即可。
        压测总时长此处涉及22条查询语句,因此测试时长选择110分钟。
        指定IP数指发起压测流量的IP地址数量,即施压机数量。此处只需设置1个施压IP。
      • 关注并发场景下的OLAP查询性能,参数配置如下。

        选择22条查询语句中的5条(Q2、Q6、Q11、Q14、Q15),在测试过程中从3并发开始,阶梯式增加并发数至15

        递增场景
        参数说明
        最大并发可以设置为您希望达到的最高并发,本示例取值15
        递增模式选择自动递增
        递增百分比每次增加并发时的增幅,本示例设为20%
        单量级持续时长每个并发数的测试时长,本示例设为20分钟。
        压测总时长总测试时长,本示例设为100分钟。
        指定IP数指发起压测流量的IP地址数量,即施压机数量。本示例设置1个施压IP。
    5. 单击下方调试场景,进行场景调试。调试场景详情请参见调试场景
      • 下图为一个正常示例。调试正常
      • 下图为一个异常示例,错误原因可能是数据库URL错误、用户名密码错误等,导致连接失败。调试异常
    6. 单击下方保存去压测按钮,选择立即执行后单击确定,即可开始压测。

Key/Value点查场景

  • 测试数据准备
    Key/Value点查场景继续使用OLAP场景创建的数据库,使用TPC-H数据集中的ORDERS表进行测试。您在登录Hologres实例后,可以执行如下语句建表并直接从OLAP场景的ORDERS表中写入数据。
    • 创建内部表。
      Key/Value点查场景测试需要设置主键并使用行存表,还需要设置合适的索引以达到更优的查询性能。更多关于表属性的信息请参见建表概述
      说明 由于点查场景需要使用行存表,所以不能使用OLAP查询场景中创建的内部表,需要重新创建一张内部表。
      DROP TABLE IF EXISTS public.orders_row;
      
      BEGIN;
      CREATE TABLE public.orders_row(
          O_ORDERKEY       INT            NOT NULL PRIMARY KEY
          ,O_CUSTKEY       INT            NOT NULL
          ,O_ORDERSTATUS   TEXT           NOT NULL
          ,O_TOTALPRICE    DECIMAL(15,2)  NOT NULL
          ,O_ORDERDATE     TIMESTAMPTZ    NOT NULL
          ,O_ORDERPRIORITY TEXT           NOT NULL
          ,O_CLERK         TEXT           NOT NULL
          ,O_SHIPPRIORITY  INT            NOT NULL
          ,O_COMMENT       TEXT           NOT NULL
      );
      CALL SET_TABLE_PROPERTY('public.orders_row', 'orientation', 'row');
      CALL SET_TABLE_PROPERTY('public.orders_row', 'clustering_key', 'o_orderkey');
      CALL SET_TABLE_PROPERTY('public.orders_row', 'distribution_key', 'o_orderkey');
      COMMIT;
    • 写入数据
      INSERT INTO public.orders_row
      SELECT * FROM public.orders;
  • 性能测试
    1. 登录PTS控制台,在左侧导航栏选择性能测试 > 创建场景,然后单击PTS压测
    2. 场景配置页签单击HTTP压测节点后的删除图标图标删除HTTP压测节点。
      说明 PTS压测场景中的串联链路指一组压测节点的有序集合。在实际测试过程中,一个串联链路内的压测节点顺序执行,不同串联链路间并行执行。在本文的测试场景中,只需保留一个串联链路,通过配置后续的并发数来模拟并行场景。
    3. 场景配置页签单击添加压测节点右侧的下拉框,并在下拉列表单击JDBC压测节点,然后在目标串联链路右侧单击tyu图标,并在展开区域配置压测API的基本请求信息、占位符信息和连接池配置。
      分类参数说明
      基本请求信息API名称自定义API名称。
      数据库类型选择PostgreSQL。
      数据库URL格式为:{ENDPOINT}:{PORT}/{DBNAME}

      通过Hologres管理控制台查看实例配置,建议使用VPC网络,详情请参见实例配置

      示例:hgpostcn-cn-i7**********-cn-hangzhou-vpc.hologres.aliyuncs.com:80/db_name

      用户名当前账号的AccessKey ID。

      您可以单击AccessKey 管理,获取AccessKey ID。

      密码当前账号的AccessKey Secret。

      您可以单击AccessKey 管理,获取AccessKey Secret。

      SQL待执行的SQL语句。
      Key/Value点查场景的SQL与OLAP场景不同,查询方式可以分为单值点查与多值点查,样例SQL如下,详情请参见测试方案介绍
      • 单值点查。
        SELECT
            O_ORDERKEY,
            O_CUSTKEY,
            O_ORDERSTATUS,
            O_TOTALPRICE,
            O_ORDERDATE,
            O_ORDERPRIORITY,
            O_CLERK,
            O_SHIPPRIORITY,
            O_COMMENT
        FROM
            public.orders_row
        WHERE
            o_orderkey = ?;
      • 多值点查,此处以9个值为例。
        SELECT
            O_ORDERKEY,
            O_CUSTKEY,
            O_ORDERSTATUS,
            O_TOTALPRICE,
            O_ORDERDATE,
            O_ORDERPRIORITY,
            O_CLERK,
            O_SHIPPRIORITY,
            O_COMMENT
        FROM
            public.orders_row
        WHERE
            o_orderkey IN (?, ?, ?, ?, ?, ?, ?, ?, ?);
      超时时间需要结合待压测接口的情况配置单接口的响应超时时间。
      limit结果集最大读取行数(仅针对Select开头的SQL),最大为1,000,000。
      占位符Type本示例占位符Type使用bigint
      由于Key/Value点查场景需要随机生成待查询的主键值,在PTS中可以通过配置占位符实现。在SQL中使用?作为占位符,并在占位符中依次配置?代表的值。
      重要 SQL中?的数量与占位符的数量需要相等,且二者按顺序一一对应。即本实践中需要为多值点查的SQL示例配置九行占位符。
      ValuePTS支持若干系统函数,本示例使用random函数,即Value值为:${sys.random(1,99999999)}
      连接池配置初始化连接数初始化时建立物理连接的个数,Key/Value点查场景涉及并发,这里先将压测节点的连接数配置为20,对应后文施压配置中的每一台施压机都会产生20个连接。
      获取连接最大等待时间从连接池中获取空闲连接的等待时间,单位毫秒,本示例设置为4000
      最大连接数最大活跃连接数量,本示例设置为20
      最小连接数池中最小空闲连接数量,本示例设置为20
    4. 施压配置页签,配置如下参数,更多施压配置相关内容请参见压力来源(公网和VPC)
      参数说明
      压力来源本示例选择阿里云VPC内网,可以提高测试结果准确性。选择阿里云VPC内网后,选择地域
      VPC信息请您根据实际情况继续选择VPC安全组虚拟交换机
      压力模式本示例选择并发模式
      最大并发由于本文Key/Value点查场景针对Hologres 64CU规格实例的测试并发数为500,本示例设为500。因此,上文的连接池配置中,每台机器在压测节点上产生的连接数配置为20,以达到需要测试的500并发数。
      递增模式由于本文的测试场景不涉及并发数的变化,因此该部分只需保证并发数始终为500即可,即本示例选择自动递增
      递增百分比为了保证并发数始终为500,本示例取值100%
      单量级持续时长为了保证并发数始终为500,本示例取值1分钟。
      压测总时长结合测试场景需要进行填写。本场景仅涉及1条测试语句,因此测试时长选择5分钟。
      指定IP数指发起压测流量的IP地址数量,即施压机数量。本场景预估达到的QPS为10万,单台施压机可以提供的QPS上限为4000,因此本示例选择25台施压机。
      说明 PTS在并发模式下,单个施压机可以提供的QPS上限为4000,因此在实际测试场景中,需要结合可能达到的QPS值来确定施压机数量,而后确定连接池配置。
    5. 单击下方调试场景,进行场景调试。调试场景详情请参见调试场景
      • 下图为一个正常示例。调试正常
      • 下图为一个异常示例,错误原因可能是数据库URL错误、用户名密码错误等,导致连接失败。调试异常
    6. 单击下方保存去压测按钮,选择立即执行后单击确定,即可开始压测。

数据更新场景

本文的数据更新场景使用与Key/Value点查场景相同的数据表,主要测试OLAP引擎在有主键情况下进行数据更新的性能。

PTS测试场景配置内容中,仅JDBC压测节点信息中的SQL语句与Key/Value点查场景不同,其余配置项均可保持一致。数据更新场景的SQL语句如下。
INSERT INTO public.orders_row (o_orderkey, o_custkey, o_orderstatus, o_totalprice, o_orderdate, o_orderpriority, o_clerk, o_shippriority, o_comment)
    VALUES (?, 1, 'demo', 1.1, '2021-01-01', 'demo', 'demo', 1, 'demo')
ON CONFLICT (o_orderkey)
    DO UPDATE SET
        (o_orderkey, o_custkey, o_orderstatus, o_totalprice, o_orderdate, o_orderpriority, o_clerk, o_shippriority, o_comment) = ROW (excluded.*);

压测报告查看

  1. 压测完成后,在压测报告页签单击查看
    查看压测报告
  2. 报告详情页面的概览页签,可以查看压测场景运行成功与否。
    • 压测运行成功,可以查看成功率、平均RT、TPS/并发、异常数、总请求数等信息。其中,平均RT对应平均查询延迟,TPS指包含连接时间的每秒事务处理量。在本文的性能测试中,TPS与QPS大小一致。
    • 压测运行失败,请求数等指标均为0,可以通过选择查看采样日志 > 点击查看详情 > Error信息查看报错信息,进行问题排查。
  3. (可选)在报告详情页面单击明细,在压测报告明细页签查看每个压测节点(对应每个Query)的相关指标。
    如本文的OLAP查询场景,针对单个串联链路中包含多个压测节点的场景,查看单个压测节点的指标。olap结果

更多关于压测报告的内容查看与分析,详情请参见查看JDBC压测报告

压测结果

  • OLAP查询场景
    • 在不配置并发时,OLAP查询场景关注的指标为Query的查询时长,即对应下图的平均RT,本文测试得到的TPC-H 22条Query执行时长之和约为25 solap结果1
    • 在配置并发后的OLAP场景测试结果如下,此时需要同时关注查询时间及QPS两项指标。可以看出,随着并发数的逐步提升,测试的QPS结果保持在5附近。您也可以前往明细页,选择对应时间段来查看每个并发数下的性能结果。olap结果2
  • Key/Value点查场景
    • 对于单值点查,本实践压测得到的QPS平均值超过100000key/value点查结果
    • 对于多值点查,以30个值的批量点查为例,本实践得到的测试结果如下,其中QPS平均值为34819。最终的QPS性能为图示平均QPS值乘以批量点查数量30,即34819 * 30 =1044570 keyvalue点查结果2