配置HetuEngine资源组
资源组介绍
资源组机制从资源分配的角度控制实例的整体查询负载,并可以对查询实施排队策略。可以在一个计算实例资源下创建多个资源组,并且每个提交的查询将分配给一个特定的资源组执行。在资源组执行新查询之前,将检查当前资源组的资源负载是否超过实例分配给它的资源量。如果超过,则将阻止新到达的查询,使其处于排队状态,甚至直接拒绝它。
资源组使用场景
通过资源组可以实现计算实例内的资源管理。对不同用户、不同查询分配不同的资源组,可以起到资源隔离的作用,避免单个用户或查询独占计算实例的资源,也能通过资源组之间的权重优先级配置保障重要任务优先执行。典型资源组使用场景如表1所示。
典型场景 |
解决方案 |
---|---|
随着使用计算实例的业务团队的增加,当某个团队的任务更加重要并且不想执行查询时没有资源。 |
每个团队分配一个指定的资源组;重要任务分配到资源较多的资源组;保证子资源组的占比和小于等于100%时,可保证某一个队列的资源不被其他资源组抢占,类似于静态化分资源。 |
当实例资源负载很高时,两个用户同时提交一个查询。一开始,两个查询都在排队。当有空闲资源时,可以调度特定用户的查询首先获取到资源。 |
两个用户分配不同的资源组,重要的任务可以分配到权重高或优先级高的资源组,调度策略由schedulingPolicy配置,不同的调度策略,会有不同的资源分配顺序。 |
对于即席查询和批量查询,可以根据不同的SQL类型进行更合理的资源分配。 |
可以对不同的查询类型,比如EXPLAIN、INSERT、SELECT和DATA_DEFINITION等类型,匹配到不同的资源组,分配不同的资源来执行查询。 |
启用资源组
在创建计算实例的时候,增加参数文件“resource-groups.json”的自定义配置参数,具体操作请参见3.e。
配置项 |
必选/可选 |
配置说明 |
---|---|---|
name |
必选 |
资源组名称。 |
maxQueued |
必选 |
最大排队查询数,当达到此阈值后,新的查询将被拒绝。 |
hardConcurrencyLimit |
必选 |
最大运行查询数。 |
softMemoryLimit |
可选 |
资源组最大内存使用量,当达到此阈值后,新任务进入排队;可以指定为固定值(如,10GB)或百分比(如,集群内存的10%)。 |
softCpuLimit |
可选 |
在一个周期内(参见全局属性的cpuQuotaPeriod参数)可以使用CPU的时间,必须同时指定hardCpuLimit参数,在达到该阈值后,该资源组内占据最大CPU资源的查询的CPU资源会被减少。 |
hardCpuLimit |
可选 |
在一个周期内可以使用的最大CPU时间。 |
schedulingPolicy |
可选 |
指定查询从排队到运行状态的调度策略。 |
schedulingWeight |
可选 |
该分组的权重,见schedulingPolicy,默认为1。 |
jmxExport |
可选 |
如果为true,则组统计信息将被导出到JMX中进行监控,默认为false。 |
subGroups |
可选 |
子分组列表。 |
killPolicy |
可选 |
当查询提交给Worker后,如果总内存使用量超过softMemoryLimit,可选择一种策略终止正在运行的查询,策略如下所示:
|
选择器规则
选择器按顺序进行匹配,将使用第一个匹配到的资源组,一般来说建议配置一个默认资源组,如果没有设置默认资源组,而又不符合其他资源组选择器条件则查询会被拒绝。选择器规则参数配置请参见表3。
配置项 |
必选/可选 |
配置说明 |
---|---|---|
user |
可选 |
匹配用户名的正则表达式。 |
source |
可选 |
匹配请求源,参见选择器属性的配置中--source选项的配置值。 |
queryType |
可选 |
配置任务类型:
|
clientTags |
可选 |
匹配客户端标签,每个标签都必须在用户提交任务的标签列表里,参见选择器属性的配置中--client-tags选项的配置值。 |
group |
必选 |
在其中运行查询的资源组。 |
选择器属性的配置
数据源名称(source)可设置如下:
- CLI:使用--source选项。
- JDBC:在Connection实例上设置ApplicationName客户端信息属性。
客户端标签(clientTags)的设置方式如下:
- CLI:使用--client-tags选项。
- JDBC:在Connection实例上设置ClientTags client info属性。
配置示例
如图1所示:
- 对于global资源组而言,最多可同时运行100个查询,有1000查询处于排队状态,在它下面有三个子资源组:data_definition、adhoc 和 pipeline;
- pipeline资源组下每一个用户最多可同时运行5个查询,占用pipeline资源组50%的内存资源,其组内默认采用fair的调度策略,所以是按照先来先执行的顺序执行;
- 为了充分利用实例资源,各个子资源组的内存配额的总和可大于父资源组,比如global资源组(80%)+admin(100%)=180%>100% 。
在下面的示例配置中,存在多个资源组,其中一些资源组是模板。模板允许HetuEngine管理员动态构建资源组树。例如,在pipeline_${USER}组中,${USER}将扩展为提交查询的用户名称。${SOURCE}也支持,后续会扩展到提交查询的来源。也可以在source表达式和user正则表达式中使用自定义命名变量。
资源组选择器示例如下:
"selectors": [{ "user": "bob", "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}" }]
有四个选择器用于定义在哪个资源组中运行查询:
- 第一个选择器匹配来自bob的查询,并将它们放在admin组中。
- 第二个选择器匹配来自包括pipeline的源名称的所有数据定义(DDL)查询,并将它们放在global.data_definition组中。这有助于减少此类查询的排队时间,因为它们预计速度很快。
- 第三个选择器匹配来自包括pipeline的源名称的查询,并将它们放在global.pipeline组下动态创建的单用户管道组中。
- 第四个选择器匹配来自BI工具的查询,BI工具有一个源与正则表达式jdbc#(?.*)匹配,并且客户端提供的标签是hi-pri的超集。这些查询被放置在global.adhoc组下动态创建的子组中。动态子组将基于命名变量toolname创建,该命名变量从源的正则表达式中提取。假设有一个源为jdbc#powerfulbi,用户为kayla,客户端标签为hipri和fast的查询。此查询将被路由到global.adhoc.bi-powerfulbi.kayla资源组。
- 最后一个选择器是一个默认选择器,它将所有尚未匹配的查询放入该资源组。
这些选择器一起实现以下策略:
- bob是HetuEngine管理员用户,可以同时运行50个查询。查询将根据用户提供的优先级运行。
- 对于剩余用户:
- 同时运行的查询总数不能超过100个。
- 使用源pipeline最多可以运行5个并发的DDL查询。查询按FIFO顺序运行。
- 非DDL查询将在global.pipeline组下运行,总并发数为45,每用户并发数为5。查询按FIFO顺序运行。
- 对于BI工具,每个工具最多可以运行10个并发查询,每个用户最多可以运行3个。如果总需求超过10个限制,运行查询最少的用户将获得下一个并发槽。这项策略使得资源争夺时更加公平。
- 所有剩余的查询都放在global.adhoc.other下的每个用户组中,该组行为类似。
查询匹配选择器的说明:
- 如上每一个大括号代表一个匹配资源组的选择器selector,这里一共配置了5个选择器以匹配上面的5个资源组:
admin global.data_definition global.pipeline.pipeline_${USER} global.adhoc.bi-${toolname}.${USER} global.adhoc.other.${USER}
- 要全部满足当前selector全部条件,才可放进当前队列执行。比如amy用户使用jdbc方式提交的查询,如果没有配置clientTags,是不能够分配到资源组global.adhoc.bi-${toolname}.${USER}对应的资源;
- 当一个查询能同时满足两个selector时,会匹配第一个满足要求的selector。比如bob用户提交一个source为pipeline的DATA_DEFINITION类型的job,只会匹配到资源组admin对应的资源,而非global.data_definition对应的资源;
- 当前4个selector都没有匹配上,会使用最后一个selector指定的资源组global.adhoc.other.${USER}的资源。该资源组相当于起到一个默认资源组的作用,如果没有设置默认资源组,而又不符合其他资源组选择器条件则会被拒绝执行。
{ "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" }, { "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" }