Trino资源组配置
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/
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 资源组配置
a、对于global资源组而言,最多可同时运行100个查询,有1000查询处于排队状态,在它下面有三个子资源组:data_definition、adhoc 和 pipeline; b、pipeline资源组下每一个用户最多可同时运行5个查询,占用pipeline资源组50%的内存资源,其组内默认采用fair的调度策略,所以是按照先来先执行的顺序执行; c、为了充分利用集群资源,各个子资源组的内存配额的总和可大于父资源组,比如global资源组(80%)+admin(100%)=180%>100% 。 当我们保证子资源组的占比和小于等于100%时,可保证某一个队列的资源总是有的,不被其他资源组抢占,类似静态化分资源
2.4 资源组选择器
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时间,在达到该阈值后,新的查询会进行排队而非直接执行;
运行结果:
正在运行的任务数:20
排队任务的最大数量:50
超过的任务数报q1队列已满:
2、用户匹配资源组
/opt/cloudera/parcels/PRESTO/bin/trino --server http://10.116.1.75:8080 --catalog hive --schema dm --user=bob -f /mnt/a.sql