Search in sources :

Example 1 with ResourceGroupSpec

use of io.trino.plugin.resourcegroups.ResourceGroupSpec in project trino by trinodb.

the class DbResourceGroupConfigurationManager method load.

@VisibleForTesting
public synchronized void load() {
    try {
        Map.Entry<ManagerSpec, Map<ResourceGroupIdTemplate, ResourceGroupSpec>> specsFromDb = buildSpecsFromDb();
        ManagerSpec managerSpec = specsFromDb.getKey();
        Map<ResourceGroupIdTemplate, ResourceGroupSpec> resourceGroupSpecs = specsFromDb.getValue();
        Set<ResourceGroupIdTemplate> changedSpecs = new HashSet<>();
        Set<ResourceGroupIdTemplate> deletedSpecs = Sets.difference(this.resourceGroupSpecs.keySet(), resourceGroupSpecs.keySet());
        for (Map.Entry<ResourceGroupIdTemplate, ResourceGroupSpec> entry : resourceGroupSpecs.entrySet()) {
            if (!entry.getValue().sameConfig(this.resourceGroupSpecs.get(entry.getKey()))) {
                changedSpecs.add(entry.getKey());
            }
        }
        this.resourceGroupSpecs = resourceGroupSpecs;
        this.cpuQuotaPeriod.set(managerSpec.getCpuQuotaPeriod());
        this.rootGroups.set(managerSpec.getRootGroups());
        List<ResourceGroupSelector> selectors = buildSelectors(managerSpec);
        if (exactMatchSelectorEnabled) {
            ImmutableList.Builder<ResourceGroupSelector> builder = ImmutableList.builder();
            builder.add(new DbSourceExactMatchSelector(environment, dao));
            builder.addAll(selectors);
            this.selectors.set(builder.build());
        } else {
            this.selectors.set(selectors);
        }
        configureChangedGroups(changedSpecs);
        disableDeletedGroups(deletedSpecs);
        if (lastRefresh.get() > 0) {
            for (ResourceGroupIdTemplate deleted : deletedSpecs) {
                log.info("Resource group spec deleted %s", deleted);
            }
            for (ResourceGroupIdTemplate changed : changedSpecs) {
                log.info("Resource group spec %s changed to %s", changed, resourceGroupSpecs.get(changed));
            }
        } else {
            log.info("Loaded %s selectors and %s resource groups from database", this.selectors.get().size(), this.resourceGroupSpecs.size());
        }
        lastRefresh.set(System.nanoTime());
    } catch (Throwable e) {
        if (succinctNanos(System.nanoTime() - lastRefresh.get()).compareTo(maxRefreshInterval) > 0) {
            lastRefresh.set(0);
        }
        refreshFailures.update(1);
        log.error(e, "Error loading configuration from db");
    }
}
Also used : ResourceGroupSelector(io.trino.plugin.resourcegroups.ResourceGroupSelector) ImmutableList(com.google.common.collect.ImmutableList) ManagerSpec(io.trino.plugin.resourcegroups.ManagerSpec) ResourceGroupSpec(io.trino.plugin.resourcegroups.ResourceGroupSpec) ResourceGroupIdTemplate(io.trino.plugin.resourcegroups.ResourceGroupIdTemplate) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) AbstractMap(java.util.AbstractMap) HashSet(java.util.HashSet) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with ResourceGroupSpec

use of io.trino.plugin.resourcegroups.ResourceGroupSpec in project trino by trinodb.

the class TestDbResourceGroupConfigurationManager method testEnvironments.

@Test
public void testEnvironments() {
    H2DaoProvider daoProvider = setup("test_configuration");
    H2ResourceGroupsDao dao = daoProvider.get();
    dao.createResourceGroupsGlobalPropertiesTable();
    dao.createResourceGroupsTable();
    dao.createSelectorsTable();
    String prodEnvironment = "prod";
    String devEnvironment = "dev";
    dao.insertResourceGroupsGlobalProperties("cpu_quota_period", "1h");
    // two resource groups are the same except the group for the prod environment has a larger softMemoryLimit
    dao.insertResourceGroup(1, "prod_global", "10MB", 1000, 100, 100, "weighted", null, true, "1h", "1d", null, prodEnvironment);
    dao.insertResourceGroup(2, "dev_global", "1MB", 1000, 100, 100, "weighted", null, true, "1h", "1d", null, devEnvironment);
    dao.insertSelector(1, 1, ".*prod_user.*", null, null, null, null, null);
    dao.insertSelector(2, 2, ".*dev_user.*", null, null, null, null, null);
    // check the prod configuration
    DbResourceGroupConfigurationManager manager = new DbResourceGroupConfigurationManager(listener -> {
    }, new DbResourceGroupConfig(), daoProvider.get(), prodEnvironment);
    List<ResourceGroupSpec> groups = manager.getRootGroups();
    assertEquals(groups.size(), 1);
    InternalResourceGroup prodGlobal = new InternalResourceGroup("prod_global", (group, export) -> {
    }, directExecutor());
    manager.configure(prodGlobal, new SelectionContext<>(prodGlobal.getId(), new ResourceGroupIdTemplate("prod_global")));
    assertEqualsResourceGroup(prodGlobal, "10MB", 1000, 100, 100, WEIGHTED, DEFAULT_WEIGHT, true, Duration.ofHours(1), Duration.ofDays(1));
    assertEquals(manager.getSelectors().size(), 1);
    ResourceGroupSelector prodSelector = manager.getSelectors().get(0);
    ResourceGroupId prodResourceGroupId = prodSelector.match(new SelectionCriteria(true, "prod_user", ImmutableSet.of(), Optional.empty(), ImmutableSet.of(), EMPTY_RESOURCE_ESTIMATES, Optional.empty())).get().getResourceGroupId();
    assertEquals(prodResourceGroupId.toString(), "prod_global");
    // check the dev configuration
    manager = new DbResourceGroupConfigurationManager(listener -> {
    }, new DbResourceGroupConfig(), daoProvider.get(), devEnvironment);
    assertEquals(groups.size(), 1);
    InternalResourceGroup devGlobal = new InternalResourceGroup("dev_global", (group, export) -> {
    }, directExecutor());
    manager.configure(devGlobal, new SelectionContext<>(prodGlobal.getId(), new ResourceGroupIdTemplate("dev_global")));
    assertEqualsResourceGroup(devGlobal, "1MB", 1000, 100, 100, WEIGHTED, DEFAULT_WEIGHT, true, Duration.ofHours(1), Duration.ofDays(1));
    assertEquals(manager.getSelectors().size(), 1);
    ResourceGroupSelector devSelector = manager.getSelectors().get(0);
    ResourceGroupId devResourceGroupId = devSelector.match(new SelectionCriteria(true, "dev_user", ImmutableSet.of(), Optional.empty(), ImmutableSet.of(), EMPTY_RESOURCE_ESTIMATES, Optional.empty())).get().getResourceGroupId();
    assertEquals(devResourceGroupId.toString(), "dev_global");
}
Also used : SelectionContext(io.trino.spi.resourcegroups.SelectionContext) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) SchedulingPolicy(io.trino.spi.resourcegroups.SchedulingPolicy) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Assert.assertEquals(org.testng.Assert.assertEquals) Test(org.testng.annotations.Test) TrinoExceptionAssert.assertTrinoExceptionThrownBy(io.trino.testing.assertions.TrinoExceptionAssert.assertTrinoExceptionThrownBy) ArrayList(java.util.ArrayList) UnableToExecuteStatementException(org.jdbi.v3.core.statement.UnableToExecuteStatementException) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) ResourceEstimates(io.trino.spi.session.ResourceEstimates) Duration(java.time.Duration) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) InternalResourceGroup(io.trino.execution.resourcegroups.InternalResourceGroup) WEIGHTED(io.trino.spi.resourcegroups.SchedulingPolicy.WEIGHTED) Assert.assertFalse(org.testng.Assert.assertFalse) ResourceGroupId(io.trino.spi.resourcegroups.ResourceGroupId) ImmutableSet(com.google.common.collect.ImmutableSet) ResourceGroupSelector(io.trino.plugin.resourcegroups.ResourceGroupSelector) TrinoException(io.trino.spi.TrinoException) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) ResourceGroupIdTemplate(io.trino.plugin.resourcegroups.ResourceGroupIdTemplate) DEFAULT_WEIGHT(io.trino.execution.resourcegroups.InternalResourceGroup.DEFAULT_WEIGHT) MoreExecutors.directExecutor(com.google.common.util.concurrent.MoreExecutors.directExecutor) FAIR(io.trino.spi.resourcegroups.SchedulingPolicy.FAIR) DataSize(io.airlift.units.DataSize) List(java.util.List) ResourceGroupSpec(io.trino.plugin.resourcegroups.ResourceGroupSpec) SelectionCriteria(io.trino.spi.resourcegroups.SelectionCriteria) Optional(java.util.Optional) Assert.assertTrue(org.testng.Assert.assertTrue) StaticSelector(io.trino.plugin.resourcegroups.StaticSelector) Pattern(java.util.regex.Pattern) Comparator(java.util.Comparator) ResourceGroupSelector(io.trino.plugin.resourcegroups.ResourceGroupSelector) ResourceGroupId(io.trino.spi.resourcegroups.ResourceGroupId) ResourceGroupSpec(io.trino.plugin.resourcegroups.ResourceGroupSpec) ResourceGroupIdTemplate(io.trino.plugin.resourcegroups.ResourceGroupIdTemplate) InternalResourceGroup(io.trino.execution.resourcegroups.InternalResourceGroup) SelectionCriteria(io.trino.spi.resourcegroups.SelectionCriteria) Test(org.testng.annotations.Test)

Example 3 with ResourceGroupSpec

use of io.trino.plugin.resourcegroups.ResourceGroupSpec in project trino by trinodb.

the class DbResourceGroupConfigurationManager method buildSpecsFromDb.

private synchronized Map.Entry<ManagerSpec, Map<ResourceGroupIdTemplate, ResourceGroupSpec>> buildSpecsFromDb() {
    // New resource group spec map
    Map<ResourceGroupIdTemplate, ResourceGroupSpec> resourceGroupSpecs = new HashMap<>();
    // Set of root group db ids
    Set<Long> rootGroupIds = new HashSet<>();
    // Map of id from db to resource group spec
    Map<Long, ResourceGroupSpec> resourceGroupSpecMap = new HashMap<>();
    // Map of id from db to resource group template id
    Map<Long, ResourceGroupIdTemplate> resourceGroupIdTemplateMap = new HashMap<>();
    // Map of id from db to resource group spec builder
    Map<Long, ResourceGroupSpecBuilder> recordMap = new HashMap<>();
    // Map of subgroup id's not yet built
    Map<Long, Set<Long>> subGroupIdsToBuild = new HashMap<>();
    populateFromDbHelper(recordMap, rootGroupIds, resourceGroupIdTemplateMap, subGroupIdsToBuild);
    // Build up resource group specs from leaf to root
    for (LinkedList<Long> queue = new LinkedList<>(rootGroupIds); !queue.isEmpty(); ) {
        Long id = queue.pollFirst();
        resourceGroupIdTemplateMap.computeIfAbsent(id, k -> {
            ResourceGroupSpecBuilder builder = recordMap.get(id);
            return ResourceGroupIdTemplate.forSubGroupNamed(resourceGroupIdTemplateMap.get(builder.getParentId().get()), builder.getNameTemplate().toString());
        });
        Set<Long> childrenToBuild = subGroupIdsToBuild.getOrDefault(id, ImmutableSet.of());
        // Add to resource group specs if no more child resource groups are left to build
        if (childrenToBuild.isEmpty()) {
            ResourceGroupSpecBuilder builder = recordMap.get(id);
            ResourceGroupSpec resourceGroupSpec = builder.build();
            resourceGroupSpecMap.put(id, resourceGroupSpec);
            // Add newly built spec to spec map
            resourceGroupSpecs.put(resourceGroupIdTemplateMap.get(id), resourceGroupSpec);
            // Add this resource group spec to parent subgroups and remove id from subgroup ids to build
            builder.getParentId().ifPresent(parentId -> {
                recordMap.get(parentId).addSubGroup(resourceGroupSpec);
                subGroupIdsToBuild.get(parentId).remove(id);
            });
        } else {
            // Add this group back to queue since it still has subgroups to build
            queue.addFirst(id);
            // Add this group's subgroups to the queue so that when this id is dequeued again childrenToBuild will be empty
            queue.addAll(0, childrenToBuild);
        }
    }
    // Specs are built from db records, validate and return manager spec
    List<ResourceGroupSpec> rootGroups = rootGroupIds.stream().map(resourceGroupSpecMap::get).collect(Collectors.toList());
    List<SelectorSpec> selectors = dao.getSelectors(environment).stream().map(selectorRecord -> new SelectorSpec(selectorRecord.getUserRegex(), selectorRecord.getUserGroupRegex(), selectorRecord.getSourceRegex(), selectorRecord.getQueryType(), selectorRecord.getClientTags(), selectorRecord.getSelectorResourceEstimate(), resourceGroupIdTemplateMap.get(selectorRecord.getResourceGroupId()))).collect(Collectors.toList());
    ManagerSpec managerSpec = new ManagerSpec(rootGroups, selectors, getCpuQuotaPeriodFromDb());
    validateRootGroups(managerSpec);
    return new AbstractMap.SimpleImmutableEntry<>(managerSpec, resourceGroupSpecs);
}
Also used : Duration.succinctNanos(io.airlift.units.Duration.succinctNanos) Duration(io.airlift.units.Duration) ClusterMemoryPoolManager(io.trino.spi.memory.ClusterMemoryPoolManager) PreDestroy(javax.annotation.PreDestroy) Executors.newSingleThreadScheduledExecutor(java.util.concurrent.Executors.newSingleThreadScheduledExecutor) Map(java.util.Map) ImmutableSet(com.google.common.collect.ImmutableSet) ResourceGroupSelector(io.trino.plugin.resourcegroups.ResourceGroupSelector) Collections.synchronizedList(java.util.Collections.synchronizedList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) TrinoException(io.trino.spi.TrinoException) GuardedBy(javax.annotation.concurrent.GuardedBy) ResourceGroup(io.trino.spi.resourcegroups.ResourceGroup) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Preconditions.checkState(com.google.common.base.Preconditions.checkState) List(java.util.List) ResourceGroupSpec(io.trino.plugin.resourcegroups.ResourceGroupSpec) SelectionCriteria(io.trino.spi.resourcegroups.SelectionCriteria) PostConstruct(javax.annotation.PostConstruct) Optional(java.util.Optional) Nested(org.weakref.jmx.Nested) SelectionContext(io.trino.spi.resourcegroups.SelectionContext) Logger(io.airlift.log.Logger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CounterStat(io.airlift.stats.CounterStat) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) CONFIGURATION_UNAVAILABLE(io.trino.spi.StandardErrorCode.CONFIGURATION_UNAVAILABLE) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) Inject(javax.inject.Inject) HashSet(java.util.HashSet) CONFIGURATION_INVALID(io.trino.spi.StandardErrorCode.CONFIGURATION_INVALID) ImmutableList(com.google.common.collect.ImmutableList) AbstractResourceConfigurationManager(io.trino.plugin.resourcegroups.AbstractResourceConfigurationManager) Managed(org.weakref.jmx.Managed) Threads.daemonThreadsNamed(io.airlift.concurrent.Threads.daemonThreadsNamed) Objects.requireNonNull(java.util.Objects.requireNonNull) SelectorSpec(io.trino.plugin.resourcegroups.SelectorSpec) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) LinkedList(java.util.LinkedList) ResourceGroupId(io.trino.spi.resourcegroups.ResourceGroupId) ResourceGroupIdTemplate(io.trino.plugin.resourcegroups.ResourceGroupIdTemplate) ManagerSpec(io.trino.plugin.resourcegroups.ManagerSpec) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) AbstractMap(java.util.AbstractMap) VisibleForTesting(com.google.common.annotations.VisibleForTesting) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) HashSet(java.util.HashSet) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ManagerSpec(io.trino.plugin.resourcegroups.ManagerSpec) ResourceGroupSpec(io.trino.plugin.resourcegroups.ResourceGroupSpec) LinkedList(java.util.LinkedList) ResourceGroupIdTemplate(io.trino.plugin.resourcegroups.ResourceGroupIdTemplate) SelectorSpec(io.trino.plugin.resourcegroups.SelectorSpec) AtomicLong(java.util.concurrent.atomic.AtomicLong) HashSet(java.util.HashSet)

Aggregations

ResourceGroupIdTemplate (io.trino.plugin.resourcegroups.ResourceGroupIdTemplate)3 ResourceGroupSelector (io.trino.plugin.resourcegroups.ResourceGroupSelector)3 ResourceGroupSpec (io.trino.plugin.resourcegroups.ResourceGroupSpec)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableSet (com.google.common.collect.ImmutableSet)2 ManagerSpec (io.trino.plugin.resourcegroups.ManagerSpec)2 TrinoException (io.trino.spi.TrinoException)2 ResourceGroupId (io.trino.spi.resourcegroups.ResourceGroupId)2 SelectionContext (io.trino.spi.resourcegroups.SelectionContext)2 SelectionCriteria (io.trino.spi.resourcegroups.SelectionCriteria)2 AbstractMap (java.util.AbstractMap)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 List (java.util.List)2 Map (java.util.Map)2 Optional (java.util.Optional)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 ConcurrentMap (java.util.concurrent.ConcurrentMap)2