Search in sources :

Example 1 with ConcurrencyLimit

use of io.crate.concurrent.limits.ConcurrencyLimit in project crate by crate.

the class NodeLimits method get.

/**
 * Retrieve the current ConcurrencyLimit for a node.
 *
 * <p>
 * Instances may change if the settings are updated.
 * Consumers of the ConcurrencyLimit need to hold onto the same instance for
 * {@link ConcurrencyLimit#startSample()} and
 * {@link ConcurrencyLimit#onSample(long, boolean)} calls to ensure the number
 * of inflight requests are accurate.
 * </p>
 */
public ConcurrencyLimit get(@Nullable String nodeId) {
    if (nodeId == null) {
        ConcurrencyLimit unknown = unknownNodelimit;
        if (unknown == null) {
            // Here be dragons: Two threads calling .get at the same time could end up
            // creating two different unknown instances.
            // This is acceptable because of the startSample/onSample contract.
            // (ConcurrencyLimit user must hold onto references and use the same instance)
            // 
            // Due to settings changes and nodeDisconnected events, we must be able to cope
            // with multiple instances anyways.
            unknown = newLimit();
            unknownNodelimit = unknown;
        }
        return unknown;
    }
    return limitsPerNode.computeIfAbsent(nodeId, ignored -> newLimit());
}
Also used : ConcurrencyLimit(io.crate.concurrent.limits.ConcurrencyLimit)

Example 2 with ConcurrencyLimit

use of io.crate.concurrent.limits.ConcurrencyLimit in project crate by crate.

the class NodeLimitsTest method test_updating_node_limit_settings_results_in_new_concurrency_limit_instances.

@Test
public void test_updating_node_limit_settings_results_in_new_concurrency_limit_instances() throws Exception {
    ConcurrencyLimit limit = nodeLimits.get("n1");
    clusterSettings.applySettings(Settings.builder().put("overload_protection.dml.initial_concurrency", 10).build());
    ConcurrencyLimit updatedLimit = nodeLimits.get("n1");
    assertThat(limit, not(sameInstance(updatedLimit)));
    assertThat(limit.getLimit(), is(5));
    assertThat(updatedLimit.getLimit(), is(10));
}
Also used : ConcurrencyLimit(io.crate.concurrent.limits.ConcurrencyLimit) Test(org.junit.Test)

Example 3 with ConcurrencyLimit

use of io.crate.concurrent.limits.ConcurrencyLimit in project crate by crate.

the class ShardingUpsertExecutor method execRequests.

private CompletableFuture<UpsertResults> execRequests(ShardedRequests<ShardUpsertRequest, ShardUpsertRequest.Item> requests, final UpsertResults upsertResults) {
    if (requests.itemsByShard.isEmpty()) {
        requests.close();
        // could be that processing the source uri only results in errors, so no items per shard exists
        return CompletableFuture.completedFuture(upsertResults);
    }
    final AtomicInteger numRequests = new AtomicInteger(requests.itemsByShard.size());
    final AtomicReference<Exception> interrupt = new AtomicReference<>(null);
    final CompletableFuture<UpsertResults> resultFuture = new CompletableFuture<>();
    Iterator<Map.Entry<ShardLocation, ShardUpsertRequest>> it = requests.itemsByShard.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry<ShardLocation, ShardUpsertRequest> entry = it.next();
        ShardUpsertRequest request = entry.getValue();
        it.remove();
        String nodeId = entry.getKey().nodeId;
        ConcurrencyLimit nodeLimit = nodeLimits.get(nodeId);
        ActionListener<ShardResponse> listener = new ShardResponseActionListener(numRequests, interrupt, upsertResults, resultCollector.accumulator(), requests.rowSourceInfos, nodeLimit, resultFuture);
        listener = new RetryListener<>(scheduler, l -> requestExecutor.execute(request, l), listener, BackoffPolicy.unlimitedDynamic(nodeLimit));
        requestExecutor.execute(request, listener);
    }
    return resultFuture.whenComplete((r, err) -> requests.close());
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) ByteSizeUnit(org.elasticsearch.common.unit.ByteSizeUnit) Item(io.crate.execution.dml.upsert.ShardUpsertRequest.Item) ClusterService(org.elasticsearch.cluster.service.ClusterService) CollectExpression(io.crate.execution.engine.collect.CollectExpression) CompletableFuture(java.util.concurrent.CompletableFuture) BatchIterator(io.crate.data.BatchIterator) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) NodeLimits(io.crate.execution.jobs.NodeLimits) BackoffPolicy(org.elasticsearch.action.bulk.BackoffPolicy) TransportCreatePartitionsAction(org.elasticsearch.action.admin.indices.create.TransportCreatePartitionsAction) RetryListener(io.crate.execution.support.RetryListener) BlockBasedRamAccounting(io.crate.breaker.BlockBasedRamAccounting) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) CircuitBreaker(org.elasticsearch.common.breaker.CircuitBreaker) TypeGuessEstimateRowSize(io.crate.breaker.TypeGuessEstimateRowSize) ConcurrencyLimit(io.crate.concurrent.limits.ConcurrencyLimit) BulkRequestExecutor(org.elasticsearch.action.bulk.BulkRequestExecutor) ToLongFunction(java.util.function.ToLongFunction) Nullable(javax.annotation.Nullable) FutureActionListener(io.crate.action.FutureActionListener) Iterator(java.util.Iterator) Setting(org.elasticsearch.common.settings.Setting) Executor(java.util.concurrent.Executor) Predicate(java.util.function.Predicate) UUID(java.util.UUID) AcknowledgedResponse(org.elasticsearch.action.support.master.AcknowledgedResponse) RamAccounting(io.crate.breaker.RamAccounting) TimeUnit(java.util.concurrent.TimeUnit) ShardResponse(io.crate.execution.dml.ShardResponse) ShardUpsertRequest(io.crate.execution.dml.upsert.ShardUpsertRequest) List(java.util.List) Logger(org.apache.logging.log4j.Logger) BatchIterators(io.crate.data.BatchIterators) Row(io.crate.data.Row) TimeValue(io.crate.common.unit.TimeValue) RowShardResolver(io.crate.execution.engine.collect.RowShardResolver) LogManager(org.apache.logging.log4j.LogManager) CreatePartitionsRequest(org.elasticsearch.action.admin.indices.create.CreatePartitionsRequest) ActionListener(org.elasticsearch.action.ActionListener) ConcurrencyLimit(io.crate.concurrent.limits.ConcurrencyLimit) ShardUpsertRequest(io.crate.execution.dml.upsert.ShardUpsertRequest) AtomicReference(java.util.concurrent.atomic.AtomicReference) ShardResponse(io.crate.execution.dml.ShardResponse) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map)

Example 4 with ConcurrencyLimit

use of io.crate.concurrent.limits.ConcurrencyLimit in project crate by crate.

the class ShardingUpsertExecutor method apply.

@Override
public CompletableFuture<? extends Iterable<Row>> apply(BatchIterator<Row> batchIterator) {
    final ConcurrencyLimit nodeLimit = nodeLimits.get(localNode);
    long startTime = nodeLimit.startSample();
    var isUsedBytesOverThreshold = new IsUsedBytesOverThreshold(queryCircuitBreaker, nodeLimit);
    var reqBatchIterator = BatchIterators.partition(batchIterator, bulkSize, () -> new ShardedRequests<>(requestFactory, ramAccounting), grouper, bulkShardCreationLimiter.or(isUsedBytesOverThreshold));
    // If IO is involved the source iterator should pause when the target node reaches a concurrent job counter limit.
    // Without IO, we assume that the source iterates over in-memory structures which should be processed as
    // fast as possible to free resources.
    Predicate<ShardedRequests<ShardUpsertRequest, ShardUpsertRequest.Item>> shouldPause = this::shouldPauseOnPartitionCreation;
    if (batchIterator.hasLazyResultSet()) {
        shouldPause = shouldPause.or(this::shouldPauseOnTargetNodeJobsCounter).or(isUsedBytesOverThreshold);
    }
    BatchIteratorBackpressureExecutor<ShardedRequests<ShardUpsertRequest, ShardUpsertRequest.Item>, UpsertResults> executor = new BatchIteratorBackpressureExecutor<>(jobId, scheduler, this.executor, reqBatchIterator, this::execute, resultCollector.combiner(), resultCollector.supplier().get(), shouldPause, earlyTerminationCondition, earlyTerminationExceptionGenerator, this::getMaxLastRttInMs);
    return executor.consumeIteratorAndExecute().thenApply(upsertResults -> resultCollector.finisher().apply(upsertResults)).whenComplete((res, err) -> {
        nodeLimit.onSample(startTime, err != null);
    });
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) ByteSizeUnit(org.elasticsearch.common.unit.ByteSizeUnit) Item(io.crate.execution.dml.upsert.ShardUpsertRequest.Item) ClusterService(org.elasticsearch.cluster.service.ClusterService) CollectExpression(io.crate.execution.engine.collect.CollectExpression) CompletableFuture(java.util.concurrent.CompletableFuture) BatchIterator(io.crate.data.BatchIterator) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) NodeLimits(io.crate.execution.jobs.NodeLimits) BackoffPolicy(org.elasticsearch.action.bulk.BackoffPolicy) TransportCreatePartitionsAction(org.elasticsearch.action.admin.indices.create.TransportCreatePartitionsAction) RetryListener(io.crate.execution.support.RetryListener) BlockBasedRamAccounting(io.crate.breaker.BlockBasedRamAccounting) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) CircuitBreaker(org.elasticsearch.common.breaker.CircuitBreaker) TypeGuessEstimateRowSize(io.crate.breaker.TypeGuessEstimateRowSize) ConcurrencyLimit(io.crate.concurrent.limits.ConcurrencyLimit) BulkRequestExecutor(org.elasticsearch.action.bulk.BulkRequestExecutor) ToLongFunction(java.util.function.ToLongFunction) Nullable(javax.annotation.Nullable) FutureActionListener(io.crate.action.FutureActionListener) Iterator(java.util.Iterator) Setting(org.elasticsearch.common.settings.Setting) Executor(java.util.concurrent.Executor) Predicate(java.util.function.Predicate) UUID(java.util.UUID) AcknowledgedResponse(org.elasticsearch.action.support.master.AcknowledgedResponse) RamAccounting(io.crate.breaker.RamAccounting) TimeUnit(java.util.concurrent.TimeUnit) ShardResponse(io.crate.execution.dml.ShardResponse) ShardUpsertRequest(io.crate.execution.dml.upsert.ShardUpsertRequest) List(java.util.List) Logger(org.apache.logging.log4j.Logger) BatchIterators(io.crate.data.BatchIterators) Row(io.crate.data.Row) TimeValue(io.crate.common.unit.TimeValue) RowShardResolver(io.crate.execution.engine.collect.RowShardResolver) LogManager(org.apache.logging.log4j.LogManager) CreatePartitionsRequest(org.elasticsearch.action.admin.indices.create.CreatePartitionsRequest) ActionListener(org.elasticsearch.action.ActionListener) ConcurrencyLimit(io.crate.concurrent.limits.ConcurrencyLimit) ShardUpsertRequest(io.crate.execution.dml.upsert.ShardUpsertRequest)

Example 5 with ConcurrencyLimit

use of io.crate.concurrent.limits.ConcurrencyLimit in project crate by crate.

the class ShardingUpsertExecutor method shouldPauseOnTargetNodeJobsCounter.

private boolean shouldPauseOnTargetNodeJobsCounter(ShardedRequests<ShardUpsertRequest, ShardUpsertRequest.Item> requests) {
    for (ShardLocation shardLocation : requests.itemsByShard.keySet()) {
        String requestNodeId = shardLocation.nodeId;
        ConcurrencyLimit nodeLimit = nodeLimits.get(requestNodeId);
        if (nodeLimit.exceedsLimit()) {
            if (isDebugEnabled) {
                LOGGER.debug("reached maximum concurrent operations for node {} (limit={}, rrt={}ms, inflight={})", requestNodeId, nodeLimit.getLimit(), nodeLimit.getLastRtt(TimeUnit.MILLISECONDS), nodeLimit.numInflight());
            }
            return true;
        }
    }
    return false;
}
Also used : ConcurrencyLimit(io.crate.concurrent.limits.ConcurrencyLimit)

Aggregations

ConcurrencyLimit (io.crate.concurrent.limits.ConcurrencyLimit)8 FutureActionListener (io.crate.action.FutureActionListener)4 ShardResponse (io.crate.execution.dml.ShardResponse)4 RamAccounting (io.crate.breaker.RamAccounting)3 TypeGuessEstimateRowSize (io.crate.breaker.TypeGuessEstimateRowSize)3 Row (io.crate.data.Row)3 ShardUpsertRequest (io.crate.execution.dml.upsert.ShardUpsertRequest)3 CollectExpression (io.crate.execution.engine.collect.CollectExpression)3 RowShardResolver (io.crate.execution.engine.collect.RowShardResolver)3 NodeLimits (io.crate.execution.jobs.NodeLimits)3 RetryListener (io.crate.execution.support.RetryListener)3 Iterator (java.util.Iterator)3 List (java.util.List)3 Map (java.util.Map)3 UUID (java.util.UUID)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 Function (java.util.function.Function)3