目录
资源组配置管理者
当选择 resource-groups.configuration-manager=db 时,资源组配置管理者ResourceGroupConfigurationManager 的实现类是 DbResourceGroupConfigurationManager
DbResourceGroupConfigurationManager 在初始化时会执行一次 load,然后每隔 1s 再执行一次 load 。
load 的作用:
1. 将 db 中配置的 资源组、选择器等加载到内存中。
2. 如果db 中的 资源组配置有更新,那么将新配置刷新到 InternalResourceGroup 的属性上
configureChangedGroups(changedSpecs);
3. 如果db 中的 资源组配置有删除,那么 资源组的 InternalResourceGroup 并发数和排队数设置为 0
disableDeletedGroups(deletedSpecs);
选择器selectors 的来源有 2个
选择器selectors 的实体类是 ResourceGroupSelector ,
当配置来自 db 中的 selectors 表时,实现类是 StaticSelector。
当配置来自 db 中的 exact_match_source_selectors 表时,实现类是 DbSourceExactMatchSelector。
在 StaticSelector 中 clientTags 的数据类型是 Set<String>
db 中的 selectors 表结构
字段 | 是否必须配置 | 默认值 | 描述 |
resource_group_id | 必须 | 查询sql绑定的资源组id | |
priority | 优先级 | ||
user_regex | 提交sql 的用户名,可使用正则 | ||
source_regex | 提交sql 指定的来源,可使用正则 | ||
query_type | 提交sql 的查询类型,可使用正则 | ||
client_tags | 提交sql 的指定的client_tags | ||
user_group_regex | 提交sql 的用户组,可使用正则 | ||
selector_resource_estimate |
因此配置 client_tags ,的写法是 '["mac","mac1"]'
INSERT INTO selectors (resource_group_id,priority,client_tags,user_regex) VALUES (1,1,'["mac","mac1"]','admin');
client-tags 的指定方式
客户端
./trino --client-tags=mac,mac1
注意:客户端启动时指定的 client-tags 要包含 selectors 表中 client_tags值,选择器才能匹配上
jdbc
selectors 的匹配
入口 DispatchManager 184 行,selectGroup 方法
具体匹配方法是 DbResourceGroupConfigurationManager.match
遍历 DbResourceGroupConfigurationManager 的 selectors ,调用 StaticSelector.match
@Override
public Optional<SelectionContext<ResourceGroupIdTemplate>> match(SelectionCriteria criteria)
{
Map<String, String> variables = new HashMap<>();
//选择器 userRegex 不为null, 必须匹配
if (userRegex.isPresent()) {
Matcher userMatcher = userRegex.get().matcher(criteria.getUser());
if (!userMatcher.matches()) {
return Optional.empty();
}
addVariableValues(userRegex.get(), criteria.getUser(), variables);
}
//选择器 userGroupRegex 不为null, 用户的所在的所有UserGroup,必须得有一个匹配
if (userGroupRegex.isPresent() && criteria.getUserGroups().stream().noneMatch(group -> userGroupRegex.get().matcher(group).matches())) {
return Optional.empty();
}
//选择器 sourceRegex 不为null, 必须匹配
if (sourceRegex.isPresent()) {
String source = criteria.getSource().orElse("");
if (!sourceRegex.get().matcher(source).matches()) {
return Optional.empty();
}
addVariableValues(sourceRegex.get(), source, variables);
}
//选择器 clientTags 不为null, 用户指定的 tags 必须包含 clientTags
if (!clientTags.isEmpty() && !criteria.getTags().containsAll(clientTags)) {
return Optional.empty();
}
if (selectorResourceEstimate.isPresent() && !selectorResourceEstimate.get().match(criteria.getResourceEstimates())) {
return Optional.empty();
}
//sql类型 queryType 不为null, 用户提交的 sql类型必须等于 queryType
if (queryType.isPresent()) {
String contextQueryType = criteria.getQueryType().orElse("");
if (!queryType.get().equalsIgnoreCase(contextQueryType)) {
return Optional.empty();
}
}
variables.putIfAbsent(USER_VARIABLE, criteria.getUser());
// Special handling for source, which is an optional field that is part of the standard variables
variables.putIfAbsent(SOURCE_VARIABLE, criteria.getSource().orElse(""));
ResourceGroupId id = group.expandTemplate(new VariableMap(variables));// group ResourceGroupIdTemplate root.dianzhang
return Optional.of(new SelectionContext<>(id, group));
}
selectors 的匹配结果的选择
selectors 是一个有顺序的的list , 顺序和 db 中的 selectors 表数据的先后顺序 一致。
当匹配值有多个时,匹配结果取第一个。
所以:db 中的选择器按顺序匹配,取第一个匹配的使用。