Trino资源组配置

耀灵10个月前技术文章838

1 概述

Presto作为一个大数据场景下的交互式查询引擎,当使用达到一定规模,就会更多考虑资源分配问题,即保障重要任务优先获取资源。

Presto资源组:
Presto的资源组机制,是从资源分配的角度来控制集群的整体查询负载。
Presto会在集群整体资源下开辟多个资源组,每一个提交的查询都会分配到一个特定的资源组执行。
在特定资源组A开启一个新的查询B之前,会检查当前A的资源负载是否超过了集群给A分配的资源量;如果已经超过了,资源组机制会阻塞新到的查询B,使其处于排队状态甚至直接拒绝。

Presto资源组可认为是实现了一个弱资源限制和隔离功能。
可以为每个资源组指定队列大小、并发大小、内存使用大小以及CPU资源量。加深对资源组的理解,为每个资源组设置合理的资源参数,一方面可以降低不同业务之间的影响,另一方面也有助于系统减少OOM问题。

2 资源组配置

2.1 配置文件

a、在Presto Coordinator节点安装目录etc下新建文件 resource-groups.json和resource-groups.properties
其中:resource-groups.properties内容如下(指向资源组配置文件的路径):
resource-groups.configuration-manager=file 
resource-groups.config-file=etc/resource-groups.json

b、修改启动脚本/opt/cloudera/parcels/PRESTO/bin/launcher
PRESTO_PARCEL_PATH=/opt/cloudera/parcels/PRESTO
cp $PRESTO_PARCEL_PATH/etc/resource-groups.properties $CONF_DIR/etc/
cp $PRESTO_PARCEL_PATH/etc/resource-groups.json $CONF_DIR/etc/

1.png

2.2 resource-groups.json配置

a、资源组主要配置项
name(必须):
特定资源组名称;

maxQueued(必须):
排队任务的最大数量,当达到此阈值后,新的任务将被拒绝;

hardConcurrencyLimit(必须):
任何时刻处于"RUNNING"状态的查询的最大数量;

softMemoryLimit(必须):
这个资源组最大内存使用量,当达到此阈值后,新任务进入排队。可以指定为一个绝对值(如100GB),也可以指定对集群内存总量的百分比(如60%);

softCpuLimit(可选):
一个周期里可以使用cpu的时间,hardCpuLimit也必须指定,在达到该阈值后,该资源组内占据最大CPU资源的查询的CPU资源会被减少;

hardCpuLimit(可选):
一个周期里可以使用的cpu时间,在达到该阈值后,新的查询会进行排队而非直接执行;

schedulingPolicy(可选) :
指定查询从排队到运行状态的调度策略。
【这里可以参照不同的调度策略,可能会有不同的资源分配顺序】

主要有以下类型:
fair(default):
当一个资源组下,有几个子资源组都同时有排队的查询,这些子资源组间按照定义的顺序,轮流获得资源,同一个子资源组的查询按照先来先执行的规则获取资源;

weighted_fair :
采取这种策略的每一个资源组会配置一个属性schedulingWeight,每个子资源组会计算一个比值:
当前子资源组查询数量/schedulingWeight,比值越小的子资源组越先得到资源;

weighted:
默认值为1,子资源组的schedulingWeight越大,越先得到资源;

query_priority:
所有的子资源组都要配置为 query_priority ,排队的查询严格按照指定的query_priority大小顺序来进行获取资源。

b、 资源组选择器
user(可选):
匹配用户名;

source(可选):
匹配连接源,如cli、jdbc、pyhive等;

queryType(可选):
匹配任务类型;
* DATA_DEFINITION:alter/create/drop schemas/tables/views的元数据和权限、会话、事物相关的任务
* DELETE:删除数据的任务
* DESCRIBE:DESCRIBE, DESCRIBE INPUT, DESCRIBE OUTPUT, and SHOW类型的任务
* EXPLAIN:EXPLAIN类型的任务
* INSERT:INSERT 和 CREATE TABLE AS 类型的任务
* SELECT:SELECT类型的任务

clientTags(可选):
tag列表,每个tag必须在用户提交任务的tag列表里;

group(必须):
这些任务运行的组。
【这里可以对不同的查询类型queryType,比如EXPLAIN、INSERT、SELECT和DATA_DEFINITION等类型,匹配到不同的资源组,分配不同的资源,来执行查询】

c、全局属性
cpuQuotaPeriod(可选):cpu份额被强制执行的时间

选择器顺序处理,匹配的第一个将被使用

提供选择器属性

source名字可以如下设置:

CLI:用--source属性
JDBC:通过连接实例设置ApplicationName属性
Client tags可以如下设置

CLI:用--client-tags属性
JDBC:通过连接实例设置ClientTags属性

2.3 资源组配置

2.png

a、对于global资源组而言,最多可同时运行100个查询,有1000查询处于排队状态,在它下面有三个子资源组:data_definition、adhoc 和 pipeline;
b、pipeline资源组下每一个用户最多可同时运行5个查询,占用pipeline资源组50%的内存资源,其组内默认采用fair的调度策略,所以是按照先来先执行的顺序执行;
c、为了充分利用集群资源,各个子资源组的内存配额的总和可大于父资源组,比如global资源组(80%)+admin(100%)=180%>100% 。

当我们保证子资源组的占比和小于等于100%时,可保证某一个队列的资源总是有的,不被其他资源组抢占,类似静态化分资源

2.4 资源组选择器

3.png

a.如上每一个大括号代表一个匹配资源组的选择器selector,这里一共配置了5个选择器以匹配上面的5个资源组:
admin
global.data_definition
global.pipeline.pipeline_${USER}、global.adhoc.bi-${toolname}.${USER}
global.adhoc.other.${USER}

b. 要全部满足当前selector全部条件,才可放进当前队列执行。比如amy用户使用jdbc方式提交的查询,如果没有配置clientTags,是不能够分配到资源组global.adhoc.bi-${toolname}.${USER}对应的资源;

c. 当一个查询能同时满足两个seletor时,会匹配第一个满足要求的seletor。比如bob用户提交一个source为pipeline的DATA_DEFINITION类型的job,只会匹配到资源组admin对应的资源,而非global.data_definition对应的资源;

d. 当前4个seletor都没有匹配上,会使用最后一个seletor指定的资源组global.adhoc.other.${USER}的资源。该资源组相当于起到一个默认资源组的作用,如果没有设置默认资源组,而又不符合其他资源组选择器条件则会被拒绝执行。

2.5 资源组配置案例

{
  "rootGroups": [
    {
      "name": "global",
      "softMemoryLimit": "80%",
      "hardConcurrencyLimit": 100,
      "maxQueued": 1000,
      "schedulingPolicy": "weighted",
      "jmxExport": true,
      "subGroups": [
        {
          "name": "data_definition",
          "softMemoryLimit": "10%",
          "hardConcurrencyLimit": 5,
          "maxQueued": 100,
          "schedulingWeight": 1
        },
        {
          "name": "adhoc",
          "softMemoryLimit": "10%",
          "hardConcurrencyLimit": 50,
          "maxQueued": 1,
          "schedulingWeight": 10,
          "subGroups": [
            {
              "name": "other",
              "softMemoryLimit": "10%",
              "hardConcurrencyLimit": 2,
              "maxQueued": 1,
              "schedulingWeight": 10,
              "schedulingPolicy": "weighted_fair",
              "subGroups": [
                {
                  "name": "${USER}",
                  "softMemoryLimit": "10%",
                  "hardConcurrencyLimit": 1,
                  "maxQueued": 100
                }
              ]
            },
            {
              "name": "bi-${toolname}",
              "softMemoryLimit": "10%",
              "hardConcurrencyLimit": 10,
              "maxQueued": 100,
              "schedulingWeight": 10,
              "schedulingPolicy": "weighted_fair",
              "subGroups": [
                {
                  "name": "${USER}",
                  "softMemoryLimit": "10%",
                  "hardConcurrencyLimit": 3,
                  "maxQueued": 10
                }
              ]
            }
          ]
        },
        {
          "name": "pipeline",
          "softMemoryLimit": "80%",
          "hardConcurrencyLimit": 45,
          "maxQueued": 100,
          "schedulingWeight": 1,
          "jmxExport": true,
          "subGroups": [
            {
              "name": "pipeline_${USER}",
              "softMemoryLimit": "50%",
              "hardConcurrencyLimit": 5,
              "maxQueued": 100
            }
          ]
        }
      ]
    },
    {
      "name": "admin",
      "softMemoryLimit": "100%",
      "hardConcurrencyLimit": 50,
      "maxQueued": 100,
      "schedulingPolicy": "query_priority",
      "jmxExport": true
    }
  ],
  "selectors": [
    {
      "user": "bob",
      "group": "admin"
    },
    {
      "userGroup": "admin",
      "group": "admin"
    },
    {
      "source": ".*pipeline.*",
      "queryType": "DATA_DEFINITION",
      "group": "global.data_definition"
    },
    {
      "source": ".*pipeline.*",
      "group": "global.pipeline.pipeline_${USER}"
    },
    {
      "source": "jdbc#(?<toolname>.*)",
      "clientTags": ["hipri"],
      "group": "global.adhoc.bi-${toolname}.${USER}"
    },
    {
      "group": "global.adhoc.other.${USER}"
    }
  ],
  "cpuQuotaPeriod": "1h"
}
例子中的配置如下,这里有多个资源组,一些是模板。模板允许管理员动态的构建资源树。例如,在pipeline_{USER} 组中,USER组中,{USER}将被扩展为提交任务的用户名。${SOURCE}也支持,将被扩展为提交任务的来源。你可以用自定义变量在source和user正则表达式中

这里定义了四个筛选器,这些任务运行在子组中:

第一个筛选器匹配bob的任务,并放在admin组中运行
第二个筛选器匹配所有的来源名字包含pipeline的DDL任务,放在global.data_definition组中运行。这有助于减少这类任务的执行时间,因为他们一般需要快速运行
第三个筛选器匹配来源中包含pipeline的任务,并放在global.pipeline中的dynamically-created per-user pipeline组中
第四个筛选器来源于 BI tools 的任务,并且客户端提供的tag是“hi-pri”的超集。他们被放在global.pipeline.tools组里的动态创建的子组。动态子组的创建基于tool_name变量的名字,从来源的正则表达式中取出。一个任务来源为“jdbc#powerfulbi”,用户为“kayla”,客户端tag为“hipri”和“fast”,这个任务将被放在global.pipeline.bi-powerfulbi.kayla资源组中。
最后一个筛选器是针对所有没有被前面匹配的任务。
这些筛选器继承了如下策略:

用户“bob”是管理员,能同时运行50个任务,任务运行基于用户提供的priority
其它的用户:

不能同时运行100个任务
来源为“pipeline”的最多可以同时运行5个DDL任务,先进先出
Non-DDL任务运行在global.pipeline中,总并发为45,每个用户并发为5,先进先出
对应BI tools,每个tools最多可以运行10个任务,每个用户最多运行3个。如果超过10个,运行任务最少的用户将可以继续运行,这样是保持公平。
其它任务被放在global.adhoc.other中的per-user 组中运行,运行相似

3 资源组使用测试

3.1 通过客户端标签匹配资源组

/opt/cloudera/parcels/PRESTO/bin/trino --server http://10.116.1.75:8080 --catalog hive --schema dm  --client-tags=q1 -f /mnt/a.sql

测试数据:

并发运行71个sql

hardCpuLimit:5分钟

一个周期里可以使用的cpu时间,在达到该阈值后,新的查询会进行排队而非直接执行;

5.png

运行结果:

6.png

正在运行的任务数:20

排队任务的最大数量:50

7.png

超过的任务数报q1队列已满:

8.png


2、用户匹配资源组

/opt/cloudera/parcels/PRESTO/bin/trino --server http://10.116.1.75:8080 --catalog hive --schema dm  --user=bob -f /mnt/a.sql

9.png

10.png


相关文章

Presto开发语句简介

Presto开发语句简介

根据presto中的结构配置,catalog表示连接,主要看presto中catalog文件夹下的配置,一般包含hive、mysql等,其中可以根据业务的不同设置多个配置文件。schema表示连接中的...

使用impala操作kudu

使用impala操作kudu

登录impala-shell,创建impala_kudu数据库。1、创建表CREATE TABLE student ( id int not null, name STRING null ,...

OSS bucket权限设置

OSS bucket权限设置

问题描述调用oss的bucket资源,开始的时候可以访问,过几分钟再访问的时候,就提示拒绝访问问题原因是因为相应的bucket权限为私有,私有权限在访问文件对象时,是存在鉴权URL,存在时间有效性,所...

阿里金融云经典网络和线下某银行实现网络互通

阿里金融云经典网络和线下某银行实现网络互通

需求某银行需要和某阿里金融云账号下的经典网络实例内网打通。已知不考虑将该服务器从经典网络类型迁移至VPC类型。阿里金融云环境下,之前是支持拉线下到经典网络专线的,但是目前和阿里侧核查,确认已不支持,仅...

kubebuilder 开发operator初探

1、使用kubebuilder初始化$ mkdir project$ cd project$ kubebuilder init --domain tutorial.kubebuilder.io --r...

MySQL运维实战(1.1)安装部署:使用RPM进行安装部署

MySQL运维实战(1.1)安装部署:使用RPM进行安装部署

我们在生产环境部署mysql时,一般很少使用rpm。用rpm或或者其他包管理器安装mysql,好处是安装简单,而且很多系统可能都自带了某个版本的mysql。但是使用RPM安装也存在一些缺点:1、rpm...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。