【Trino 选择器selectors 的匹配原理】

目录

资源组配置管理者

load 的作用:

选择器selectors 的来源有 2个

client-tags 的指定方式

客户端

jdbc

selectors 的匹配

selectors 的匹配结果的选择


资源组配置管理者

当选择 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 中的选择器按顺序匹配,取第一个匹配的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值