Search in sources :

Example 1 with Decrementer

use of io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer in project ksql by confluentinc.

the class QueryMetricsUtil method initializePullStreamMetricsCallback.

public static MetricsCallback initializePullStreamMetricsCallback(final Optional<PullQueryExecutorMetrics> pullQueryMetrics, final SlidingWindowRateLimiter pullBandRateLimiter, final ImmutableAnalysis analysis, final AtomicReference<StreamPullQueryMetadata> resultForMetrics, final AtomicReference<Decrementer> refDecrementer) {
    final MetricsCallback metricsCallback = (statusCode, requestBytes, responseBytes, startTimeNanos) -> pullQueryMetrics.ifPresent(metrics -> {
        metrics.recordStatusCode(statusCode);
        metrics.recordRequestSize(requestBytes);
        final StreamPullQueryMetadata m = resultForMetrics.get();
        final KafkaStreams.State state = m == null ? null : m.getTransientQueryMetadata().getKafkaStreams().state();
        if (m == null || state == null || state.equals(State.ERROR) || state.equals(State.PENDING_ERROR)) {
            recordErrorMetrics(pullQueryMetrics, responseBytes, startTimeNanos);
        } else {
            final boolean isWindowed = analysis.getFrom().getDataSource().getKsqlTopic().getKeyFormat().isWindowed();
            final QuerySourceType sourceType = isWindowed ? QuerySourceType.WINDOWED_STREAM : QuerySourceType.NON_WINDOWED_STREAM;
            // There is no WHERE clause constraint information in the persistent logical plan
            final PullPhysicalPlanType planType = PullPhysicalPlanType.UNKNOWN;
            final RoutingNodeType routingNodeType = RoutingNodeType.SOURCE_NODE;
            metrics.recordResponseSize(responseBytes, sourceType, planType, routingNodeType);
            metrics.recordLatency(startTimeNanos, sourceType, planType, routingNodeType);
            final TransientQueryQueue rowQueue = (TransientQueryQueue) m.getTransientQueryMetadata().getRowQueue();
            // The rows read from the underlying data source equal the rows read by the user
            // since the WHERE condition is pushed to the data source
            metrics.recordRowsReturned(rowQueue.getTotalRowsQueued(), sourceType, planType, routingNodeType);
            metrics.recordRowsProcessed(rowQueue.getTotalRowsQueued(), sourceType, planType, routingNodeType);
        }
        pullBandRateLimiter.add(responseBytes);
        // Decrement on happy or exception path
        final Decrementer decrementer = refDecrementer.get();
        if (decrementer != null) {
            decrementer.decrementAtMostOnce();
        }
    });
    return metricsCallback;
}
Also used : ImmutableAnalysis(io.confluent.ksql.analyzer.ImmutableAnalysis) Decrementer(io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer) ScalablePushQueryMetadata(io.confluent.ksql.util.ScalablePushQueryMetadata) QuerySourceType(io.confluent.ksql.util.KsqlConstants.QuerySourceType) ScalablePushQueryMetrics(io.confluent.ksql.internal.ScalablePushQueryMetrics) RoutingNodeType(io.confluent.ksql.util.KsqlConstants.RoutingNodeType) MetricsCallback(io.confluent.ksql.api.server.MetricsCallback) State(org.apache.kafka.streams.KafkaStreams.State) AtomicReference(java.util.concurrent.atomic.AtomicReference) PullQueryExecutorMetrics(io.confluent.ksql.internal.PullQueryExecutorMetrics) StreamPullQueryMetadata(io.confluent.ksql.util.StreamPullQueryMetadata) Optional(java.util.Optional) TransientQueryQueue(io.confluent.ksql.query.TransientQueryQueue) KafkaStreams(org.apache.kafka.streams.KafkaStreams) PullPhysicalPlanType(io.confluent.ksql.physical.pull.PullPhysicalPlan.PullPhysicalPlanType) PullQueryResult(io.confluent.ksql.physical.pull.PullQueryResult) SlidingWindowRateLimiter(io.confluent.ksql.api.server.SlidingWindowRateLimiter) RoutingNodeType(io.confluent.ksql.util.KsqlConstants.RoutingNodeType) KafkaStreams(org.apache.kafka.streams.KafkaStreams) TransientQueryQueue(io.confluent.ksql.query.TransientQueryQueue) State(org.apache.kafka.streams.KafkaStreams.State) PullPhysicalPlanType(io.confluent.ksql.physical.pull.PullPhysicalPlan.PullPhysicalPlanType) StreamPullQueryMetadata(io.confluent.ksql.util.StreamPullQueryMetadata) MetricsCallback(io.confluent.ksql.api.server.MetricsCallback) Decrementer(io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer) QuerySourceType(io.confluent.ksql.util.KsqlConstants.QuerySourceType)

Example 2 with Decrementer

use of io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer in project ksql by confluentinc.

the class ConcurrencyLimiterTest method shouldSucceedUnderLimit.

@Test
public void shouldSucceedUnderLimit() {
    final Metrics metrics = new Metrics();
    final Map<String, String> tags = Collections.emptyMap();
    ConcurrencyLimiter limiter = new ConcurrencyLimiter(1, "pull", metrics, tags);
    assertThat(getReject(metrics, tags), is(0.0));
    assertThat(getRemaining(metrics, tags), is(1.0));
    Decrementer decrementer = limiter.increment();
    assertThat(limiter.getCount(), is(1));
    assertThat(getReject(metrics, tags), is(0.0));
    assertThat(getRemaining(metrics, tags), is(0.0));
    decrementer.decrementAtMostOnce();
    decrementer.decrementAtMostOnce();
    assertThat(limiter.getCount(), is(0));
    assertThat(getReject(metrics, tags), is(0.0));
    assertThat(getRemaining(metrics, tags), is(1.0));
}
Also used : Metrics(org.apache.kafka.common.metrics.Metrics) Matchers.containsString(org.hamcrest.Matchers.containsString) Decrementer(io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer) Test(org.junit.Test)

Example 3 with Decrementer

use of io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer in project ksql by confluentinc.

the class ConcurrencyLimiterTest method shouldError_atLimit.

@Test
public void shouldError_atLimit() {
    final Metrics metrics = new Metrics();
    final Map<String, String> tags = Collections.emptyMap();
    ConcurrencyLimiter limiter = new ConcurrencyLimiter(1, "pull", metrics, tags);
    assertThat(getReject(metrics, tags), is(0.0));
    assertThat(getRemaining(metrics, tags), is(1.0));
    Decrementer decrementer = limiter.increment();
    assertThat(getReject(metrics, tags), is(0.0));
    assertThat(getRemaining(metrics, tags), is(0.0));
    final Exception e = assertThrows(KsqlException.class, limiter::increment);
    assertThat(e.getMessage(), containsString("Host is at concurrency limit for pull queries."));
    assertThat(limiter.getCount(), is(1));
    assertThat(getReject(metrics, tags), is(1.0));
    assertThat(getRemaining(metrics, tags), is(0.0));
    decrementer.decrementAtMostOnce();
    assertThat(limiter.getCount(), is(0));
    assertThat(getReject(metrics, tags), is(1.0));
    assertThat(getRemaining(metrics, tags), is(1.0));
}
Also used : Metrics(org.apache.kafka.common.metrics.Metrics) Matchers.containsString(org.hamcrest.Matchers.containsString) Decrementer(io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer) KsqlException(io.confluent.ksql.util.KsqlException) Test(org.junit.Test)

Example 4 with Decrementer

use of io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer in project ksql by confluentinc.

the class QueryExecutor method handleTablePullQuery.

private QueryMetadataHolder handleTablePullQuery(final ImmutableAnalysis analysis, final ServiceContext serviceContext, final ConfiguredStatement<Query> configured, final Map<String, Object> requestProperties, final Optional<Boolean> isInternalRequest, final SlidingWindowRateLimiter pullBandRateLimiter, final AtomicReference<PullQueryResult> resultForMetrics, final Optional<ConsistencyOffsetVector> consistencyOffsetVector) {
    final RoutingOptions routingOptions = new PullQueryConfigRoutingOptions(configured.getSessionConfig().getConfig(false), configured.getSessionConfig().getOverrides(), requestProperties);
    final PullQueryConfigPlannerOptions plannerOptions = new PullQueryConfigPlannerOptions(configured.getSessionConfig().getConfig(false), configured.getSessionConfig().getOverrides());
    // A request is considered forwarded if the request has the forwarded flag or if the request
    // is from an internal listener.
    final boolean isAlreadyForwarded = routingOptions.getIsSkipForwardRequest() && // Trust the forward request option if isInternalRequest isn't available.
    isInternalRequest.orElse(true);
    // Only check the rate limit at the forwarding host
    Decrementer decrementer = null;
    try {
        if (!isAlreadyForwarded) {
            rateLimiter.checkLimit();
            decrementer = concurrencyLimiter.increment();
        }
        pullBandRateLimiter.allow(KsqlQueryType.PULL);
        final Optional<Decrementer> optionalDecrementer = Optional.ofNullable(decrementer);
        final PullQueryResult result = ksqlEngine.executeTablePullQuery(analysis, serviceContext, configured, routing, routingOptions, plannerOptions, pullQueryMetrics, false, consistencyOffsetVector);
        resultForMetrics.set(result);
        result.onCompletionOrException((v, t) -> optionalDecrementer.ifPresent(Decrementer::decrementAtMostOnce));
        return QueryMetadataHolder.of(result);
    } catch (final Throwable t) {
        if (decrementer != null) {
            decrementer.decrementAtMostOnce();
        }
        throw t;
    }
}
Also used : RoutingOptions(io.confluent.ksql.execution.streams.RoutingOptions) PullQueryConfigRoutingOptions(io.confluent.ksql.rest.server.resources.streaming.PullQueryConfigRoutingOptions) PushQueryConfigRoutingOptions(io.confluent.ksql.rest.server.resources.streaming.PushQueryConfigRoutingOptions) PullQueryConfigRoutingOptions(io.confluent.ksql.rest.server.resources.streaming.PullQueryConfigRoutingOptions) PullQueryConfigPlannerOptions(io.confluent.ksql.rest.server.resources.streaming.PullQueryConfigPlannerOptions) Decrementer(io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer) PullQueryResult(io.confluent.ksql.physical.pull.PullQueryResult)

Aggregations

Decrementer (io.confluent.ksql.rest.util.ConcurrencyLimiter.Decrementer)4 PullQueryResult (io.confluent.ksql.physical.pull.PullQueryResult)2 Metrics (org.apache.kafka.common.metrics.Metrics)2 Matchers.containsString (org.hamcrest.Matchers.containsString)2 Test (org.junit.Test)2 ImmutableAnalysis (io.confluent.ksql.analyzer.ImmutableAnalysis)1 MetricsCallback (io.confluent.ksql.api.server.MetricsCallback)1 SlidingWindowRateLimiter (io.confluent.ksql.api.server.SlidingWindowRateLimiter)1 RoutingOptions (io.confluent.ksql.execution.streams.RoutingOptions)1 PullQueryExecutorMetrics (io.confluent.ksql.internal.PullQueryExecutorMetrics)1 ScalablePushQueryMetrics (io.confluent.ksql.internal.ScalablePushQueryMetrics)1 PullPhysicalPlanType (io.confluent.ksql.physical.pull.PullPhysicalPlan.PullPhysicalPlanType)1 TransientQueryQueue (io.confluent.ksql.query.TransientQueryQueue)1 PullQueryConfigPlannerOptions (io.confluent.ksql.rest.server.resources.streaming.PullQueryConfigPlannerOptions)1 PullQueryConfigRoutingOptions (io.confluent.ksql.rest.server.resources.streaming.PullQueryConfigRoutingOptions)1 PushQueryConfigRoutingOptions (io.confluent.ksql.rest.server.resources.streaming.PushQueryConfigRoutingOptions)1 QuerySourceType (io.confluent.ksql.util.KsqlConstants.QuerySourceType)1 RoutingNodeType (io.confluent.ksql.util.KsqlConstants.RoutingNodeType)1 KsqlException (io.confluent.ksql.util.KsqlException)1 ScalablePushQueryMetadata (io.confluent.ksql.util.ScalablePushQueryMetadata)1